diff --git a/assistant/src/command/app/index.ts b/assistant/src/command/app/index.ts index d9742b5..51b12ec 100644 --- a/assistant/src/command/app/index.ts +++ b/assistant/src/command/app/index.ts @@ -43,3 +43,11 @@ const deleteCommand = new Command('delete') logger.debug(info); }); appManagerCommand.addCommand(deleteCommand); + +const uploadCommand = new Command('upload') + .description('上传应用') + .option('-i, --id ', '应用名称 root/app-name 的格式,如果是后端,会自动解析为 app-name') + .option('-t, --type ', '应用类型', 'web') + .action(async (options) => { + // + }); diff --git a/assistant/src/command/config-manager/index.ts b/assistant/src/command/config-manager/index.ts index f3c7d68..cdef122 100644 --- a/assistant/src/command/config-manager/index.ts +++ b/assistant/src/command/config-manager/index.ts @@ -63,3 +63,27 @@ const removeCommand = new Command('remove') } }); program.addCommand(removeCommand); + +const npmCommand = new Command('pnpm') + .description('助手pnpm命令') + .option('-p --path ', '助手路径,默认为执行命令的目录,如果助手路径不存在则创建。') + .action((opts) => { + if (opts.path && !opts.path.startsWith('/')) { + opts.path = path.join(process.cwd(), opts.path); + } else if (opts.path) { + opts.path = path.resolve(opts.path); + } + const configDir = AssistantInit.detectConfigDir(opts.path); + console.log('configDir', configDir); + const assistantInit = new AssistantInit({ + path: configDir, + }); + const initRes = assistantInit.initPnpm(); + if (initRes?.create) { + console.log(chalk.blue('助手pnpm命令初始化成功,创建了新文件')); + } else { + console.log(chalk.green('助手pnpm命令初始化成功')); + } + }); + +Init.addCommand(npmCommand); diff --git a/assistant/src/module/assistant/config/index.ts b/assistant/src/module/assistant/config/index.ts index defb54a..ef9c044 100644 --- a/assistant/src/module/assistant/config/index.ts +++ b/assistant/src/module/assistant/config/index.ts @@ -60,8 +60,12 @@ export const initConfig = (configRootPath: string) => { }; export type ReturnInitConfigType = ReturnType; +type AuthPermission = { + type?: 'auth-proxy' | 'public' | 'private' | 'project'; +}; export type AssistantConfigData = { pageApi?: string; // https://kevisual.cn + token?: string; registry?: string; // https://kevisual.cn proxy?: ProxyInfo[]; apiProxyList?: ProxyInfo[]; @@ -78,6 +82,7 @@ export type AssistantConfigData = { scripts?: { [key: string]: string; }; + auth?: AuthPermission; }; let assistantConfig: AssistantConfigData; type AssistantConfigOptions = { diff --git a/assistant/src/routes/index.ts b/assistant/src/routes/index.ts index 4b94ffc..b000db2 100644 --- a/assistant/src/routes/index.ts +++ b/assistant/src/routes/index.ts @@ -1,4 +1,5 @@ -import { app } from '../app.ts'; +import { Query } from '@kevisual/query'; +import { app, assistantConfig } from '../app.ts'; import './config/index.ts'; import './shop-install/index.ts'; @@ -8,7 +9,34 @@ app id: 'auth', }) .define(async (ctx) => { - // + const config = assistantConfig.getConfig(); + const { auth } = config; + const host = config.pageApi || config.registry || 'https://kevisual.cn'; + const url = new URL('/api/router', host); + const token = ctx.token; + if (auth && auth.type !== 'public') { + if (!token) { + return ctx.throw(4001, 'not login'); + } + url.searchParams.set('token', token); + // 鉴权代理 + // TODO: + const query = new Query({ baseURL: url.toString() }); + const res = await query.post({ + path: 'user', + key: 'me', + }); + console.log('res', res); + if (res.code !== 200) { + return ctx.throw(4001, 'not login'); + } + const tokenUser = res.data || {}; + ctx.state = { + ...ctx.state, + tokenUser, + }; + const { username } = tokenUser; + } }) .addTo(app); diff --git a/assistant/src/services/init/index.ts b/assistant/src/services/init/index.ts index 76cb5f5..8d1f8b5 100644 --- a/assistant/src/services/init/index.ts +++ b/assistant/src/services/init/index.ts @@ -72,6 +72,58 @@ export class AssistantInit extends AssistantConfig { console.log(chalk.green('助手配置文件assistant-config.json创建成功')); } } + initPnpm() { + const pnpmPath = path.join(this.configDir, 'assistant-app', 'pnpm.yaml'); + let create = false; + if (!checkFileExists(pnpmPath, true)) { + create = true; + fs.writeFileSync( + pnpmPath, + `packages: + - 'apps/**/*' + - 'pages/**/*' + `, + ); + console.log(chalk.green('助手 pnpm.yaml 文件创建成功')); + } + const packagePath = path.join(this.configDir, 'assistant-app', 'package.json'); + if (!checkFileExists(packagePath, true)) { + create = true; + fs.writeFileSync( + packagePath, + `{ + "name": "assistant-app", + "version": "1.0.0", + "description": "assistant-app package pnpm, node pkgs projects", + "type": "module", + "scripts": { + "start": "pm2 start apps/code-center/dist/app.mjs --name code-center", + "proxy": "pm2 start apps/page-proxy/dist/app.mjs --name page-proxy" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@kevisual/router": "^0.0.20", + "@kevisual/use-config": "^1.0.17", + "ioredis": "^5.6.1", + "minio": "^8.0.5", + "pg": "^8.16.0", + "pm2": "^6.0.6", + "sequelize": "^6.37.7", + "sqlite3": "^5.1.7", + "socket.io": "^4.8.1", + "dotenv": "^16.5.0" + } +} +`, + ); + console.log(chalk.green('助手 package.json 文件创建成功')); + } + return { + create, + }; + } protected getDefaultInitAssistantConfig() { return { description: '助手配置文件', diff --git a/assistant/src/services/init/package.json b/assistant/src/services/init/package.json new file mode 100644 index 0000000..18a235b --- /dev/null +++ b/assistant/src/services/init/package.json @@ -0,0 +1,25 @@ +{ + "name": "assistant-app", + "version": "1.0.0", + "description": "assistant-app package pnpm, node pkgs projects", + "type": "module", + "scripts": { + "start": "pm2 start apps/code-center/dist/app.mjs --name code-center", + "proxy": "pm2 start apps/page-proxy/dist/app.mjs --name page-proxy" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@kevisual/router": "^0.0.20", + "@kevisual/use-config": "^1.0.17", + "ioredis": "^5.6.1", + "minio": "^8.0.5", + "pg": "^8.16.0", + "pm2": "^6.0.6", + "sequelize": "^6.37.7", + "sqlite3": "^5.1.7", + "socket.io": "^4.8.1", + "dotenv": "^16.5.0" + } +} \ No newline at end of file diff --git a/package.json b/package.json index b5a219d..03d2af0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/envision-cli", - "version": "0.0.51", + "version": "0.0.52-beta.0", "description": "envision command tools", "main": "dist/app.mjs", "type": "module", diff --git a/src/command/ls-token.ts b/src/command/ls-token.ts index de9cf61..f2a3bb9 100644 --- a/src/command/ls-token.ts +++ b/src/command/ls-token.ts @@ -167,7 +167,7 @@ const rvm = new Command('registry') .option('-s, --set ', 'set registry') .action(async (opts) => { const config = getConfig(); - const defaultRegistry = ['https://kevisual.cn', 'https://kevisual.silkyai.cn', 'https://kevisual.xiongxiao.me']; + const defaultRegistry = ['https://kevisual.cn', 'https://kevisual.silkyai.cn', 'https://kevisual.xiongxiao.me', 'http://localhost:4005']; if (opts.list) { showList(defaultRegistry); return; @@ -208,6 +208,14 @@ const xiongxiao = new Command('me').description('xiongxiao registry').action(asy showList(defaultRegistry); }); baseURL.addCommand(xiongxiao); +const local = new Command('local').description('local registry').action(async (opts) => { + console.log('local registry'); + const config = getConfig(); + const defaultRegistry = ['http://localhost:4005']; + writeConfig({ ...config, baseURL: defaultRegistry[0] }); + showList(defaultRegistry); +}); +baseURL.addCommand(local); const kv = new Command('kevisual').description('kevisual registry').action(async (opts) => { console.log('kevisual registry'); diff --git a/src/command/publish.ts b/src/command/publish.ts index c6eb6a2..369b4cc 100644 --- a/src/command/publish.ts +++ b/src/command/publish.ts @@ -205,7 +205,7 @@ export const pack = async (opts: { isTar: boolean; packDist?: string }) => { const readmeContent = fs.readFileSync(readme, 'utf-8'); collection.readme = readmeContent; } - return { collection, outputFilePath }; + return { collection, outputFilePath, dir: cwd }; }; export const getPackageInfo = async () => { const cwd = process.cwd(); @@ -287,14 +287,22 @@ export const packByIgnore = async (opts: PackByIgnoreOpts) => { const readmeContent = fs.readFileSync(readme, 'utf-8'); collection.readme = readmeContent; } - return { collection, outputFilePath }; + return { collection, outputFilePath, dir: cwd }; }; /** * 打包应用 * @param ignore 是否忽略 .npmignore 文件 * @returns 打包结果 */ -export const packLib = async ({ ignore = false, tar = false, packDist = 'pack-dist' }: { ignore?: boolean; tar?: boolean; packDist?: string }) => { +export const packLib = async ({ + ignore = false, + tar = false, + packDist = 'pack-dist', +}: { + ignore?: boolean; + tar?: boolean; + packDist?: string; +}): Promise<{ collection: Record; outputFilePath: string; dir: string }> => { if (ignore) { return await packByIgnore({ isTar: tar, packDist }); } @@ -367,6 +375,7 @@ const packCommand = new Command('pack') .option('-t, --tar', '打包为 tgz 文件') .option('-d, --packDist ', '打包目录') .option('-y, --yes', '确定,直接打包', true) + .option('-c, --clean', '清理 package.json中的 devDependencies') .action(async (opts) => { const packDist = opts.packDist || 'pack-dist'; const packageInfo = await getPackageInfo(); @@ -409,16 +418,20 @@ const packCommand = new Command('pack') ]); appKey = answers.appKey || appKey; } - let value: { collection: Record; outputFilePath: string } = await packLib({ + let value = await packLib({ ignore: opts.ignore, tar: opts.tar, packDist, }); + if (opts?.clean) { + const newPackageJson = { ...packageInfo }; + delete newPackageJson.devDependencies; + fs.writeFileSync(path.join(process.cwd(), 'pack-dist', 'package.json'), JSON.stringify(newPackageJson, null, 2)); + } if (opts.publish) { // 运行 deploy 命令 const runDeployCommand = 'envision pack-deploy ' + value.outputFilePath + ' -k ' + appKey; const [_app, _command] = process.argv; - console.log(chalk.blue('example: '), runDeployCommand); let deployDist = opts.isTar ? value.outputFilePath : packDist; const deployCommand = [_app, _command, 'deploy', deployDist, '-k', appKey, '-v', version, '-u']; if (opts.org) { @@ -430,6 +443,9 @@ const packCommand = new Command('pack') if (opts.yes) { deployCommand.push('-y', 'yes'); } + console.log(chalk.blue('deploy doing: '), deployCommand.slice(2).join(' '), '\n\n'); + console.log('pack deploy services', chalk.blue('example: '), runDeployCommand); + program.parse(deployCommand); } });