clear code
This commit is contained in:
		
							
								
								
									
										29
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "@kevisual/envision-cli", |   "name": "@kevisual/envision-cli", | ||||||
|   "version": "0.0.35", |   "version": "0.0.37", | ||||||
|   "description": "envision command tools", |   "description": "envision command tools", | ||||||
|   "main": "dist/app.mjs", |   "main": "dist/app.mjs", | ||||||
|   "type": "module", |   "type": "module", | ||||||
| @@ -40,10 +40,9 @@ | |||||||
|     "@rollup/plugin-json": "^6.1.0", |     "@rollup/plugin-json": "^6.1.0", | ||||||
|     "@rollup/plugin-node-resolve": "^16.0.1", |     "@rollup/plugin-node-resolve": "^16.0.1", | ||||||
|     "@rollup/plugin-replace": "^6.0.2", |     "@rollup/plugin-replace": "^6.0.2", | ||||||
|     "@rollup/plugin-typescript": "^12.1.2", |  | ||||||
|     "@types/crypto-js": "^4.2.2", |     "@types/crypto-js": "^4.2.2", | ||||||
|     "@types/jsonwebtoken": "^9.0.9", |     "@types/jsonwebtoken": "^9.0.9", | ||||||
|     "@types/node": "^22.13.14", |     "@types/node": "^22.13.17", | ||||||
|     "chalk": "^5.4.1", |     "chalk": "^5.4.1", | ||||||
|     "commander": "^13.1.0", |     "commander": "^13.1.0", | ||||||
|     "fast-glob": "^3.3.3", |     "fast-glob": "^3.3.3", | ||||||
| @@ -51,17 +50,12 @@ | |||||||
|     "form-data": "^4.0.2", |     "form-data": "^4.0.2", | ||||||
|     "ignore": "^7.0.3", |     "ignore": "^7.0.3", | ||||||
|     "inquirer": "^12.5.0", |     "inquirer": "^12.5.0", | ||||||
|     "rimraf": "^6.0.1", |     "rollup": "^4.39.0", | ||||||
|     "rollup": "^4.38.0", |  | ||||||
|     "rollup-plugin-dts": "^6.2.1", |  | ||||||
|     "rollup-plugin-esbuild": "^6.2.1", |     "rollup-plugin-esbuild": "^6.2.1", | ||||||
|     "tar": "^7.4.3", |     "tar": "^7.4.3", | ||||||
|     "tslib": "^2.8.1", |     "@kevisual/load": "^0.0.6", | ||||||
|     "tsup": "^8.4.0", |     "crypto-js": "^4.2.0", | ||||||
|     "typescript": "^5.8.2" |     "jsonwebtoken": "^9.0.2" | ||||||
|   }, |  | ||||||
|   "resolutions": { |  | ||||||
|     "picomatch": "^4" |  | ||||||
|   }, |   }, | ||||||
|   "engines": { |   "engines": { | ||||||
|     "node": ">=22.0.0" |     "node": ">=22.0.0" | ||||||
| @@ -69,14 +63,5 @@ | |||||||
|   "publishConfig": { |   "publishConfig": { | ||||||
|     "access": "public" |     "access": "public" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": {} | ||||||
|     "@kevisual/load": "^0.0.6", |  | ||||||
|     "@kevisual/router": "^0.0.9", |  | ||||||
|     "crypto-js": "^4.2.0", |  | ||||||
|     "jsonwebtoken": "^9.0.2", |  | ||||||
|     "pg-hstore": "^2.3.4", |  | ||||||
|     "sequelize": "^6.37.7", |  | ||||||
|     "sqlite3": "^5.1.7", |  | ||||||
|     "vite": "^6.2.3" |  | ||||||
|   } |  | ||||||
| } | } | ||||||
							
								
								
									
										1651
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1651
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,6 +1,4 @@ | |||||||
| // rollup.config.js | // rollup.config.js | ||||||
|  |  | ||||||
| import typescript from '@rollup/plugin-typescript'; |  | ||||||
| import resolve from '@rollup/plugin-node-resolve'; | import resolve from '@rollup/plugin-node-resolve'; | ||||||
| import commonjs from '@rollup/plugin-commonjs'; | import commonjs from '@rollup/plugin-commonjs'; | ||||||
| import json from '@rollup/plugin-json'; | import json from '@rollup/plugin-json'; | ||||||
| @@ -11,7 +9,7 @@ import esbuild from 'rollup-plugin-esbuild'; | |||||||
| import alias from '@rollup/plugin-alias'; | import alias from '@rollup/plugin-alias'; | ||||||
| import replace from '@rollup/plugin-replace'; | import replace from '@rollup/plugin-replace'; | ||||||
|  |  | ||||||
| const pkgs = JSON.parse(fs.readFileSync('./package.json', 'utf-8')); | const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf-8')); | ||||||
| /** | /** | ||||||
|  * @type {import('rollup').RollupOptions} |  * @type {import('rollup').RollupOptions} | ||||||
|  */ |  */ | ||||||
| @@ -26,7 +24,7 @@ const config = { | |||||||
|   plugins: [ |   plugins: [ | ||||||
|     replace({ |     replace({ | ||||||
|       preventAssignment: true, // 防止意外赋值 |       preventAssignment: true, // 防止意外赋值 | ||||||
|       VERSION: JSON.stringify(pkgs.version || '1.0.0'), |       VERSION: JSON.stringify(pkg.version || '1.0.0'), | ||||||
|     }), |     }), | ||||||
|     alias({ |     alias({ | ||||||
|       // only esbuild needs to be configured |       // only esbuild needs to be configured | ||||||
| @@ -66,15 +64,7 @@ const config = { | |||||||
|       tsconfig: 'tsconfig.json', |       tsconfig: 'tsconfig.json', | ||||||
|     }), |     }), | ||||||
|     json(), |     json(), | ||||||
|     // typescript({ |  | ||||||
|     //   allowImportingTsExtensions: true, |  | ||||||
|     //   noEmit: true, |  | ||||||
|     //   // 不生成声明文件 |  | ||||||
|     //   declaration: false, |  | ||||||
|     // }), // 使用 @rollup/plugin-typescript 处理 TypeScript 文件 |  | ||||||
|   ], |   ], | ||||||
|   // 将 sqlite3 作为外部依赖 |  | ||||||
|   external: ['sqlite3', 'sequelize', 'vite', 'sequelize', '@kevisual/router', 'ioredis', 'socket.io', 'minio'], |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export default [config]; | export default [config]; | ||||||
|   | |||||||
| @@ -1,30 +0,0 @@ | |||||||
| import { App } from '@kevisual/router'; |  | ||||||
| import { app } from './app.ts'; |  | ||||||
|  |  | ||||||
| type Message = { |  | ||||||
|   path: string; |  | ||||||
|   key?: string; |  | ||||||
|   payload?: any; |  | ||||||
| }; |  | ||||||
| type Response = { |  | ||||||
|   code: number; |  | ||||||
|   data?: any; |  | ||||||
|   message?: string; |  | ||||||
| }; |  | ||||||
| export const runApp = async (msg: Message): Promise<Response> => { |  | ||||||
|   try { |  | ||||||
|     const { code, body, message } = await app.call(msg); |  | ||||||
|     const res = { code, data: body }; |  | ||||||
|     if (message) { |  | ||||||
|       res['message'] = message; |  | ||||||
|     } |  | ||||||
|     return res as { code: number; data: any; message?: string }; |  | ||||||
|   } catch (error) { |  | ||||||
|     console.error('runApp error', error); |  | ||||||
|     return { code: 500, message: error.message }; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export const loadApp = async (mainApp: App) => { |  | ||||||
|   mainApp.importApp(app); |  | ||||||
| }; |  | ||||||
							
								
								
									
										54
									
								
								src/app.ts
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/app.ts
									
									
									
									
									
								
							| @@ -1,54 +0,0 @@ | |||||||
| import { App } from '@kevisual/router'; |  | ||||||
| import fs from 'fs'; |  | ||||||
| import { getConfig, getPidList, pidFilePath, checkFileExists } from './module/get-config.ts'; |  | ||||||
| import { sequelize } from './module/sequelize.ts'; |  | ||||||
| export { sequelize }; |  | ||||||
|  |  | ||||||
| export const app = new App({ |  | ||||||
|   serverOptions: { |  | ||||||
|     cors: { |  | ||||||
|       origin: '*', // 允许所有来源 |  | ||||||
|     }, |  | ||||||
|     httpType: 'https', |  | ||||||
|   }, |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| // 处理进程退出或中断信号,确保删除 pid 文件 |  | ||||||
| const cleanUp = () => { |  | ||||||
|   const pidList = getPidList(); |  | ||||||
|   const findPid = pidList.find((item) => Number(item.pid) === process.pid); |  | ||||||
|   // if (checkFileExists(pidFilePath)) { |  | ||||||
|   //   const pid = fs.readFileSync(pidFilePath, 'utf-8'); |  | ||||||
|   //   if (Number(pid) === process.pid) { |  | ||||||
|   //     fs.unlinkSync(pidFilePath); |  | ||||||
|   //     console.log('server id', process.pid, 'is exit'); |  | ||||||
|   //   } |  | ||||||
|   // } |  | ||||||
|   if (findPid) { |  | ||||||
|     console.log('server id', process.pid, 'is exit'); |  | ||||||
|     try { |  | ||||||
|       fs.unlinkSync(findPid.file); |  | ||||||
|     } catch (e) { |  | ||||||
|       console.log('unlinkSync error', findPid); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   process.exit(0); // 退出进程 |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| // 当进程收到以下信号时,删除 pid 文件 |  | ||||||
| process.on('SIGINT', cleanUp); // 例如 Ctrl+C |  | ||||||
| process.on('SIGTERM', cleanUp); // 终止信号 |  | ||||||
| process.on('exit', cleanUp); // 进程退出 |  | ||||||
|  |  | ||||||
| export const createApp = async () => { |  | ||||||
|   if (checkFileExists(pidFilePath)) { |  | ||||||
|     const pid = fs.readFileSync(pidFilePath, 'utf-8'); |  | ||||||
|     console.log('服务已经启动,请勿重复启动。', 'server id', pid); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   fs.writeFileSync(pidFilePath, process.pid.toString()); |  | ||||||
|   app.listen(21015, () => { |  | ||||||
|     console.log('Server is running on port 21015', 'https://localhost:21015/api/router', 'server id', process.pid); |  | ||||||
|   }); |  | ||||||
|   // import('./route.ts'); |  | ||||||
| }; |  | ||||||
| @@ -119,3 +119,15 @@ const command = new Command('me') | |||||||
|   }); |   }); | ||||||
|  |  | ||||||
| program.addCommand(command); | program.addCommand(command); | ||||||
|  |  | ||||||
|  | const logoutCommand = new Command('logout').description('退出登陆').action(async () => { | ||||||
|  |   try { | ||||||
|  |     await queryLogin.logout(); | ||||||
|  |     storage.removeItem('token'); | ||||||
|  |     console.log('退出成功'); | ||||||
|  |   } catch (error) { | ||||||
|  |     console.log('退出失败', error); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | program.addCommand(logoutCommand); | ||||||
|   | |||||||
| @@ -1,11 +0,0 @@ | |||||||
| import { program as app, Command } from '@/program.ts'; |  | ||||||
| import { getConfig, writeConfig } from '@/module/index.ts'; |  | ||||||
|  |  | ||||||
| const command = new Command('logout') |  | ||||||
|   .description('') |  | ||||||
|   .action(async () => { |  | ||||||
|     const config = getConfig(); |  | ||||||
|     writeConfig({ ...config, token: '' }); |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
| app.addCommand(command); |  | ||||||
| @@ -13,7 +13,7 @@ const tokenList = new Command('list') | |||||||
|   // .option('-r --remove <number>', 'remove token by number') |   // .option('-r --remove <number>', 'remove token by number') | ||||||
|   .action(async (opts) => { |   .action(async (opts) => { | ||||||
|     console.log('show token list'); |     console.log('show token list'); | ||||||
|     queryLogin.cacheStore.init() |     queryLogin.cacheStore.init(); | ||||||
|     // const res = await queryLogin.cacheStore.cache.get('token'); |     // const res = await queryLogin.cacheStore.cache.get('token'); | ||||||
|     console.log(queryLogin.cacheStore.cacheData); |     console.log(queryLogin.cacheStore.cacheData); | ||||||
|     // console.log(util.inspect(res, { colors: true, depth: 4 })); |     // console.log(util.inspect(res, { colors: true, depth: 4 })); | ||||||
| @@ -33,6 +33,11 @@ const baseURL = new Command('baseURL') | |||||||
|   .action(async (opts) => { |   .action(async (opts) => { | ||||||
|     let config = getConfig(); |     let config = getConfig(); | ||||||
|     let list = (config.baseURLList as Array<string>) || []; |     let list = (config.baseURLList as Array<string>) || []; | ||||||
|  |     if (!config.baseURL) { | ||||||
|  |       list = ['https://kevisual.cn']; | ||||||
|  |       writeConfig({ ...config, baseURL: 'https://kevisual.cn', baseURLList: list }); | ||||||
|  |       config = getConfig(); | ||||||
|  |     } | ||||||
|     const quineList = (list: string[]) => { |     const quineList = (list: string[]) => { | ||||||
|       const newList = new Set(list); |       const newList = new Set(list); | ||||||
|       return Array.from(newList); |       return Array.from(newList); | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ import inquirer from 'inquirer'; | |||||||
| import { query } from '../module/index.ts'; | import { query } from '../module/index.ts'; | ||||||
| import chalk from 'chalk'; | import chalk from 'chalk'; | ||||||
| import util from 'util'; | import util from 'util'; | ||||||
| import { runApp } from '@/app-run.ts'; |  | ||||||
|  |  | ||||||
| const router = new Command('router').description('router get'); | const router = new Command('router').description('router get'); | ||||||
| program.addCommand(router); | program.addCommand(router); | ||||||
| @@ -58,45 +57,3 @@ const command = new Command('service') | |||||||
|   }); |   }); | ||||||
|  |  | ||||||
| router.addCommand(command); | router.addCommand(command); | ||||||
|  |  | ||||||
| const localRouter = new Command('local') |  | ||||||
|   .description('router local get') |  | ||||||
|   .option('-p, --path <path>', '第一路径 path') |  | ||||||
|   .option('-k, --key <key>', '第二路径 key') |  | ||||||
|   .action(async (options) => { |  | ||||||
|     let { path, key } = options; |  | ||||||
|     // 如果没有传递参数,则通过交互式输入 |  | ||||||
|     if (!path) { |  | ||||||
|       const answers = await inquirer.prompt([ |  | ||||||
|         { |  | ||||||
|           type: 'input', |  | ||||||
|           name: 'path', |  | ||||||
|           required: true, |  | ||||||
|           message: 'Enter your path:', |  | ||||||
|           when: () => !path, // 当 username 为空时,提示用户输入 |  | ||||||
|         }, |  | ||||||
|       ]); |  | ||||||
|       path = answers.path || path; |  | ||||||
|     } |  | ||||||
|     if (!key) { |  | ||||||
|       const answers = await inquirer.prompt([ |  | ||||||
|         { |  | ||||||
|           type: 'input', |  | ||||||
|           required: false, |  | ||||||
|           name: 'key', |  | ||||||
|           message: 'Enter your key:', |  | ||||||
|         }, |  | ||||||
|       ]); |  | ||||||
|       key = answers.key || key; |  | ||||||
|     } |  | ||||||
|     const res = await runApp({ path, key }); |  | ||||||
|     if (res?.code === 200) { |  | ||||||
|       console.log('query success'); |  | ||||||
|  |  | ||||||
|       console.log(chalk.green(util.inspect(res, { colors: true, depth: 4 }))); |  | ||||||
|     } else { |  | ||||||
|       console.log('error query', res.code, res.message || ''); |  | ||||||
|     } |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
| router.addCommand(localRouter); |  | ||||||
|   | |||||||
| @@ -1,40 +0,0 @@ | |||||||
| import { program as app, Command } from '@/program.ts'; |  | ||||||
| import { getConfig, writeConfig, pidFilePath, checkFileExists } from '@/module/index.ts'; |  | ||||||
| import { createApp } from '@/app.ts'; |  | ||||||
| import fs from 'fs'; |  | ||||||
|  |  | ||||||
| const command = new Command('serve') |  | ||||||
|   .description('serve manager') |  | ||||||
|   .option('-e, --exit', '退出进程') |  | ||||||
|   .option('-s, --start', '启动进程') |  | ||||||
|   .action(async (options) => { |  | ||||||
|     console.log('options', options); |  | ||||||
|     if (options.exit) { |  | ||||||
|       if (checkFileExists(pidFilePath)) { |  | ||||||
|         console.log('服务已经启动, 准备退出'); |  | ||||||
|         const pid = fs.readFileSync(pidFilePath, 'utf-8'); |  | ||||||
|         // 通知进程退出 |  | ||||||
|         process.kill(Number(pid), 'SIGTERM'); |  | ||||||
|         setTimeout(() => { |  | ||||||
|           if (checkFileExists(pidFilePath)) { |  | ||||||
|             // 强制删除 pid 文件 |  | ||||||
|             fs.unlinkSync(pidFilePath); |  | ||||||
|           } |  | ||||||
|         }, 2000); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (options.start) { |  | ||||||
|       const config = getConfig(); |  | ||||||
|       await createApp(); |  | ||||||
|     } |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
| app.addCommand(command); |  | ||||||
|  |  | ||||||
| const start = new Command('start').description('start serve').action(async () => { |  | ||||||
|   const config = getConfig(); |  | ||||||
|   await createApp(); |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| app.addCommand(start); |  | ||||||
| @@ -1,71 +0,0 @@ | |||||||
| import { program as app, Command } from '@/program.ts'; |  | ||||||
| import { getConfig, writeConfig, checkFileExists, query } from '@/module/index.ts'; |  | ||||||
| import fs from 'fs'; |  | ||||||
| import path from 'path'; |  | ||||||
| import { startContainerServer } from '@/module/run-vite.ts'; |  | ||||||
| // web 开发模块 |  | ||||||
| const command = new Command('web') |  | ||||||
|   .description('web dev manager') |  | ||||||
|   .option('-e, --exit', '退出进程') |  | ||||||
|   .option('-s, --start', '启动进程') |  | ||||||
|  |  | ||||||
|   .action(async (options) => { |  | ||||||
|     const { exit, start } = options || {}; |  | ||||||
|   }); |  | ||||||
| app.addCommand(command); |  | ||||||
|  |  | ||||||
| // container 开发模块 |  | ||||||
| const container = new Command('container') |  | ||||||
|   .description('container manager') |  | ||||||
|   .option('-d, --container <id>', '下载镜像') |  | ||||||
|   .option('-f, --force', '下载镜像') |  | ||||||
|   .option('-u, --upload <id>', '上传镜像') |  | ||||||
|   .action(async (options) => { |  | ||||||
|     const { container, upload, force } = options || {}; |  | ||||||
|     const config = getConfig(); |  | ||||||
|     const workdir = config.workdir; |  | ||||||
|     if (!workdir) { |  | ||||||
|       console.log('请先配置工作目录'); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     if (!config.token) { |  | ||||||
|       console.log('请先登录'); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     // 32210aa6-3d5a-4687-b769-ae4e8137ec1e |  | ||||||
|     if (container) { |  | ||||||
|       console.log('下载镜像', container); |  | ||||||
|       const res = await query.post({ path: 'container', key: 'get', id: container }); |  | ||||||
|       if (res.code !== 200) { |  | ||||||
|         console.log('error', res.message || ''); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|       await startContainerServer(res.data, force); |  | ||||||
|     } |  | ||||||
|     if (upload) { |  | ||||||
|       console.log('上传镜像', upload); |  | ||||||
|       const directory = path.join(workdir, 'container', upload); |  | ||||||
|       if (!checkFileExists(directory)) { |  | ||||||
|         console.log('文件夹不存在'); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|       const code = fs.readFileSync(path.join(directory, 'index.js'), 'utf-8'); |  | ||||||
|       if (!code) { |  | ||||||
|         console.log('文件不能为空'); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|       const res = await query.post({ |  | ||||||
|         path: 'container', // |  | ||||||
|         key: 'update', |  | ||||||
|         data: { id: upload, code }, |  | ||||||
|       }); |  | ||||||
|       if (res.code !== 200) { |  | ||||||
|         console.log('error', res.message || ''); |  | ||||||
|         console.log(res); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
|       console.log('上传成功'); |  | ||||||
|     } |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
| app.addCommand(container); |  | ||||||
| @@ -1,11 +1,8 @@ | |||||||
| import { program } from '@/program.ts'; | import { program } from '@/program.ts'; | ||||||
| import './command/login.ts'; | import './command/login.ts'; | ||||||
| import './command/logout.ts'; |  | ||||||
| import './command/ls-token.ts'; | import './command/ls-token.ts'; | ||||||
| import './command/deploy.ts'; | import './command/deploy.ts'; | ||||||
| import './command/serve.ts'; |  | ||||||
| import './command/config.ts'; | import './command/config.ts'; | ||||||
| import './command/web.ts'; |  | ||||||
| import './command/router.ts'; | import './command/router.ts'; | ||||||
| import './command/npm.ts'; | import './command/npm.ts'; | ||||||
| import './command/publish.ts'; | import './command/publish.ts'; | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import path from 'path'; | import path from 'path'; | ||||||
| import fs from 'fs'; | import fs from 'fs'; | ||||||
|  | import { storage } from '../query.ts'; | ||||||
|  |  | ||||||
| type DownloadTask = { | type DownloadTask = { | ||||||
|   downloadPath: string; |   downloadPath: string; | ||||||
| @@ -62,8 +63,13 @@ export const installApp = async (app: Package, opts: InstallAppOpts = {}) => { | |||||||
|       if (!fs.existsSync(dir)) { |       if (!fs.existsSync(dir)) { | ||||||
|         fs.mkdirSync(dir, { recursive: true }); |         fs.mkdirSync(dir, { recursive: true }); | ||||||
|       } |       } | ||||||
|       console.log('downloadUrl', downloadUrl); |       console.log('downloadUrwl', downloadUrl); | ||||||
|       const res = await fetch(downloadUrl); |       const token = process.env.KEVISUAL_TOKEN || storage.getItem('token'); | ||||||
|  |       const fetchURL = new URL(downloadUrl); | ||||||
|  |       if (token) { | ||||||
|  |         fetchURL.searchParams.set('token', token); | ||||||
|  |       } | ||||||
|  |       const res = await fetch(fetchURL.toString()); | ||||||
|       const blob = await res.blob(); |       const blob = await res.blob(); | ||||||
|       fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); |       fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -5,20 +5,6 @@ import fs from 'fs'; | |||||||
| export const envisionPath = path.join(os.homedir(), '.config', 'envision'); | export const envisionPath = path.join(os.homedir(), '.config', 'envision'); | ||||||
| const configPath = path.join(os.homedir(), '.config', 'envision', 'config.json'); | const configPath = path.join(os.homedir(), '.config', 'envision', 'config.json'); | ||||||
|  |  | ||||||
| export const pidFilePath = path.join(envisionPath, 'app.pid'); |  | ||||||
| export const dbPath = path.join(envisionPath, 'db.sqlite'); |  | ||||||
| const envisionPidDir = path.join(envisionPath); |  | ||||||
| export const getPidList = () => { |  | ||||||
|   const files = fs.readdirSync(envisionPidDir); |  | ||||||
|   const pidFiles = files.filter((file) => file.endsWith('.pid')); |  | ||||||
|   return pidFiles.map((file) => { |  | ||||||
|     const pid = fs.readFileSync(path.join(envisionPidDir, file), 'utf-8'); |  | ||||||
|     return { pid, file: path.join(envisionPidDir, file) }; |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
| export const writeVitePid = (pid: number) => { |  | ||||||
|   fs.writeFileSync(path.join(envisionPath, `vite-${pid}.pid`), pid.toString()); |  | ||||||
| }; |  | ||||||
| export const checkFileExists = (filePath: string) => { | export const checkFileExists = (filePath: string) => { | ||||||
|   try { |   try { | ||||||
|     fs.accessSync(filePath, fs.constants.F_OK); |     fs.accessSync(filePath, fs.constants.F_OK); | ||||||
| @@ -39,6 +25,9 @@ export const getConfig = () => { | |||||||
|       return {}; |       return {}; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   writeConfig({ | ||||||
|  |     baseURL: 'https://kevisual.cn', | ||||||
|  |   }); | ||||||
|   return {}; |   return {}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,7 +25,11 @@ export const query = new Query({ | |||||||
|  |  | ||||||
| query.beforeRequest = async (config) => { | query.beforeRequest = async (config) => { | ||||||
|   if (config.headers) { |   if (config.headers) { | ||||||
|     const token = await storage.getItem('token'); |     let token = process.env.KEVISUAL_TOKEN; | ||||||
|  |     if (!token) { | ||||||
|  |       token = await storage.getItem('token'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (token) { |     if (token) { | ||||||
|       config.headers['Authorization'] = 'Bearer ' + token; |       config.headers['Authorization'] = 'Bearer ' + token; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,79 +0,0 @@ | |||||||
| import fs from 'fs'; |  | ||||||
| import path from 'path'; |  | ||||||
| import { createServer } from 'vite'; |  | ||||||
| import { checkFileExists, getConfig, writeVitePid } from './index.ts'; |  | ||||||
|  |  | ||||||
| export const runVite = async (entry: string) => { |  | ||||||
|   const entryDir = path.dirname(entry); |  | ||||||
|   const server = await createServer({ |  | ||||||
|     // Vite 配置选项 |  | ||||||
|     root: entryDir, |  | ||||||
|     server: { |  | ||||||
|       port: 7101, // 可以根据需要设置端口 |  | ||||||
|       host: '0.0.0.0', |  | ||||||
|     }, |  | ||||||
|   }); |  | ||||||
|   await server.listen(); |  | ||||||
|   console.log('Vite server is running at:', server.config.server.port); |  | ||||||
| }; |  | ||||||
| const template = `<!DOCTYPE html> |  | ||||||
| <html lang="zh-CN"> |  | ||||||
| <head> |  | ||||||
|   <meta charset="UTF-8"> |  | ||||||
|   <meta name="viewport" content="width=device-width, initial-scale=1.0"> |  | ||||||
|    <link rel="icon" href="https://envision.xiongxiao.me/resources/root/avatar.png"/> |  | ||||||
|   <title>Container Develop</title> |  | ||||||
|   <style> |  | ||||||
|     html, |  | ||||||
|     body { |  | ||||||
|       margin: 0; |  | ||||||
|       padding: 0; |  | ||||||
|       width: 100%; |  | ||||||
|       height: 100%; |  | ||||||
|     } |  | ||||||
|     body { |  | ||||||
|       font-size: 16px; |  | ||||||
|     } |  | ||||||
|   </style> |  | ||||||
| </head> |  | ||||||
|  |  | ||||||
| <body> |  | ||||||
|   <div id="root"></div> |  | ||||||
|   <script type="module"> |  | ||||||
|     import { ContainerOne } from 'https://kevisual.xiongxiao.me/system/lib/container.js' |  | ||||||
|     import { render, unmount } from './index.js' |  | ||||||
|     const container = new ContainerOne({ |  | ||||||
|       root: '#root', |  | ||||||
|     }); |  | ||||||
|     container.renderOne({ |  | ||||||
|       code: {render, unmount} |  | ||||||
|     }); |  | ||||||
|   </script> |  | ||||||
| </body> |  | ||||||
|  |  | ||||||
| </html>`; |  | ||||||
| export const startContainerServer = async (container: any, force: boolean) => { |  | ||||||
|   const { id, code } = container; |  | ||||||
|   const config = getConfig(); |  | ||||||
|   const workdir = config.workdir; |  | ||||||
|   if (!workdir) { |  | ||||||
|     console.log('请先配置工作目录'); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   if (!config.token) { |  | ||||||
|     console.log('请先登录'); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   const directory = path.join(workdir, 'container', id); |  | ||||||
|   if (!checkFileExists(directory) || force) { |  | ||||||
|     fs.mkdirSync(directory, { recursive: true }); |  | ||||||
|     fs.writeFileSync(path.join(directory, 'index.js'), code); |  | ||||||
|     fs.writeFileSync(path.join(directory, 'index.html'), template); |  | ||||||
|   } else { |  | ||||||
|     console.log('文件夹已存在'); |  | ||||||
|   } |  | ||||||
|   await runVite(path.join(directory, 'index.html')); |  | ||||||
|   console.log('container server is running at:', 'http://localhost:7101'); |  | ||||||
|   console.log('pid:', process.pid); |  | ||||||
|   writeVitePid(process.pid); |  | ||||||
| }; |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| import { Sequelize } from 'sequelize'; |  | ||||||
| import { dbPath } from './get-config.ts'; |  | ||||||
| // connect to db |  | ||||||
| export const sequelize = new Sequelize({ |  | ||||||
|   dialect: 'sqlite', |  | ||||||
|   // storage: 'db.sqlite', |  | ||||||
|   storage: dbPath, |  | ||||||
|   // logging: false, |  | ||||||
| }); |  | ||||||
|  |  | ||||||
| sequelize |  | ||||||
|   .authenticate({ logging: false }) |  | ||||||
|   .then(() => {}) |  | ||||||
|   .catch((err) => { |  | ||||||
|     console.error('Unable to connect to the database:', err); |  | ||||||
|   }); |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| export * from './user/login.ts'; |  | ||||||
| @@ -1,40 +0,0 @@ | |||||||
| import { query } from '@/module/query.ts'; |  | ||||||
|  |  | ||||||
| export const queryLogin = async (username: string, password: string) => { |  | ||||||
|   return await query.post({ |  | ||||||
|     path: 'user', |  | ||||||
|     key: 'login', |  | ||||||
|     payload: { |  | ||||||
|       username, |  | ||||||
|       password, |  | ||||||
|       loginType: 'plugin', |  | ||||||
|     }, |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export const queryMe = async () => { |  | ||||||
|   return await query.post({ |  | ||||||
|     path: 'user', |  | ||||||
|     key: 'me', |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export const switchOrg = async (username) => { |  | ||||||
|   return await query.post({ |  | ||||||
|     path: 'user', |  | ||||||
|     key: 'switchOrg', |  | ||||||
|     data: { |  | ||||||
|       loginType: 'plugin', |  | ||||||
|       username, |  | ||||||
|     }, |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
| export const switchMe = async () => { |  | ||||||
|   return await query.post({ |  | ||||||
|     path: 'user', |  | ||||||
|     key: 'switchOrg', |  | ||||||
|     data: { |  | ||||||
|       type: 'user', |  | ||||||
|     }, |  | ||||||
|   }); |  | ||||||
| }; |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| import './route/system-config/index.ts'; |  | ||||||
 Submodule submodules/kevisual-query-login updated: 98c8a2ad86...f1024941ed
									
								
							
		Reference in New Issue
	
	Block a user