update download app show me

This commit is contained in:
熊潇 2025-03-30 20:23:45 +08:00
parent be6d7091c3
commit aadd8266b1
8 changed files with 132 additions and 30 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@kevisual/envision-cli", "name": "@kevisual/envision-cli",
"version": "0.0.35-alpha.1", "version": "0.0.35",
"description": "envision command tools", "description": "envision command tools",
"main": "dist/app.mjs", "main": "dist/app.mjs",
"type": "module", "type": "module",
@ -43,7 +43,7 @@
"@rollup/plugin-typescript": "^12.1.2", "@rollup/plugin-typescript": "^12.1.2",
"@types/crypto-js": "^4.2.2", "@types/crypto-js": "^4.2.2",
"@types/jsonwebtoken": "^9.0.9", "@types/jsonwebtoken": "^9.0.9",
"@types/node": "^22.13.11", "@types/node": "^22.13.14",
"chalk": "^5.4.1", "chalk": "^5.4.1",
"commander": "^13.1.0", "commander": "^13.1.0",
"fast-glob": "^3.3.3", "fast-glob": "^3.3.3",
@ -52,7 +52,7 @@
"ignore": "^7.0.3", "ignore": "^7.0.3",
"inquirer": "^12.5.0", "inquirer": "^12.5.0",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"rollup": "^4.36.0", "rollup": "^4.38.0",
"rollup-plugin-dts": "^6.2.1", "rollup-plugin-dts": "^6.2.1",
"rollup-plugin-esbuild": "^6.2.1", "rollup-plugin-esbuild": "^6.2.1",
"tar": "^7.4.3", "tar": "^7.4.3",
@ -75,8 +75,8 @@
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"pg-hstore": "^2.3.4", "pg-hstore": "^2.3.4",
"sequelize": "^6.37.6", "sequelize": "^6.37.7",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"vite": "^6.2.2" "vite": "^6.2.3"
} }
} }

View File

