Files
cli/assistant/src/services/app/index.ts

137 lines
3.5 KiB
TypeScript

import { checkFileExists, AssistantConfig } from '@/module/assistant/index.ts';
import path from 'path';
import fs from 'fs';
import inquirer from 'inquirer';
import { spawnSync } from 'child_process';
export const runCommand = (command: string, args: string[]) => {
const result = spawnSync(command, args, {
stdio: 'inherit',
shell: true,
});
if (result.error) {
console.error('Error executing command:', result.error);
throw result.error;
}
if (result.status !== 0) {
console.error('Command failed with status:', result.status);
throw new Error(`Command failed with status: ${result.status}`);
}
return result;
};
export type appType = 'web' | 'app';
type DownloadAppOptions = {
/**
* 应用名称
* @type {string}
* @example user/app
* @description 应用名称
*/
id: string;
type?: appType;
registry?: string;
/**
* 应用名称,默认为 user/app的 app
*/
appName?: string;
force?: boolean;
yes?: boolean;
};
type DeleteAppOptions = {
/**
* 应用名称
* @type {string}
* @example user/app
* @description 应用名称
*/
id: string;
type?: appType;
appName?: string;
yes?: boolean;
};
export class AppDownload {
config: AssistantConfig;
constructor(config: AssistantConfig) {
this.config = config;
}
async getRegistry() {
return this.config.getRegistry();
}
async downloadApp(opts: DownloadAppOptions) {
const { id, type = 'web', force, yes } = opts;
const configDir = this.config.configDir;
this.config?.checkMounted();
const appsDir = this.config.configPath?.appsDir;
const pagesDir = this.config.configPath?.pagesDir;
if (!id) {
throw new Error('应用名称不能为空');
}
const command = 'ev';
const args = ['app', 'download'];
args.push('-i', id);
if (type === 'web') {
args.push('-o', pagesDir);
} else if (type === 'app') {
args.push('-o', path.join(appsDir));
} else {
throw new Error('应用类型错误,只能是 web 或 app');
}
if (force) {
args.push('-f');
if (opts.yes) {
args.push('-y');
}
}
if (opts.registry) {
args.push('-r', opts.registry);
}
return runCommand(command, args);
}
async confirm(message?: string) {
const { confirm } = await inquirer.prompt([
{
type: 'confirm',
name: 'confirm',
message: message || '是否继续删除应用?',
default: false,
},
]);
return confirm;
}
async deleteApp(opts: DeleteAppOptions) {
const { id, type = 'web', yes = false } = opts;
const appName = opts?.appName || id.split('/').pop();
this.config?.checkMounted();
const appsDir = this.config.configPath?.appsDir;
const pagesDir = this.config.configPath?.pagesDir;
if (!id) {
throw new Error('应用名称不能为空');
}
let deletePath = '';
let isDelete = false;
if (type === 'web') {
// 直接删除路径就行
const pagePath = path.join(pagesDir, id);
deletePath = pagePath;
} else if (type === 'app') {
const appPath = path.join(appsDir, id);
deletePath = appPath;
}
if (deletePath && checkFileExists(deletePath)) {
if (!yes) {
const confirm = await this.confirm(`是否删除 ${deletePath} 应用?`);
if (!confirm) {
console.log('取消删除应用');
return;
}
}
fs.rmSync(deletePath, { recursive: true });
isDelete = true;
console.log(`删除应用成功: ${deletePath}`);
}
}
}