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

229 lines
6.6 KiB
TypeScript

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;
};
const randomId = () => Math.random().toString(36).substring(2, 8);
/**
* 助手初始化类
* @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();
this.initIgnore();
}
get query() {
if (!this.#query) {
this.setQuery();
}
return this.#query;
}
get baseURL() {
return `${this.getConfig()?.app?.url || 'https://kevisual.cn'}/api/router`;
}
setQuery(query?: Query) {
this.#query = query || new Query({
url: `${this.getConfig()?.app?.url || '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创建成功'));
} else {
const config = this.getConfig();
if (!config?.app?.id) {
if (!config.app) {
config.app = {};
}
config.app.id = randomId();
this.setConfig(config);
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",
"cnb": "ASSISTANT_CONFIG_DIR=/workspace asst server -s -p 7878"
},
"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,
};
}
initIgnore() {
const gitignorePath = path.join(this.configDir, '.gitignore');
let content = '';
if (checkFileExists(gitignorePath, true)) {
content = fs.readFileSync(gitignorePath, 'utf-8');
}
const ignoreLines = [
'node_modules',
'.DS_Store',
'dist',
'pack-dist',
'cache-file',
'build',
'apps/**/node_modules/',
'pages/**/node_modules/',
'.env',
'!.env*development',
'.pnpm-store',
'.vite',
'.astro'
];
let updated = false;
ignoreLines.forEach((line) => {
if (!content.includes(line)) {
content += `\n${line}`;
updated = true;
}
});
if (updated) {
fs.writeFileSync(gitignorePath, content.trim() + '\n');
console.log(chalk.green('.gitignore 文件更新成功'));
}
}
protected getDefaultInitAssistantConfig() {
const id = randomId();
return {
app: {
url: 'https://kevisual.cn',
id,
},
description: '助手配置文件',
docs: "https://kevisual.cn/root/cli/docs/",
home: '/root/home',
proxy: [],
share: {
enabled: false,
url: 'https://kevisual.cn/ws/proxy',
},
} as AssistantConfigData;
}
getHttps() {
const https = this.getConfig()?.https || {};
return {
https,
protocol: https?.type === 'https' ? 'https' : 'http',
};
}
}