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",
"version": "0.0.35-alpha.1",
"version": "0.0.35",
"description": "envision command tools",
"main": "dist/app.mjs",
"type": "module",
@ -43,7 +43,7 @@
"@rollup/plugin-typescript": "^12.1.2",
"@types/crypto-js": "^4.2.2",
"@types/jsonwebtoken": "^9.0.9",
"@types/node": "^22.13.11",
"@types/node": "^22.13.14",
"chalk": "^5.4.1",
"commander": "^13.1.0",
"fast-glob": "^3.3.3",
@ -52,7 +52,7 @@
"ignore": "^7.0.3",
"inquirer": "^12.5.0",
"rimraf": "^6.0.1",
"rollup": "^4.36.0",
"rollup": "^4.38.0",
"rollup-plugin-dts": "^6.2.1",
"rollup-plugin-esbuild": "^6.2.1",
"tar": "^7.4.3",
@ -75,8 +75,8 @@
"crypto-js": "^4.2.0",
"jsonwebtoken": "^9.0.2",
"pg-hstore": "^2.3.4",
"sequelize": "^6.37.6",
"sequelize": "^6.37.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 { program, Command } from '../../../program.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(() => {
console.log('app');
});
program.addCommand(appCommand);
/**
* app serve client的包
* output不存在,
*
* -t appweb web
* -r 使
* -o
* -i app serve client的包, id user/key
*
*/
const downloadAppCommand = new Command('download')
.description('下载 app serve client的包. \napp download -i root/code-center')
.option('-i, --id <id>', '下载 app serve client的包, id 或者user/key')
.option('-o, --output <output>', '下载 app serve client的包, 输出路径')
.option('-t, --type <type>', '下载 app serve client的包, 类型, app或者web 默认为web')
.option('-r, --registry <registry>', '下载 app serve client的包, 使用私有源')
.action(async (options) => {
const id = options.id || '';
const output = options.output || '';
if (!id) {
console.error(chalk.red('id is required'));
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 data: any = {};
if (user && key) {
@ -38,10 +61,16 @@ const downloadAppCommand = new Command('download')
}
if (res.code === 200) {
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, {
appDir: '',
// kevisualUrl: 'https://kevisual.cn',
appDir: output,
kevisualUrl: registry,
appType: appType,
});
if (result.code === 200) {
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 chalk from 'chalk';
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')
.description('把前端文件传到服务器')
.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('-y, --yes <yes>', 'yes')
.option('-o, --org <org>', 'org')
.option('-u, --update', 'load current app. set current version in product')
.option('-s, --showBackend', 'show backend url')
.option('-u, --update', 'load current app. set current version in product。 redis 缓存更新')
.option('-s, --showBackend', 'show backend url, 部署的后端应用显示执行的cli命令')
.action(async (filePath, options) => {
try {
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) {
const answers = await inquirer.prompt([
{

View File

@ -3,7 +3,15 @@ import { getConfig } from '@/module/get-config.ts';
import inquirer from 'inquirer';
import { loginInCommand } from '@/module/login/login-by-web.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`
*/
@ -86,13 +94,28 @@ const switchOrgCommand = new Command('switch').argument('<username>', 'Switch to
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 {
const res = await showMe(false);
console.log('me', res?.data);
let res = await showMe(false);
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) {
console.log('me error', error);
}
});
});
program.addCommand(command);

View File

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

View File

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

View File

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

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