@ -5,24 +5,47 @@
import { chalk } from '@/module/chalk.ts'; import { chalk } from '@/module/chalk.ts';
import { program, Command } from '../../../program.ts'; import { program, Command } from '../../../program.ts';
import { queryApp } from '../../../query/app-manager/query-app.ts'; import { queryApp } from '../../../query/app-manager/query-app.ts';
import { installApp, uninstallApp } from '@/module/download/install.ts'; import { checkAppDir, installApp, uninstallApp } from '@/module/download/install.ts';
import { fileIsExist } from '@/uitls/file.ts';
import fs from 'fs';
export const appCommand = new Command('app').description('app 命令').action(() => { export const appCommand = new Command('app').description('app 命令').action(() => {
console.log('app'); console.log('app');
}); });
program.addCommand(appCommand); program.addCommand(appCommand);
/**
* app serve client的包
* output不存在,
*
* -t appweb web
* -r 使
* -o
* -i app serve client的包, id user/key
*
*/
const downloadAppCommand = new Command('download') const downloadAppCommand = new Command('download')
.description('下载 app serve client的包. \napp download -i root/code-center') .description('下载 app serve client的包. \napp download -i root/code-center')
.option('-i, --id <id>', '下载 app serve client的包, id 或者user/key') .option('-i, --id <id>', '下载 app serve client的包, id 或者user/key')
.option('-o, --output <output>', '下载 app serve client的包, 输出路径') .option('-o, --output <output>', '下载 app serve client的包, 输出路径')
.option('-t, --type <type>', '下载 app serve client的包, 类型, app或者web 默认为web')
.option('-r, --registry <registry>', '下载 app serve client的包, 使用私有源') .option('-r, --registry <registry>', '下载 app serve client的包, 使用私有源')
.action(async (options) => { .action(async (options) => {
const id = options.id || ''; const id = options.id || '';
const output = options.output || '';
if (!id) { if (!id) {
console.error(chalk.red('id is required')); console.error(chalk.red('id is required'));
return; return;
} }
if (output) {
const checkOutput = fileIsExist(output);
if (!checkOutput) {
// console.error(chalk.red('output is error, 请输入正确的路径'));
// return;
fs.mkdirSync(output, { recursive: true });
}
}
const [user, key] = id.split('/'); const [user, key] = id.split('/');
const data: any = {}; const data: any = {};
if (user && key) { if (user && key) {
@ -38,10 +61,16 @@ const downloadAppCommand = new Command('download')
} }
if (res.code === 200) { if (res.code === 200) {
const app = res.data; const app = res.data;
let appType: 'app' | 'web' = 'web';
if (options.type === 'app') {
appType = 'app';
} else if (options.type === 'web') {
appType = 'web';
}
const result = await installApp(app, { const result = await installApp(app, {
appDir: '', appDir: output,
// kevisualUrl: 'https://kevisual.cn',
kevisualUrl: registry, kevisualUrl: registry,
appType: appType,
}); });
if (result.code === 200) { if (result.code === 200) {
console.log(chalk.green('下载成功', res.data?.user, res.data?.key)); console.log(chalk.green('下载成功', res.data?.user, res.data?.key));

View File

@ -9,6 +9,30 @@ import inquirer from 'inquirer';
import { packLib, unpackLib } from './publish.ts'; import { packLib, unpackLib } from './publish.ts';
import chalk from 'chalk'; import chalk from 'chalk';
import { installDeps } from '@/uitls/npm.ts'; import { installDeps } from '@/uitls/npm.ts';
/**
* package.json basename, version, user, appKey
* @returns
*/
export const getPackageJson = () => {
const filePath = path.join(process.cwd(), 'package.json');
if (!fs.existsSync(filePath)) {
return null;
}
try {
const packageJson = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
const basename = packageJson.basename || '';
const version = packageJson.version || '';
const userAppArry = basename.split('/');
if (userAppArry.length !== 2) {
console.error(chalk.red('basename is error, 请输入正确的路径, packages.json中basename例如 root/appKey'));
return null;
}
const [user, appKey] = userAppArry;
return { basename, version, pkg: packageJson, user, appKey };
} catch (error) {
return null;
}
};
const command = new Command('deploy') const command = new Command('deploy')
.description('把前端文件传到服务器') .description('把前端文件传到服务器')
.argument('<filePath>', 'Path to the file to be uploaded, filepath or directory') // 定义文件路径参数 .argument('<filePath>', 'Path to the file to be uploaded, filepath or directory') // 定义文件路径参数
@ -16,11 +40,19 @@ const command = new Command('deploy')
.option('-k, --key <key>', 'key') .option('-k, --key <key>', 'key')
.option('-y, --yes <yes>', 'yes') .option('-y, --yes <yes>', 'yes')
.option('-o, --org <org>', 'org') .option('-o, --org <org>', 'org')
.option('-u, --update', 'load current app. set current version in product') .option('-u, --update', 'load current app. set current version in product。 redis 缓存更新')
.option('-s, --showBackend', 'show backend url') .option('-s, --showBackend', 'show backend url, 部署的后端应用显示执行的cli命令')
.action(async (filePath, options) => { .action(async (filePath, options) => {
try { try {
let { version, key, yes, update, org, showBackend } = options; let { version, key, yes, update, org, showBackend } = options;
// 获取当前目录是否存在package.json, 如果有从package.json 获取 version 和basename
const pkgInfo = getPackageJson();
if (!version && pkgInfo?.version) {
version = pkgInfo?.version || '';
}
if (!key && pkgInfo?.appKey) {
key = pkgInfo?.appKey || '';
}
if (!version || !key) { if (!version || !key) {
const answers = await inquirer.prompt([ const answers = await inquirer.prompt([
{ {

View File

@ -3,7 +3,15 @@ import { getConfig } from '@/module/get-config.ts';
import inquirer from 'inquirer'; import inquirer from 'inquirer';
import { loginInCommand } from '@/module/login/login-by-web.ts'; import { loginInCommand } from '@/module/login/login-by-web.ts';
import { queryLogin, storage } from '@/module/query.ts'; import { queryLogin, storage } from '@/module/query.ts';
import chalk from 'chalk';
import util from 'util';
const pick = (obj: any, keys: string[]) => {
return keys.reduce((acc, key) => {
acc[key] = obj[key];
return acc;
}, {});
};
/** /**
* login命令 `-u` `-p` * login命令 `-u` `-p`
*/ */
@ -86,10 +94,25 @@ const switchOrgCommand = new Command('switch').argument('<username>', 'Switch to
program.addCommand(switchOrgCommand); program.addCommand(switchOrgCommand);
const command = new Command('me').description('').action(async () => { const command = new Command('me')
.option('-a, --all', 'show all info')
.description('')
.action(async (options) => {
try { try {
const res = await showMe(false); let res = await showMe(false);
console.log('me', res?.data); if (res.code === 200 && res.data?.accessToken) {
res = await showMe(false);
}
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) { } catch (error) {
console.log('me error', error); console.log('me error', error);
} }

View File

@ -12,8 +12,11 @@ const tokenList = new Command('list')
.description('show token list') .description('show token list')
// .option('-r --remove <number>', 'remove token by number') // .option('-r --remove <number>', 'remove token by number')
.action(async (opts) => { .action(async (opts) => {
const res = queryLogin.cacheStore.cacheData; console.log('show token list');
console.log(util.inspect(res, { colors: true, depth: 4 })); queryLogin.cacheStore.init()
// const res = await queryLogin.cacheStore.cache.get('token');
console.log(queryLogin.cacheStore.cacheData);
// console.log(util.inspect(res, { colors: true, depth: 4 }));
}); });
token.addCommand(tokenList); token.addCommand(tokenList);
app.addCommand(token); app.addCommand(token);

View File

@ -393,6 +393,10 @@ const packCommand = new Command('pack')
basename = basename.slice(1); basename = basename.slice(1);
} }
const basenameArr = basename.split('/'); const basenameArr = basename.split('/');
if (basenameArr.length !== 2) {
console.error(chalk.red('basename is error, 请输入正确的路径, packages.json中basename例如 root/appKey'));
return;
}
appKey = basenameArr[1] || ''; appKey = basenameArr[1] || '';
} }
if (!appKey) { if (!appKey) {

View File

@ -25,10 +25,14 @@ type InstallAppOpts = {
* , assistant-config的下面 * , assistant-config的下面
*/ */
isClient?: boolean; isClient?: boolean;
/**
* web, web-config的下面
*/
appType?: 'app' | 'web';
}; };
export const installApp = async (app: Package, opts: InstallAppOpts = {}) => { export const installApp = async (app: Package, opts: InstallAppOpts = {}) => {
// const _app = demoData; // const _app = demoData;
const { appDir = '', kevisualUrl = 'https://kevisual.cn' } = opts; const { appDir = '', kevisualUrl = 'https://kevisual.cn', isClient = false, appType = 'web' } = opts;
const _app = app; const _app = app;
try { try {
let files = _app.data.files || []; let files = _app.data.files || [];
@ -38,13 +42,19 @@ export const installApp = async (app: Package, opts: InstallAppOpts = {}) => {
const downFiles = files.map((file: any) => { const downFiles = files.map((file: any) => {
const noVersionPath = file.path.replace(`/${version}`, ''); const noVersionPath = file.path.replace(`/${version}`, '');
let downloadPath = noVersionPath;
if (appType === 'app') {
downloadPath = noVersionPath.replace(`${user}/${key}/`, '');
}
return { return {
...file, ...file,
downloadPath: path.join(appDir, noVersionPath), downloadPath: path.join(appDir, downloadPath),
downloadUrl: `${kevisualUrl}/${noVersionPath}`, downloadUrl: `${kevisualUrl}/${noVersionPath}`,
}; };
}); });
const downloadTasks: DownloadTask[] = downFiles as any; const downloadTasks: DownloadTask[] = downFiles as any;
console.log('downloadTasks', downloadTasks);
// return;
for (const file of downloadTasks) { for (const file of downloadTasks) {
const downloadPath = file.downloadPath; const downloadPath = file.downloadPath;
const downloadUrl = file.downloadUrl; const downloadUrl = file.downloadUrl;
@ -52,18 +62,19 @@ export const installApp = async (app: Package, opts: InstallAppOpts = {}) => {
if (!fs.existsSync(dir)) { if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true }); fs.mkdirSync(dir, { recursive: true });
} }
console.log('downloadUrl', downloadUrl);
const res = await fetch(downloadUrl); const res = await fetch(downloadUrl);
const blob = await res.blob(); const blob = await res.blob();
fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer()));
} }
let indexHtml = files.find((file: any) => file.name === 'index.html'); let indexHtml = files.find((file: any) => file.name === 'index.html');
if (!indexHtml) { // if (!indexHtml) {
files.push({ // files.push({
name: 'index.html', // name: 'index.html',
path: `${user}/${key}/index.html`, // path: `${user}/${key}/index.html`,
}); // });
fs.writeFileSync(path.join(appDir, `${user}/${key}/index.html`), JSON.stringify(app, null, 2)); // fs.writeFileSync(path.join(appDir, `${user}/${key}/index.html`), JSON.stringify(app, null, 2));
} // }
_app.data.files = files; _app.data.files = files;
return { return {
code: 200, code: 200,

@ -1 +1 @@
Subproject commit fdf6d3ac0a2c12cbac15a50d5089c6497c51a271 Subproject commit 98c8a2ad86331566058ca7cc12df5ee2b406fa2f