update ev for new version

This commit is contained in:
熊潇 2025-05-08 20:46:34 +08:00
parent 6759438921
commit 6e85d65d2b
6 changed files with 89 additions and 22 deletions

0
bin/assistant-server.js Executable file → Normal file
View File

View File

@ -1,6 +1,6 @@
{ {
"name": "@kevisual/envision-cli", "name": "@kevisual/envision-cli",
"version": "0.0.45", "version": "0.0.46",
"description": "envision command tools", "description": "envision command tools",
"main": "dist/app.mjs", "main": "dist/app.mjs",
"type": "module", "type": "module",

View File

@ -9,6 +9,7 @@ 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';
import { MD5 } from 'crypto-js';
/** /**
* package.json basename, version, user, appKey * package.json basename, version, user, appKey
* @returns * @returns
@ -43,9 +44,14 @@ const command = new Command('deploy')
.option('-o, --org <org>', 'org') .option('-o, --org <org>', 'org')
.option('-u, --update', 'load current app. set current version in product。 redis 缓存更新') .option('-u, --update', 'load current app. set current version in product。 redis 缓存更新')
.option('-s, --showBackend', 'show backend url, 部署的后端应用显示执行的cli命令') .option('-s, --showBackend', 'show backend url, 部署的后端应用显示执行的cli命令')
.option('-c, --noCheck', '是否受app manager控制的模块。默认检测')
.option('-d, --dot', '是否上传隐藏文件')
.option('--dir, --directory <directory>', '上传的默认路径')
.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;
const noCheck = !options.noCheck;
const dot = !!options.dot;
// 获取当前目录是否存在package.json, 如果有从package.json 获取 version 和basename // 获取当前目录是否存在package.json, 如果有从package.json 获取 version 和basename
const pkgInfo = getPackageJson(); const pkgInfo = getPackageJson();
if (!version && pkgInfo?.version) { if (!version && pkgInfo?.version) {
@ -54,7 +60,7 @@ const command = new Command('deploy')
if (!key && pkgInfo?.appKey) { if (!key && pkgInfo?.appKey) {
key = pkgInfo?.appKey || ''; key = pkgInfo?.appKey || '';
} }
console.log('start deploy') console.log('start deploy');
if (!version || !key) { if (!version || !key) {
const answers = await inquirer.prompt([ const answers = await inquirer.prompt([
{ {
@ -82,7 +88,7 @@ const command = new Command('deploy')
if (stat.isDirectory()) { if (stat.isDirectory()) {
isDirectory = true; isDirectory = true;
const gPath = path.join(directory, '**/*'); const gPath = path.join(directory, '**/*');
const files = await glob(gPath, { cwd: pwd, ignore: ['node_modules/**/*'], onlyFiles: true }); const files = await glob(gPath, { cwd: pwd, ignore: ['node_modules/**/*'], onlyFiles: true, dot });
_relativeFiles = files.map((file) => path.relative(directory, file)); _relativeFiles = files.map((file) => path.relative(directory, file));
} else if (stat.isFile()) { } else if (stat.isFile()) {
const filename = path.basename(directory); const filename = path.basename(directory);
@ -104,13 +110,13 @@ const command = new Command('deploy')
} }
} }
const uploadDirectory = isDirectory ? directory : path.dirname(directory); const uploadDirectory = isDirectory ? directory : path.dirname(directory);
const res = await uploadFiles(_relativeFiles, uploadDirectory, { key, version, username: org }); const res = await uploadFiles(_relativeFiles, uploadDirectory, { key, version, username: org, noCheckAppFiles: !noCheck, directory: options.directory });
if (res?.code === 200) { if (res?.code === 200) {
console.log('File uploaded successfully!'); console.log('File uploaded successfully!');
res.data?.data?.files?.map?.((d) => { res.data?.upload?.map?.((d) => {
console.log('uploaded file', d?.name, d?.path); console.log(chalk.green('uploaded file', d?.name, d?.path));
}); });
const { id, data, ...rest } = res.data || {}; const { id, data, ...rest } = res.data?.app || {};
if (id && !update) { if (id && !update) {
console.log(chalk.green('id: '), id); console.log(chalk.green('id: '), id);
if (!org) { if (!org) {
@ -121,7 +127,7 @@ const command = new Command('deploy')
} else if (id && update) { } else if (id && update) {
deployLoadFn(id); deployLoadFn(id);
} else { } else {
console.log('rest error', JSON.stringify(rest, null, 2)); // console.log('rest', JSON.stringify(res.data, null, 2));
} }
if (id && showBackend) { if (id && showBackend) {
console.log('\n'); console.log('\n');
@ -142,34 +148,92 @@ const command = new Command('deploy')
console.error('error', error); console.error('error', error);
} }
}); });
export const getHash = (file: string) => {
const uploadFiles = async ( const content = fs.readFileSync(file, 'utf-8');
files: string[], return MD5(content).toString();
directory: string, };
{ key, version, username }: { key: string; version: string; username: string }, type UploadFileOptions = {
): Promise<any> => { key: string;
version: string;
username?: string;
noCheckAppFiles?: boolean;
directory?: string;
};
const uploadFiles = async (files: string[], directory: string, opts: UploadFileOptions): Promise<any> => {
const { key, version, username } = opts || {};
const config = await getConfig(); const config = await getConfig();
const form = new FormData(); const form = new FormData();
const data: Record<string, any> = { files: [] };
for (const file of files) { for (const file of files) {
const filePath = path.join(directory, file); const filePath = path.join(directory, file);
form.append('file', fs.createReadStream(filePath), { const hash = getHash(filePath);
filename: file, data.files.push({ path: file, hash: hash });
filepath: file,
});
} }
data.appKey = key;
data.version = version;
form.append('appKey', key); form.append('appKey', key);
form.append('version', version); form.append('version', version);
if (username) { if (username) {
form.append('username', username); form.append('username', username);
data.username = username;
} }
if (opts?.directory) {
form.append('directory', opts.directory);
data.directory = opts.directory;
}
const token = await storage.getItem('token');
const checkUrl = new URL('/api/s1/resources/upload/check', getBaseURL());
const res = await query
.adapter({ url: checkUrl.toString(), method: 'POST', body: data, headers: { Authorization: 'Bearer ' + token, contentType: 'application/json' } })
.then((res) => {
try {
if (typeof res === 'string') {
return JSON.parse(res);
} else {
return res;
}
} catch (error) {
return typeof res === 'string' ? {} : res;
}
});
const checkData: { path: string; isUpload: boolean }[] = res.data;
if (res.code !== 200) {
console.error('check failed', res);
return res;
}
let needUpload = false;
for (const file of files) {
const filePath = path.join(directory, file);
const check = checkData.find((d) => d.path === file);
if (check?.isUpload) {
console.log('文件已经上传过了', file);
continue;
}
form.append('file', fs.createReadStream(filePath), {
filename: file,
filepath: file,
});
needUpload = true;
}
if (!needUpload) {
console.log('所有文件都上传过了,不需要上传文件');
return {
code: 200,
};
}
return new Promise(async (resolve) => { return new Promise(async (resolve) => {
const _baseURL = getBaseURL(); const _baseURL = getBaseURL();
const url = new URL(_baseURL); const url = new URL('/api/s1/resources/upload', _baseURL);
const searchParams = url.searchParams;
if (opts.noCheckAppFiles) {
searchParams.append('noCheckAppFiles', 'true');
}
console.log('upload url', url.hostname, url.protocol, url.port); console.log('upload url', url.hostname, url.protocol, url.port);
const token = await storage.getItem('token'); const pathname = url.href.toString().replace(_baseURL.toString(), '');
form.submit( form.submit(
{ {
path: '/api/app/upload', path: pathname,
host: url.hostname, host: url.hostname,
protocol: url.protocol as any, protocol: url.protocol as any,
port: url.port, port: url.port,

3
test/code/node/.npmrc Normal file
View File

@ -0,0 +1,3 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN}
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
ignore-workspace-root-check=true

View File

@ -1 +0,0 @@
test

1
test/test-cli.html Normal file
View File

@ -0,0 +1 @@
test-cli deploy2