init
This commit is contained in:
@@ -7,7 +7,7 @@ const external = ['bun'];
|
||||
await Bun.build({
|
||||
target: 'node',
|
||||
format: 'esm',
|
||||
entrypoints: ['./src/index.ts'],
|
||||
entrypoints: ['./src/oldindex.ts'],
|
||||
outdir: './dist',
|
||||
naming: {
|
||||
entry: 'envision.js',
|
||||
12
package.json
12
package.json
@@ -26,12 +26,12 @@
|
||||
"files": [
|
||||
"dist",
|
||||
"bin",
|
||||
"bun.config.mjs"
|
||||
"bun.config.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "bun src/run.ts ",
|
||||
"dev": "bun src/cli.ts ",
|
||||
"dev:server": "cd assistant && bun --watch src/run-server.ts ",
|
||||
"build": "rimraf dist && bun run bun.config.mjs",
|
||||
"build": "rimraf dist && bun run bun.config.ts",
|
||||
"deploy": "ev pack -u -p -m no",
|
||||
"postbuild": "cd assistant && pnpm build "
|
||||
},
|
||||
@@ -58,7 +58,8 @@
|
||||
"nanoid": "^5.1.7",
|
||||
"pm2": "latest",
|
||||
"semver": "^7.7.4",
|
||||
"unstorage": "^1.17.4"
|
||||
"unstorage": "^1.17.4",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kevisual/api": "^0.0.65",
|
||||
@@ -76,13 +77,14 @@
|
||||
"chalk": "^5.6.2",
|
||||
"commander": "^14.0.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"es-toolkit": "^1.45.1",
|
||||
"fast-glob": "^3.3.3",
|
||||
"filesize": "^11.0.13",
|
||||
"form-data": "^4.0.5",
|
||||
"ignore": "^7.0.5",
|
||||
"jsonwebtoken": "^9.0.3",
|
||||
"pm2": "^6.0.14",
|
||||
"tar": "^7.5.12",
|
||||
"tar": "^7.5.13",
|
||||
"zustand": "^5.0.12"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
@@ -62,6 +62,9 @@ importers:
|
||||
unstorage:
|
||||
specifier: ^1.17.4
|
||||
version: 1.17.4(idb-keyval@6.2.2)
|
||||
zod:
|
||||
specifier: ^4.3.6
|
||||
version: 4.3.6
|
||||
devDependencies:
|
||||
'@kevisual/api':
|
||||
specifier: ^0.0.65
|
||||
@@ -108,6 +111,9 @@ importers:
|
||||
crypto-js:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
es-toolkit:
|
||||
specifier: ^1.45.1
|
||||
version: 1.45.1
|
||||
fast-glob:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
@@ -124,8 +130,8 @@ importers:
|
||||
specifier: ^9.0.3
|
||||
version: 9.0.3
|
||||
tar:
|
||||
specifier: ^7.5.12
|
||||
version: 7.5.12
|
||||
specifier: ^7.5.13
|
||||
version: 7.5.13
|
||||
zustand:
|
||||
specifier: ^5.0.12
|
||||
version: 5.0.12(react@19.2.4)
|
||||
@@ -2257,8 +2263,8 @@ packages:
|
||||
resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
tar@7.5.12:
|
||||
resolution: {integrity: sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw==}
|
||||
tar@7.5.13:
|
||||
resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
to-regex-range@5.0.1:
|
||||
@@ -4928,7 +4934,7 @@ snapshots:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
tar@7.5.12:
|
||||
tar@7.5.13:
|
||||
dependencies:
|
||||
'@isaacs/fs-minipass': 4.0.1
|
||||
chownr: 3.0.0
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import { App } from '@kevisual/app/mod.ts';
|
||||
import { storage } from '../module/query.ts';
|
||||
import { sessionStorage } from '../module/cache.ts';
|
||||
export const app = new App({ token: storage.getItem('token') || '', storage: sessionStorage });
|
||||
@@ -1,6 +0,0 @@
|
||||
import { app } from './ai.ts'
|
||||
import './routes/cmd-run.ts'
|
||||
|
||||
export {
|
||||
app
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import { app } from '../ai.ts';
|
||||
import { execSync } from 'node:child_process'
|
||||
import { logger } from '@/module/logger.ts';
|
||||
const promptTemplate = `# CMD 结果判断器
|
||||
|
||||
分析上一条 CMD 命令的执行结果,判断是否需要执行下一条命令。
|
||||
|
||||
- 若结果中隐含或明确指示需继续执行 → 返回:\`{"cmd": "推断出的下一条命令", "type": "cmd"}\`
|
||||
- 若无后续操作,甚至上一次执行的返回为空或者成功 → 返回:\`{"type": "none"}\`
|
||||
|
||||
1. 仅输出合法 JSON,无任何额外文本。
|
||||
2. \`cmd\` 必须从执行结果中合理推断得出,非预设或猜测。
|
||||
3. 禁止解释、注释、换行或格式错误。`
|
||||
|
||||
app.router.route({
|
||||
path: 'cmd-run',
|
||||
description: '执行 CMD 命令并判断下一步操作, 参数是 cmd 字符串',
|
||||
}).define(async (ctx) => {
|
||||
const cmd = ctx.query.cmd || '';
|
||||
if (!cmd) {
|
||||
ctx.throw(400, 'cmd is required');
|
||||
}
|
||||
let result = '';
|
||||
ctx.state.steps = ctx.state?.steps || [];
|
||||
|
||||
try {
|
||||
logger.info('执行命令:', cmd);
|
||||
result = execSync(cmd, { encoding: 'utf-8' });
|
||||
ctx.state.steps.push({ cmd, result });
|
||||
logger.info(result);
|
||||
} catch (error: any) {
|
||||
result = error.message || '';
|
||||
ctx.state.steps.push({ cmd, result, error: true });
|
||||
ctx.body = {
|
||||
steps: ctx.state.steps,
|
||||
}
|
||||
return;
|
||||
}
|
||||
await app.loadAI()
|
||||
const prompt = `${promptTemplate}\n上一条命令:\n${cmd}\n执行结果:\n${result}\n`;
|
||||
const response = await app.ai.question(prompt);
|
||||
|
||||
const msg = app.ai.utils.extractJsonFromMarkdown(app.ai.responseText);
|
||||
try {
|
||||
logger.debug('AI Prompt', prompt);
|
||||
logger.debug('AI 分析结果:', msg);
|
||||
const { cmd, type } = msg;
|
||||
if (type === 'cmd' && cmd) {
|
||||
await app.router.call({ path: 'cmd-run', payload: { cmd } }, { state: ctx.state });
|
||||
} else {
|
||||
logger.info('无后续命令,结束执行');
|
||||
ctx.state.steps.push({ type: 'none' });
|
||||
}
|
||||
} catch (error) {
|
||||
result = '执行错误,无法解析返回结果为合法 JSON' + app.ai.responseText
|
||||
logger.error(result);
|
||||
ctx.state.steps.push({ cmd, result, parseError: true });
|
||||
}
|
||||
ctx.body = {
|
||||
steps: ctx.state.steps,
|
||||
}
|
||||
}).addTo(app.router);
|
||||
6
src/app.ts
Normal file
6
src/app.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { App } from '@kevisual/router';
|
||||
import { useContextKey } from '@kevisual/context';
|
||||
|
||||
export const app = useContextKey<App>('app', () => {
|
||||
return new App()
|
||||
});
|
||||
4
src/cli.ts
Normal file
4
src/cli.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { app } from './index.ts';
|
||||
import { parse } from "@kevisual/router/commander"
|
||||
|
||||
parse({ app });
|
||||
@@ -1,6 +1,6 @@
|
||||
import { program, Command } from '@/program.ts';
|
||||
import { getConfig, getEnvToken } from '@/module/get-config.ts';
|
||||
import { input, password } from '@inquirer/prompts';
|
||||
import { input } from '@inquirer/prompts';
|
||||
import { loginInCommand } from '@/module/login/login-by-web.ts';
|
||||
import { queryLogin, storage } from '@/module/query.ts';
|
||||
import chalk from 'chalk';
|
||||
|
||||
37
src/index.ts
37
src/index.ts
@@ -1,34 +1,7 @@
|
||||
import { program } from '@/program.ts';
|
||||
import './command/login.ts';
|
||||
import './command/ls-token.ts';
|
||||
import './command/deploy.ts';
|
||||
import './command/config.ts';
|
||||
import './command/router.ts';
|
||||
import './command/npm.ts';
|
||||
import './command/publish.ts';
|
||||
import './command/proxy.ts';
|
||||
import './command/update.ts';
|
||||
import { app } from './app.ts'
|
||||
import './routes/login.ts'
|
||||
|
||||
import './command/sync/sync.ts';
|
||||
export { app };
|
||||
|
||||
import './command/app/index.ts';
|
||||
|
||||
import './command/gist/index.ts';
|
||||
import './command/config-remote.ts';
|
||||
import './command/config-secret-remote.ts';
|
||||
// import './command/ai.ts';
|
||||
import './command/coding-plan/cc.ts'
|
||||
import './command/coding-plan/oc.ts'
|
||||
import './command/docker.ts';
|
||||
import './command/jwks.ts';
|
||||
|
||||
import './command/cnb/index.ts';
|
||||
import './command/download.ts';
|
||||
|
||||
// program.parse(process.argv);
|
||||
|
||||
export const runParser = async (argv: string[]) => {
|
||||
// program.parse(process.argv);
|
||||
// console.log('argv', argv);
|
||||
program.parse(argv);
|
||||
};
|
||||
app.createAuth(() => { })
|
||||
app.createRouteList()
|
||||
33
src/oldindex.ts
Normal file
33
src/oldindex.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { program } from '@/program.ts';
|
||||
import './command/login.ts';
|
||||
import './command/ls-token.ts';
|
||||
import './command/deploy.ts';
|
||||
import './command/config.ts';
|
||||
import './command/router.ts';
|
||||
import './command/npm.ts';
|
||||
import './command/publish.ts';
|
||||
import './command/proxy.ts';
|
||||
import './command/update.ts';
|
||||
|
||||
import './command/sync/sync.ts';
|
||||
|
||||
import './command/app/index.ts';
|
||||
|
||||
import './command/gist/index.ts';
|
||||
import './command/config-remote.ts';
|
||||
import './command/config-secret-remote.ts';
|
||||
import './command/coding-plan/cc.ts'
|
||||
import './command/coding-plan/oc.ts'
|
||||
import './command/docker.ts';
|
||||
import './command/jwks.ts';
|
||||
|
||||
import './command/cnb/index.ts';
|
||||
import './command/download.ts';
|
||||
|
||||
// program.parse(process.argv);
|
||||
|
||||
export const runParser = async (argv: string[]) => {
|
||||
// program.parse(process.argv);
|
||||
// console.log('argv', argv);
|
||||
program.parse(argv);
|
||||
};
|
||||
194
src/routes/login.ts
Normal file
194
src/routes/login.ts
Normal file
@@ -0,0 +1,194 @@
|
||||
import { app } from '../app.ts';
|
||||
import { z } from 'zod';
|
||||
import { getConfig, getEnvToken } from '@/module/get-config.ts';
|
||||
import { input, password as inputPassword } from '@inquirer/prompts';
|
||||
import { loginInCommand } from '@/module/login/login-by-web.ts';
|
||||
import { queryLogin, storage } from '@/module/query.ts';
|
||||
import chalk from 'chalk';
|
||||
import util from 'util';
|
||||
import { pick } from 'es-toolkit'
|
||||
|
||||
export const getUsername = async () => {
|
||||
const token = getEnvToken();
|
||||
const localToken = storage.getItem('token');
|
||||
if (!token && !localToken) {
|
||||
console.log('请先登录');
|
||||
return null;
|
||||
}
|
||||
let me = await queryLogin.getMe(localToken || token);
|
||||
if (me?.code === 401) {
|
||||
me = await queryLogin.getMe();
|
||||
}
|
||||
if (me?.code === 200) {
|
||||
return me.data?.username;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const showMe = async (show = true) => {
|
||||
const token = getEnvToken();
|
||||
const localToken = storage.getItem('token');
|
||||
if (!token && !localToken) {
|
||||
console.log('请先登录');
|
||||
return { code: 40400, message: '请先登录' };
|
||||
}
|
||||
let me = await queryLogin.getMe(localToken || token);
|
||||
if (me?.code === 401) {
|
||||
me = await queryLogin.getMe();
|
||||
}
|
||||
if (show) {
|
||||
console.log('Me', me.data);
|
||||
}
|
||||
return me;
|
||||
};
|
||||
|
||||
app.route({
|
||||
path: 'user',
|
||||
key: 'login',
|
||||
description: '登录',
|
||||
metadata: {
|
||||
args: {
|
||||
username: z.string().optional().describe('用户名'),
|
||||
password: z.string().optional().describe('密码'),
|
||||
force: z.boolean().optional().describe('强制登录'),
|
||||
web: z.boolean().optional().describe('是否通过web登录'),
|
||||
env: z.boolean().optional().describe('是否通过环境变量KEVISUAL_TOKEN登录'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
let { username, password, force, web, env } = ctx.args;
|
||||
if (web) {
|
||||
await loginInCommand();
|
||||
return;
|
||||
}
|
||||
// 从环境变量登录
|
||||
if (env) {
|
||||
const envToken = getEnvToken();
|
||||
if (!envToken) {
|
||||
console.log('环境变量 KEVISUAL_TOKEN 未设置');
|
||||
return;
|
||||
}
|
||||
const res = await showMe(false);
|
||||
if (res.code === 200) {
|
||||
console.log('Login success:', res.data?.username || res.data?.email);
|
||||
} else {
|
||||
console.log('Login failed:', res.message || 'Invalid token');
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 如果没有传递参数,则通过交互式输入
|
||||
if (!username) {
|
||||
username = await input({
|
||||
message: 'Enter your username:',
|
||||
});
|
||||
}
|
||||
if (!password) {
|
||||
password = await inputPassword({
|
||||
message: 'Enter your password:',
|
||||
});
|
||||
}
|
||||
const token = storage.getItem('token');
|
||||
if (token) {
|
||||
const res = await showMe(false);
|
||||
if (res.code === 200) {
|
||||
const data = res.data;
|
||||
if (data.username === username) {
|
||||
console.log('Already Login For', data.username);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const res = await queryLogin.login({
|
||||
username,
|
||||
password,
|
||||
}).catch((err) => {
|
||||
return { code: 500, message: err.message || '' };
|
||||
});
|
||||
if (res.code === 200) {
|
||||
console.log('welcome', username);
|
||||
} else {
|
||||
console.log('登录失败', res.message || '');
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
|
||||
app.route({
|
||||
path: 'user',
|
||||
key: 'me',
|
||||
description: '查看当前登录用户信息',
|
||||
metadata: {
|
||||
args: {
|
||||
all: z.boolean().optional().describe('是否显示全部信息,默认为false'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const options = ctx.args;
|
||||
try {
|
||||
let res = await showMe(false);
|
||||
let isRefresh = false;
|
||||
if (res.code === 200 && res.data?.accessToken) {
|
||||
res = await showMe(false);
|
||||
isRefresh = true;
|
||||
}
|
||||
if (res.code === 40400) {
|
||||
return
|
||||
}
|
||||
if (res.code === 200) {
|
||||
if (isRefresh) {
|
||||
console.log(chalk.green('refresh token success'), '\n');
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
isRefresh ? chalk.red('refresh token failed, please login again.') : chalk.red('you need login first. \n run `envision login` to login'),
|
||||
'\n',
|
||||
);
|
||||
return;
|
||||
}
|
||||
const baseURL = getConfig().baseURL;
|
||||
const pickData = pick(res?.data, ['username', 'type', 'orgs']);
|
||||
|
||||
console.log(chalk.blue('baseURL', baseURL));
|
||||
if (options.all) {
|
||||
console.log(chalk.blue(util.inspect(res?.data, { colors: true, depth: 4 })));
|
||||
} else {
|
||||
// 打印pickData
|
||||
console.log(chalk.blue(util.inspect(pickData, { colors: true, depth: 4 })));
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('me error', error);
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'user',
|
||||
key: 'switch',
|
||||
description: '切换到其他组织或用户',
|
||||
metadata: {
|
||||
args: {
|
||||
username: z.string().describe('用户名或组织名'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const { username } = ctx.args;
|
||||
const res = await queryLogin.switchUser(username);
|
||||
if (res.code === 200) {
|
||||
console.log('success switch to', username);
|
||||
} else {
|
||||
console.log('switch to', username, 'failed', res.message || '');
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'user',
|
||||
key: 'logout',
|
||||
description: '退出登录',
|
||||
metadata: {}
|
||||
}).define(async () => {
|
||||
try {
|
||||
await queryLogin.logout();
|
||||
storage.removeItem('token');
|
||||
console.log('退出成功');
|
||||
} catch (error) {
|
||||
console.log('退出失败', error);
|
||||
}
|
||||
}).addTo(app)
|
||||
252
src/routes/token-ls.ts
Normal file
252
src/routes/token-ls.ts
Normal file
@@ -0,0 +1,252 @@
|
||||
import { app } from '../app.ts';
|
||||
import { z } from 'zod';
|
||||
import { getConfig, getEnvToken, writeConfig } from '@/module/get-config.ts';
|
||||
import { queryLogin, storage } from '@/module/query.ts';
|
||||
import { Kevisual } from '@/module/kevisual.ts';
|
||||
import { showMore } from '@/uitls/show-more.ts';
|
||||
|
||||
function isNumeric(str: string) {
|
||||
return /^-?\d+\.?\d*$/.test(str);
|
||||
}
|
||||
|
||||
const showList = (list: string[]) => {
|
||||
if (list.length === 0) {
|
||||
console.log('expand baseURLList is empty');
|
||||
return;
|
||||
}
|
||||
const config = getConfig();
|
||||
console.log('----current baseURL:' + config.baseURL + '----\n');
|
||||
list.forEach((item, index) => {
|
||||
console.log(`${index + 1}: ${item}`);
|
||||
});
|
||||
};
|
||||
|
||||
app.route({
|
||||
path: 'token',
|
||||
key: 'ls',
|
||||
description: '显示 token 列表',
|
||||
metadata: {
|
||||
args: {}
|
||||
}
|
||||
}).define(async () => {
|
||||
console.log('show token list');
|
||||
queryLogin.cacheStore.init();
|
||||
console.log(queryLogin.cacheStore.cacheData);
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'token',
|
||||
key: 'info',
|
||||
description: '显示 token 信息',
|
||||
metadata: {
|
||||
args: {
|
||||
env: z.boolean().optional().describe('显示环境变量中的 token'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const { env } = ctx.args;
|
||||
const token = storage.getItem('token');
|
||||
if (env) {
|
||||
console.log('token in env', getEnvToken());
|
||||
} else {
|
||||
console.log('token', token);
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'token',
|
||||
key: 'create',
|
||||
description: '创建 jwks token',
|
||||
metadata: {
|
||||
args: {}
|
||||
}
|
||||
}).define(async () => {
|
||||
const kevisual = new Kevisual();
|
||||
const res = await kevisual.getAdminToken();
|
||||
if (res.code === 200) {
|
||||
const jwtToken = res.data?.accessToken;
|
||||
console.log('============jwt token============\n\n');
|
||||
console.log(jwtToken);
|
||||
} else {
|
||||
console.log('create token failed', showMore(res));
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'baseURL',
|
||||
key: 'info',
|
||||
description: '显示 baseURL',
|
||||
metadata: {
|
||||
args: {
|
||||
add: z.string().optional().describe('添加 baseURL'),
|
||||
remove: z.number().optional().describe('按编号移除 baseURL'),
|
||||
set: z.union([z.number(), z.string()]).optional().describe('设置 baseURL'),
|
||||
list: z.boolean().optional().describe('列出 baseURL'),
|
||||
clear: z.boolean().optional().describe('清除 baseURL'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
let { add, remove, set, list, clear } = ctx.args;
|
||||
let config = getConfig();
|
||||
let baseList = (config.baseURLList as Array<string>) || [];
|
||||
if (!config.baseURL) {
|
||||
baseList = ['https://kevisual.cn'];
|
||||
writeConfig({ ...config, baseURL: 'https://kevisual.cn', baseURLList: baseList });
|
||||
config = getConfig();
|
||||
}
|
||||
const quineList = (list: string[]) => {
|
||||
const newList = new Set(list);
|
||||
return Array.from(newList);
|
||||
};
|
||||
|
||||
if (add || set) {
|
||||
let change = false;
|
||||
if (add) {
|
||||
change = true;
|
||||
baseList.push(add);
|
||||
} else if (set) {
|
||||
if (!isNumeric(String(set))) {
|
||||
change = true;
|
||||
baseList.push(String(set));
|
||||
writeConfig({ ...config, baseURL: String(set) });
|
||||
config = getConfig();
|
||||
}
|
||||
}
|
||||
if (change) {
|
||||
baseList = quineList(baseList);
|
||||
writeConfig({ ...config, baseURLList: baseList });
|
||||
config = getConfig();
|
||||
showList(baseList);
|
||||
}
|
||||
}
|
||||
if (remove !== undefined) {
|
||||
const index = remove - 1;
|
||||
if (index < 0 || index >= baseList.length) {
|
||||
console.log('index out of range');
|
||||
return;
|
||||
}
|
||||
const removeBase = baseList.splice(index, 1);
|
||||
baseList = quineList(baseList);
|
||||
showList(baseList);
|
||||
writeConfig({ ...config, baseURLList: baseList });
|
||||
removeBase[0];
|
||||
return;
|
||||
}
|
||||
if (set !== undefined) {
|
||||
const isNumber = isNumeric(String(set));
|
||||
if (isNumber) {
|
||||
const index = Number(set) - 1;
|
||||
if (index < 0 || index >= baseList.length) {
|
||||
console.log('index out of range');
|
||||
return;
|
||||
}
|
||||
writeConfig({ ...config, baseURL: baseList[index] });
|
||||
showList(baseList);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (list) {
|
||||
showList(baseList);
|
||||
return;
|
||||
}
|
||||
if (clear) {
|
||||
writeConfig({ ...config, baseURLList: [] });
|
||||
return;
|
||||
}
|
||||
if (!config.baseURL) {
|
||||
config = getConfig();
|
||||
writeConfig({ ...config, baseURL: 'https://kevisual.cn' });
|
||||
config = getConfig();
|
||||
}
|
||||
console.log('current baseURL:', config.baseURL);
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'baseURL',
|
||||
key: 'set',
|
||||
description: '设置 baseURL',
|
||||
metadata: {
|
||||
args: {
|
||||
baseURL: z.string().optional().describe('baseURL 地址'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const config = getConfig();
|
||||
let baseURL = ctx.args.baseURL;
|
||||
if (!baseURL) {
|
||||
console.log('baseURL is required');
|
||||
return;
|
||||
}
|
||||
writeConfig({ ...config, baseURL });
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'registry',
|
||||
key: 'manage',
|
||||
description: 'registry 管理',
|
||||
metadata: {
|
||||
args: {
|
||||
list: z.boolean().optional().describe('列出 registry'),
|
||||
set: z.string().optional().describe('设置 registry'),
|
||||
}
|
||||
}
|
||||
}).define(async (ctx) => {
|
||||
const { list, set } = ctx.args;
|
||||
const config = getConfig();
|
||||
const defaultRegistry = ['https://kevisual.cn', 'https://kevisual.silkyai.cn', 'https://kevisual.xiongxiao.me', 'http://localhost:3005'];
|
||||
if (list) {
|
||||
showList(defaultRegistry);
|
||||
return;
|
||||
}
|
||||
if (set) {
|
||||
const isNumber = isNumeric(set);
|
||||
if (isNumber) {
|
||||
const index = Number(set) - 1;
|
||||
if (index < 0 || index >= defaultRegistry.length) {
|
||||
console.log('index out of range');
|
||||
return;
|
||||
}
|
||||
writeConfig({ ...config, baseURL: defaultRegistry[index] });
|
||||
console.log('set registry', defaultRegistry[index]);
|
||||
} else {
|
||||
writeConfig({ ...config, baseURL: set });
|
||||
console.log('set registry', set);
|
||||
}
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'baseURL',
|
||||
key: 'kevisual',
|
||||
description: 'kevisual registry',
|
||||
metadata: { args: {} }
|
||||
}).define(async () => {
|
||||
const config = getConfig();
|
||||
const defaultRegistry = ['https://kevisual.cn'];
|
||||
writeConfig({ ...config, baseURL: defaultRegistry[0] });
|
||||
showList(defaultRegistry);
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'baseURL',
|
||||
key: 'silky',
|
||||
description: 'silky registry',
|
||||
metadata: { args: {} }
|
||||
}).define(async () => {
|
||||
const config = getConfig();
|
||||
const defaultRegistry = ['https://kevisual.silkyai.cn'];
|
||||
writeConfig({ ...config, baseURL: defaultRegistry[0] });
|
||||
showList(defaultRegistry);
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'baseURL',
|
||||
key: 'local',
|
||||
description: 'local registry',
|
||||
metadata: { args: {} }
|
||||
}).define(async () => {
|
||||
const config = getConfig();
|
||||
const defaultRegistry = ['http://localhost:3005'];
|
||||
writeConfig({ ...config, baseURL: defaultRegistry[0] });
|
||||
showList(defaultRegistry);
|
||||
}).addTo(app)
|
||||
@@ -1,3 +0,0 @@
|
||||
import { runParser } from './index.ts';
|
||||
|
||||
runParser(process.argv);
|
||||
Reference in New Issue
Block a user