import fs from 'node:fs'; import path from 'node:path'; import { checkFileExists, AssistantConfig, AssistantConfigData, parseHomeArg, parseHelpArg } from '@/module/assistant/index.ts'; import { chalk } from '@/module/chalk.ts'; import { HttpsPem } from '@/module/assistant/https/sign.ts'; import { Query } from '@kevisual/query/query'; import { installDeps } from '@/module/npm-install.ts' export { parseHomeArg, parseHelpArg }; export type AssistantInitOptions = { path?: string; init?: boolean; }; /** * 助手初始化类 * @class AssistantInit */ export class AssistantInit extends AssistantConfig { #query: Query constructor(opts?: AssistantInitOptions) { const configDir = opts?.path || process.cwd(); super({ configDir, init: false, }); if (opts?.init) { this.init(); } } async init() { // 1. 检查助手路径是否存在 if (!this.checkConfigPath()) { console.log(chalk.blue('助手路径不存在,正在创建...')); super.init(); } else { super.init(); const assistantConfig = this; console.log(chalk.yellow('助手路径已存在'), chalk.green(assistantConfig.configDir)); } this.createAssistantConfig(); this.createEnvConfig(); this.createOtherConfig(); this.initPnpm(); } get query() { if (!this.#query) { this.setQuery(); } return this.#query; } setQuery(query?: Query) { this.#query = query || new Query({ url: `${this.getConfig()?.pageApi || 'https://kevisual.cn'}/api/router`, }); } checkConfigPath() { const assistantPath = path.join(this.configDir, 'assistant-app', 'assistant-config.json'); return checkFileExists(assistantPath); } createEnvConfig() { const env = this.configPath?.envConfigPath; // 创建助手环境配置文件 env if (!checkFileExists(env, true)) { fs.writeFileSync(env, '# 环境配置文件\n'); console.log(chalk.green('助手环境配置.env文件创建成功')); } } createOtherConfig() { const appsConfig = this.configPath?.appsConfigPath; // 创建助手应用配置文件 apps if (!checkFileExists(appsConfig, true)) { fs.writeFileSync(appsConfig, JSON.stringify({ description: 'apps manager.', list: [] })); console.log(chalk.green('助手应用配置文件 apps.json 创建成功')); } // create pem dir // const pemDir = path.join(this.configPath?.configDir, 'pem'); const httpsPem = new HttpsPem(this); if (httpsPem.isHttps) { if (!checkFileExists(pemDir)) { console.log(chalk.green('助手证书目录创建成功')); } } } createAssistantConfig() { const assistantPath = this.configPath?.configPath; // 创建助手配置文件 assistant-config.json if (!checkFileExists(assistantPath, true)) { this.setConfig(this.getDefaultInitAssistantConfig()); console.log(chalk.green('助手配置文件assistant-config.json创建成功')); } } initPnpm() { const pnpmPath = path.join(this.configDir, 'assistant-app', 'pnpm-workspace.yaml'); let create = false; if (!checkFileExists(pnpmPath, true)) { create = true; fs.writeFileSync( pnpmPath, `packages: - 'apps/**/*' - 'pages/**/*' `, ); console.log(chalk.green('助手 pnpm-workspace.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/root/code-center/app.mjs --name root/code-center", "proxy": "pm2 start apps/root/page-proxy/app.mjs --name root/page-proxy" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@kevisual/router": "latest", "@kevisual/use-config": "latest", "@kevisual/query": "latest", "ioredis": "latest", "minio": "latest", "pg": "latest", "pm2": "latest", "sequelize": "latest", "crypto-js": "latest", "better-sqlite3": "latest", "unstorage": "latest", "dayjs": "latest", "es-toolkit": "latest", "node-cron": "latest", "dotenv": "latest" }, "devDependencies": { "@types/node": "latest", "@types/crypto-js": "latest" } } `, ); console.log(chalk.green('助手 package.json 文件创建成功, 正在安装依赖...')); installDeps({ appPath: path.dirname(packagePath), isProduction: true }).then(() => { console.log(chalk.green('助手依赖安装完成')); }); } return { create, }; } protected getDefaultInitAssistantConfig() { return { description: '助手配置文件', home: '/root/center', proxy: [], apiProxyList: [], share: { enabled: false, name: 'abc', url: 'https://kevisual.cn/ws/proxy', }, watch: { enabled: true, }, } as AssistantConfigData; } getHttps() { const https = this.getConfig()?.https || {}; return { https, protocol: https?.type === 'https' ? 'https' : 'http', }; } }