generated from tailored/router-template
	base module
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -12,3 +12,4 @@ cache-file | |||||||
| /apps | /apps | ||||||
|  |  | ||||||
| logs | logs | ||||||
|  | root/ | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								.npmrc
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								.npmrc
									
									
									
									
									
								
							| @@ -1,2 +1,3 @@ | |||||||
| //npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} | //npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} | ||||||
| //registry.npmjs.org/:_authToken=${NPM_TOKEN} | //registry.npmjs.org/:_authToken=${NPM_TOKEN} | ||||||
|  | ignore-workspace-root-check=true | ||||||
							
								
								
									
										2
									
								
								assistant-module/.npmrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								assistant-module/.npmrc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | //npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} | ||||||
|  | //registry.npmjs.org/:_authToken=${NPM_TOKEN} | ||||||
							
								
								
									
										49
									
								
								assistant-module/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								assistant-module/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | { | ||||||
|  |   "name": "@kevisual/assistant-module", | ||||||
|  |   "version": "0.0.3", | ||||||
|  |   "description": "assistant module", | ||||||
|  |   "main": "dist/assistant-module.mjs", | ||||||
|  |   "types": "dist/assistant-module.d.ts", | ||||||
|  |   "scripts": { | ||||||
|  |     "dev": "rollup -c -w", | ||||||
|  |     "build": "npm run clean && rollup -c", | ||||||
|  |     "clean": "rm -rf dist" | ||||||
|  |   }, | ||||||
|  |   "keywords": [], | ||||||
|  |   "author": "abearxiong <xiongxiao@xiongxiao.me>", | ||||||
|  |   "license": "MIT", | ||||||
|  |   "type": "module", | ||||||
|  |   "devDependencies": { | ||||||
|  |     "@types/node": "^22.13.10", | ||||||
|  |     "@types/send": "^0.17.4", | ||||||
|  |     "@types/ws": "^8.18.0" | ||||||
|  |   }, | ||||||
|  |   "publishConfig": { | ||||||
|  |     "access": "public" | ||||||
|  |   }, | ||||||
|  |   "files": [ | ||||||
|  |     "dist" | ||||||
|  |   ], | ||||||
|  |   "exports": { | ||||||
|  |     ".": { | ||||||
|  |       "import": "./dist/assistant-module.mjs", | ||||||
|  |       "types": "./dist/assistant-module.d.ts" | ||||||
|  |     }, | ||||||
|  |     "./proxy": { | ||||||
|  |       "import": "./dist/assistant-proxy.mjs", | ||||||
|  |       "types": "./dist/assistant-proxy.d.ts" | ||||||
|  |     }, | ||||||
|  |     "./assistant-config": { | ||||||
|  |       "import": "./dist/assistant-config.mjs", | ||||||
|  |       "types": "./dist/assistant-config.d.ts" | ||||||
|  |     }, | ||||||
|  |     "./assistant-process": { | ||||||
|  |       "import": "./dist/assistant-process.mjs", | ||||||
|  |       "types": "./dist/assistant-process.d.ts" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "send": "^1.1.0", | ||||||
|  |     "ws": "^8.18.1" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								assistant-module/pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								assistant-module/pnpm-lock.yaml
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | lockfileVersion: '9.0' | ||||||
|  |  | ||||||
|  | settings: | ||||||
|  |   autoInstallPeers: true | ||||||
|  |   excludeLinksFromLockfile: false | ||||||
|  |  | ||||||
|  | importers: | ||||||
|  |  | ||||||
|  |   .: | ||||||
|  |     devDependencies: | ||||||
|  |       '@types/node': | ||||||
|  |         specifier: ^22.13.10 | ||||||
|  |         version: 22.13.10 | ||||||
|  |  | ||||||
|  | packages: | ||||||
|  |  | ||||||
|  |   '@types/node@22.13.10': | ||||||
|  |     resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} | ||||||
|  |  | ||||||
|  |   undici-types@6.20.0: | ||||||
|  |     resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} | ||||||
|  |  | ||||||
|  | snapshots: | ||||||
|  |  | ||||||
|  |   '@types/node@22.13.10': | ||||||
|  |     dependencies: | ||||||
|  |       undici-types: 6.20.0 | ||||||
|  |  | ||||||
|  |   undici-types@6.20.0: {} | ||||||
							
								
								
									
										172
									
								
								assistant-module/rollup.config.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								assistant-module/rollup.config.mjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | |||||||
|  | import resolve from '@rollup/plugin-node-resolve'; | ||||||
|  | import commonjs from '@rollup/plugin-commonjs'; | ||||||
|  | import json from '@rollup/plugin-json'; | ||||||
|  | import path from 'path'; | ||||||
|  | import esbuild from 'rollup-plugin-esbuild'; | ||||||
|  | import alias from '@rollup/plugin-alias'; | ||||||
|  | import replace from '@rollup/plugin-replace'; | ||||||
|  | import dts from 'rollup-plugin-dts'; | ||||||
|  | // @ts-ignore | ||||||
|  | import pkgs from './package.json' with {type: 'json'}; | ||||||
|  |  | ||||||
|  | const isDev = process.env.NODE_ENV === 'development'; | ||||||
|  | const input = './src/index.ts'; | ||||||
|  | /** | ||||||
|  |  * @type {import('rollup').RollupOptions} | ||||||
|  |  */ | ||||||
|  | const config = { | ||||||
|  |   input, | ||||||
|  |   output: { | ||||||
|  |     dir: './dist', | ||||||
|  |     entryFileNames: 'assistant-module.mjs', | ||||||
|  |     chunkFileNames: '[name]-[hash].mjs', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [ | ||||||
|  |     replace({ | ||||||
|  |       preventAssignment: true, // 防止意外赋值 | ||||||
|  |       DEV_SERVER: JSON.stringify(isDev), // 替换 process.env.NODE_ENV | ||||||
|  |       VERSION: JSON.stringify(pkgs.version), | ||||||
|  |     }), | ||||||
|  |     alias({ | ||||||
|  |       // only esbuild needs to be configured | ||||||
|  |       entries: [ | ||||||
|  |         { find: '@', replacement: path.resolve('src') }, // 配置 @ 为 src 目录 | ||||||
|  |         { find: 'http', replacement: 'node:http' }, | ||||||
|  |         { find: 'https', replacement: 'node:https' }, | ||||||
|  |         { find: 'fs', replacement: 'node:fs' }, | ||||||
|  |         { find: 'path', replacement: 'node:path' }, | ||||||
|  |         { find: 'crypto', replacement: 'node:crypto' }, | ||||||
|  |         { find: 'zlib', replacement: 'node:zlib' }, | ||||||
|  |         { find: 'stream', replacement: 'node:stream' }, | ||||||
|  |         { find: 'net', replacement: 'node:net' }, | ||||||
|  |         { find: 'tty', replacement: 'node:tty' }, | ||||||
|  |         { find: 'tls', replacement: 'node:tls' }, | ||||||
|  |         { find: 'buffer', replacement: 'node:buffer' }, | ||||||
|  |         { find: 'timers', replacement: 'node:timers' }, | ||||||
|  |         // { find: 'string_decoder', replacement: 'node:string_decoder' }, | ||||||
|  |         { find: 'dns', replacement: 'node:dns' }, | ||||||
|  |         { find: 'domain', replacement: 'node:domain' }, | ||||||
|  |         { find: 'os', replacement: 'node:os' }, | ||||||
|  |         { find: 'events', replacement: 'node:events' }, | ||||||
|  |         { find: 'url', replacement: 'node:url' }, | ||||||
|  |         { find: 'assert', replacement: 'node:assert' }, | ||||||
|  |         { find: 'util', replacement: 'node:util' }, | ||||||
|  |       ], | ||||||
|  |     }), | ||||||
|  |     resolve({ | ||||||
|  |       preferBuiltins: true, // 强制优先使用内置模块 | ||||||
|  |     }), | ||||||
|  |     commonjs(), | ||||||
|  |     esbuild({ | ||||||
|  |       target: 'node22', // | ||||||
|  |       minify: false, // 启用代码压缩 | ||||||
|  |       tsconfig: 'tsconfig.json', | ||||||
|  |     }), | ||||||
|  |     json(), | ||||||
|  |   ], | ||||||
|  |   external: [ | ||||||
|  |     /@kevisual\/router(\/.*)?/, //, // 路由 | ||||||
|  |     /@kevisual\/use-config(\/.*)?/, // | ||||||
|  |   ], | ||||||
|  | }; | ||||||
|  | const dtsConfig = [{ | ||||||
|  |   input, | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-module.d.ts', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [dts()], | ||||||
|  | }]; | ||||||
|  |  | ||||||
|  | const moduleConfig = { | ||||||
|  |   input: './src/assistant-proxy.ts', | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-proxy.mjs', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [ | ||||||
|  |     alias({ | ||||||
|  |       entries: [{ find: '@', replacement: path.resolve('src') }], | ||||||
|  |     }), | ||||||
|  |     resolve({ | ||||||
|  |       preferBuiltins: true, // 强制优先使用内置模块 | ||||||
|  |     }), | ||||||
|  |     commonjs(), | ||||||
|  |     esbuild({ | ||||||
|  |       target: 'node22', // | ||||||
|  |     }), | ||||||
|  |     json(), | ||||||
|  |   ], | ||||||
|  |  | ||||||
|  | }; | ||||||
|  | const moduleDtsConfig = [{ | ||||||
|  |   input: './src/assistant-proxy.ts', | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-proxy.d.ts', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [dts()], | ||||||
|  | }]; | ||||||
|  |  | ||||||
|  | const assistantConfigConfig = { | ||||||
|  |   input: './src/assistant-config.ts', | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-config.mjs', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [ | ||||||
|  |     alias({ | ||||||
|  |       entries: [{ find: '@', replacement: path.resolve('src') }], | ||||||
|  |     }), | ||||||
|  |     resolve({ | ||||||
|  |       preferBuiltins: true, // 强制优先使用内置模块 | ||||||
|  |     }), | ||||||
|  |     commonjs(), | ||||||
|  |     esbuild({ | ||||||
|  |       target: 'node22', // | ||||||
|  |     }), | ||||||
|  |     json(), | ||||||
|  |   ], | ||||||
|  | }; | ||||||
|  | const assistantConfigDtsConfig = [{ | ||||||
|  |   input: './src/assistant-config.ts', | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-config.d.ts', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [dts()], | ||||||
|  | }]; | ||||||
|  |  | ||||||
|  | const assistantProcessConfig = { | ||||||
|  |   input: './src/assistant-process.ts', | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-process.mjs', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [ | ||||||
|  |     alias({ | ||||||
|  |       entries: [{ find: '@', replacement: path.resolve('src') }], | ||||||
|  |     }), | ||||||
|  |     resolve({ | ||||||
|  |       preferBuiltins: true, // 强制优先使用内置模块 | ||||||
|  |     }), | ||||||
|  |     commonjs(), | ||||||
|  |     esbuild({ | ||||||
|  |       target: 'node22', // | ||||||
|  |     }), | ||||||
|  |     json(), | ||||||
|  |   ], | ||||||
|  | }; | ||||||
|  | const assistantProcessDtsConfig = [{   | ||||||
|  |   input: './src/assistant-process.ts', | ||||||
|  |   output: { | ||||||
|  |     file: 'dist/assistant-process.d.ts', | ||||||
|  |     format: 'esm', | ||||||
|  |   }, | ||||||
|  |   plugins: [dts()], | ||||||
|  | }]; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export default [config, ...dtsConfig, moduleConfig, ...moduleDtsConfig, assistantConfigConfig, ...assistantConfigDtsConfig, assistantProcessConfig, ...assistantProcessDtsConfig]; | ||||||
							
								
								
									
										1
									
								
								assistant-module/src/assistant-config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								assistant-module/src/assistant-config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | export * from './config/index.ts'; | ||||||
							
								
								
									
										1
									
								
								assistant-module/src/assistant-process.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								assistant-module/src/assistant-process.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | export * from './process/index.ts'; | ||||||
							
								
								
									
										1
									
								
								assistant-module/src/assistant-proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								assistant-module/src/assistant-proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | export * from './proxy/index.ts'; | ||||||
							
								
								
									
										111
									
								
								assistant-module/src/config/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								assistant-module/src/config/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | import path from 'path'; | ||||||
|  | import { homedir } from 'os'; | ||||||
|  | import fs from 'fs'; | ||||||
|  | import { checkFileExists, createDir } from '../file/index.ts'; | ||||||
|  | import { ProxyInfo } from '../proxy/proxy.ts'; | ||||||
|  |  | ||||||
|  | export const kevisualUrl = 'https://kevisual.xiongxiao.me'; | ||||||
|  | const configDir = createDir(path.join(homedir(), '.config/envision')); | ||||||
|  | export const configPath = path.join(configDir, 'assistant-config.json'); | ||||||
|  | export const appConfigPath = path.join(configDir, 'assistant-app-config.json'); | ||||||
|  | export const appDir = createDir(path.join(configDir, 'assistant-app/frontend')); | ||||||
|  | export const appPidPath = path.join(configDir, 'assistant-app.pid'); | ||||||
|  | export const LocalElectronAppUrl = 'https://assistant.app/user/tiptap/'; | ||||||
|  |  | ||||||
|  | type AssistantConfig = { | ||||||
|  |   pageApi?: string; // https://kevisual.silkyai.cn | ||||||
|  |   loadURL?: string; // https://assistant.app/user/tiptap/ | ||||||
|  |   proxy?: { user: string; key: string; path: string }[]; | ||||||
|  |   apiProxyList?: ProxyInfo[]; | ||||||
|  | }; | ||||||
|  | let assistantConfig: AssistantConfig; | ||||||
|  | export const getConfig = () => { | ||||||
|  |   try { | ||||||
|  |     if (!checkFileExists(configPath)) { | ||||||
|  |       fs.writeFileSync(configPath, JSON.stringify({ proxy: [] }, null, 2)); | ||||||
|  |       return { | ||||||
|  |         loadURL: LocalElectronAppUrl, | ||||||
|  |         pageApi: '', | ||||||
|  |         proxy: [], | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  |     assistantConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')); | ||||||
|  |     return assistantConfig; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error(error); | ||||||
|  |     return { | ||||||
|  |       loadURL: LocalElectronAppUrl, | ||||||
|  |       pageApi: '', | ||||||
|  |       proxy: [], | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | export const getCacheAssistantConfig = () => { | ||||||
|  |   if (assistantConfig) { | ||||||
|  |     return assistantConfig; | ||||||
|  |   } | ||||||
|  |   return getConfig(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const setConfig = (config?: AssistantConfig) => { | ||||||
|  |   if (!config) { | ||||||
|  |     return assistantConfig; | ||||||
|  |   } | ||||||
|  |   assistantConfig = config; | ||||||
|  |   fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); | ||||||
|  |   return assistantConfig; | ||||||
|  | }; | ||||||
|  | type AppConfig = { | ||||||
|  |   list: any[]; | ||||||
|  | }; | ||||||
|  | /** | ||||||
|  |  * 应用配置 | ||||||
|  |  * @returns | ||||||
|  |  */ | ||||||
|  | export const getAppConfig = (): AppConfig => { | ||||||
|  |   if (!checkFileExists(appConfigPath)) { | ||||||
|  |     return { | ||||||
|  |       list: [], | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |   return JSON.parse(fs.readFileSync(appConfigPath, 'utf8')); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const setAppConfig = (config: AppConfig) => { | ||||||
|  |   fs.writeFileSync(appConfigPath, JSON.stringify(config, null, 2)); | ||||||
|  |   return config; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const addAppConfig = (app: any) => { | ||||||
|  |   const config = getAppConfig(); | ||||||
|  |   const assistantConfig = getCacheAssistantConfig(); | ||||||
|  |   const _apps = config.list; | ||||||
|  |   const _proxy = assistantConfig.proxy || []; | ||||||
|  |   const { user, key } = app; | ||||||
|  |   const newProxyInfo = { | ||||||
|  |     user, | ||||||
|  |     key, | ||||||
|  |     path: `/${user}/${key}`, | ||||||
|  |   }; | ||||||
|  |   const _proxyIndex = _proxy.findIndex((_proxy: any) => _proxy.path === newProxyInfo.path); | ||||||
|  |   if (_proxyIndex !== -1) { | ||||||
|  |     _proxy[_proxyIndex] = newProxyInfo; | ||||||
|  |   } else { | ||||||
|  |     _proxy.push(newProxyInfo); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const _app = _apps.findIndex((_app: any) => _app.id === app.id); | ||||||
|  |   if (_app !== -1) { | ||||||
|  |     _apps[_app] = app; | ||||||
|  |   } else { | ||||||
|  |     _apps.push(app); | ||||||
|  |   } | ||||||
|  |   setAppConfig({ ...config, list: _apps }); | ||||||
|  |   setConfig({ ...assistantConfig, proxy: _proxy }); | ||||||
|  |   return config; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const getAppList = () => { | ||||||
|  |   const config = getAppConfig(); | ||||||
|  |   return config.list || []; | ||||||
|  | }; | ||||||
							
								
								
									
										20
									
								
								assistant-module/src/file/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								assistant-module/src/file/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | import fs from 'fs'; | ||||||
|  |  | ||||||
|  | export const checkFileExists = (filePath: string, checkIsFile = false) => { | ||||||
|  |   try { | ||||||
|  |     fs.accessSync(filePath); | ||||||
|  |     if (checkIsFile) { | ||||||
|  |       return fs.statSync(filePath).isFile(); | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  |   } catch (error) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const createDir = (dirPath: string) => { | ||||||
|  |   if (!checkFileExists(dirPath)) { | ||||||
|  |     fs.mkdirSync(dirPath, { recursive: true }); | ||||||
|  |   } | ||||||
|  |   return dirPath; | ||||||
|  | }; | ||||||
							
								
								
									
										2
									
								
								assistant-module/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								assistant-module/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | export * from './install/index.ts'; | ||||||
|  | export * from './config/index.ts'; | ||||||
							
								
								
									
										127
									
								
								assistant-module/src/install/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								assistant-module/src/install/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | import path from 'path'; | ||||||
|  | import fs from 'fs'; | ||||||
|  |  | ||||||
|  | type DownloadTask = { | ||||||
|  |   downloadPath: string; | ||||||
|  |   downloadUrl: string; | ||||||
|  |   user: string; | ||||||
|  |   key: string; | ||||||
|  |   version: string; | ||||||
|  | }; | ||||||
|  | export type Package = { | ||||||
|  |   id: string; | ||||||
|  |   name?: string; | ||||||
|  |   version?: string; | ||||||
|  |   description?: string; | ||||||
|  |   title?: string; | ||||||
|  |   user?: string; | ||||||
|  |   key?: string; | ||||||
|  |   [key: string]: any; | ||||||
|  | }; | ||||||
|  | type InstallAppOpts = { | ||||||
|  |   appDir?: string; | ||||||
|  |   kevisualUrl?: string; | ||||||
|  |   /** | ||||||
|  |    * 是否是客户端, 下载到 assistant-config的下面 | ||||||
|  |    */ | ||||||
|  | }; | ||||||
|  | export const installApp = async (app: Package, opts: InstallAppOpts = {}) => { | ||||||
|  |   // const _app = demoData; | ||||||
|  |   const { appDir = '', kevisualUrl = 'https://kevisual.cn' } = opts; | ||||||
|  |   const _app = app; | ||||||
|  |   try { | ||||||
|  |     let files = _app.data.files || []; | ||||||
|  |     const version = _app.version; | ||||||
|  |     const user = _app.user; | ||||||
|  |     const key = _app.key; | ||||||
|  |  | ||||||
|  |     const downFiles = files.map((file: any) => { | ||||||
|  |       const noVersionPath = file.path.replace(`/${version}`, ''); | ||||||
|  |       return { | ||||||
|  |         ...file, | ||||||
|  |         downloadPath: path.join(appDir, noVersionPath), | ||||||
|  |         downloadUrl: `${kevisualUrl}/${noVersionPath}`, | ||||||
|  |       }; | ||||||
|  |     }); | ||||||
|  |     const downloadTasks: DownloadTask[] = downFiles as any; | ||||||
|  |     for (const file of downloadTasks) { | ||||||
|  |       const downloadPath = file.downloadPath; | ||||||
|  |       const downloadUrl = file.downloadUrl; | ||||||
|  |       const dir = path.dirname(downloadPath); | ||||||
|  |       if (!fs.existsSync(dir)) { | ||||||
|  |         fs.mkdirSync(dir, { recursive: true }); | ||||||
|  |       } | ||||||
|  |       const res = await fetch(downloadUrl); | ||||||
|  |       const blob = await res.blob(); | ||||||
|  |       fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); | ||||||
|  |     } | ||||||
|  |     let indexHtml = files.find((file: any) => file.name === 'index.html'); | ||||||
|  |     if (!indexHtml) { | ||||||
|  |       files.push({ | ||||||
|  |         name: 'index.html', | ||||||
|  |         path: `${user}/${key}/index.html`, | ||||||
|  |       }); | ||||||
|  |       fs.writeFileSync(path.join(appDir, `${user}/${key}/index.html`), JSON.stringify(app, null, 2)); | ||||||
|  |     } | ||||||
|  |     _app.data.files = files; | ||||||
|  |     return { | ||||||
|  |       code: 200, | ||||||
|  |       data: _app, | ||||||
|  |       message: 'Install app success', | ||||||
|  |     }; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error(error); | ||||||
|  |     return { | ||||||
|  |       code: 500, | ||||||
|  |       message: 'Install app failed', | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | export const checkAppDir = (appDir: string) => { | ||||||
|  |   const files = fs.readdirSync(appDir); | ||||||
|  |   if (files.length === 0) { | ||||||
|  |     fs.rmSync(appDir, { recursive: true }); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | export const checkFileExists = (path: string) => { | ||||||
|  |   try { | ||||||
|  |     fs.accessSync(path); | ||||||
|  |     return true; | ||||||
|  |   } catch (error) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | type UninstallAppOpts = { | ||||||
|  |   appDir?: string; | ||||||
|  | }; | ||||||
|  | export const uninstallApp = async (app: Partial<Package>, opts: UninstallAppOpts = {}) => { | ||||||
|  |   const { appDir = '' } = opts; | ||||||
|  |   try { | ||||||
|  |     const { user, key } = app; | ||||||
|  |     const keyDir = path.join(appDir, user, key); | ||||||
|  |     const parentDir = path.join(appDir, user); | ||||||
|  |     if (!checkFileExists(appDir) || !checkFileExists(keyDir)) { | ||||||
|  |       return { | ||||||
|  |         code: 200, | ||||||
|  |         message: 'uninstall app success', | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |       // 删除appDir和文件 | ||||||
|  |       fs.rmSync(keyDir, { recursive: true }); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error(error); | ||||||
|  |     } | ||||||
|  |     checkAppDir(parentDir); | ||||||
|  |     return { | ||||||
|  |       code: 200, | ||||||
|  |       message: 'Uninstall app success', | ||||||
|  |     }; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error(error); | ||||||
|  |     return { | ||||||
|  |       code: 500, | ||||||
|  |       message: 'Uninstall app failed', | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
							
								
								
									
										70
									
								
								assistant-module/src/process/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								assistant-module/src/process/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | import { ChildProcess, fork } from 'child_process'; | ||||||
|  |  | ||||||
|  | export const runProcess = (appPath: string) => { | ||||||
|  |   const process = fork(appPath); | ||||||
|  |   process.on('exit', (code) => { | ||||||
|  |     console.log(`Process exited with code ${code}`); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   process.on('message', (message) => { | ||||||
|  |     console.log('Message from child:', message); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   // Example of sending a message to the child process | ||||||
|  |   // process.send({ hello: 'world' }); | ||||||
|  | }; | ||||||
|  | class BaseProcess { | ||||||
|  |   private process: ChildProcess; | ||||||
|  |   status: 'running' | 'stopped' | 'error' = 'stopped'; | ||||||
|  |   appPath: string; | ||||||
|  |   constructor(appPath: string) { | ||||||
|  |     this.appPath = appPath; | ||||||
|  |     // this.createProcess(appPath); | ||||||
|  |   } | ||||||
|  |   createProcess(appPath: string = this.appPath) { | ||||||
|  |     if (this.process) { | ||||||
|  |       this.process.kill(); | ||||||
|  |     } | ||||||
|  |     this.appPath = appPath; | ||||||
|  |     this.process = fork(appPath); | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |   kill(signal?: NodeJS.Signals | number) { | ||||||
|  |     if (this.process) { | ||||||
|  |       this.process.kill(signal); | ||||||
|  |     } | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |   public send(message: any) { | ||||||
|  |     this.process.send(message); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public on(event: string, callback: (message: any) => void) { | ||||||
|  |     this.process.on(event, callback); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public onExit(callback: (code: number) => void) { | ||||||
|  |     this.process.on('exit', callback); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public onError(callback: (error: Error) => void) { | ||||||
|  |     this.process.on('error', callback); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public onMessage(callback: (message: any) => void) { | ||||||
|  |     this.process.on('message', callback); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public onClose(callback: () => void) { | ||||||
|  |     this.process.on('close', callback); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public onDisconnect(callback: () => void) { | ||||||
|  |     this.process.on('disconnect', callback); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | export class AssistantProcess extends BaseProcess { | ||||||
|  |   constructor(appPath: string) { | ||||||
|  |     super(appPath); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										82
									
								
								assistant-module/src/proxy/api-proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								assistant-module/src/proxy/api-proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | import http from 'http'; | ||||||
|  | import https from 'https'; | ||||||
|  |  | ||||||
|  | import { ProxyInfo } from './proxy.ts'; | ||||||
|  | export const defaultApiProxy = [ | ||||||
|  |   { | ||||||
|  |     path: '/api/router', | ||||||
|  |     target: 'https://kevisual.xiongxiao.me', | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     path: '/v1', | ||||||
|  |     target: 'https://kevisual.xiongxiao.me', | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  | /** | ||||||
|  |  * 创建api代理 | ||||||
|  |  * @param api  | ||||||
|  |  * @param paths ['/api/router', '/v1' ] | ||||||
|  |  * @returns  | ||||||
|  |  */ | ||||||
|  | export const createApiProxy = (api: string, paths: string[] = ['/api/router', '/v1']) => { | ||||||
|  |   const pathList = paths.map((item) => { | ||||||
|  |     return { | ||||||
|  |       path: item, | ||||||
|  |       target: new URL(api).origin, | ||||||
|  |     }; | ||||||
|  |   }); | ||||||
|  |   return pathList; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const apiProxy = (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => { | ||||||
|  |   const _u = new URL(req.url, `${proxyApi.target}`); | ||||||
|  |   console.log('proxyApi', req.url, _u.href); | ||||||
|  |   // 设置代理请求的目标 URL 和请求头 | ||||||
|  |   let header: any = {}; | ||||||
|  |   if (req.headers?.['Authorization'] && !req.headers?.['authorization']) { | ||||||
|  |     header.authorization = req.headers['Authorization']; | ||||||
|  |   } | ||||||
|  |   // 提取req的headers中的非HOST的header | ||||||
|  |   const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host'); | ||||||
|  |   headers.forEach((item) => { | ||||||
|  |     if (item.toLowerCase() === 'origin') { | ||||||
|  |       header.origin = new URL(proxyApi.target).origin; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     if (item.toLowerCase() === 'referer') { | ||||||
|  |       header.referer = new URL(req.url, proxyApi.target).href; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     header[item] = req.headers[item]; | ||||||
|  |   }); | ||||||
|  |   const options = { | ||||||
|  |     host: _u.hostname, | ||||||
|  |     path: req.url, | ||||||
|  |     method: req.method, | ||||||
|  |     headers: { | ||||||
|  |       ...header, | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  |   console.log('options', JSON.stringify(options, null, 2)); | ||||||
|  |   if (_u.port) { | ||||||
|  |     // @ts-ignore | ||||||
|  |     options.port = _u.port; | ||||||
|  |   } | ||||||
|  |   const httpProxy = _u.protocol === 'https:' ? https : http; | ||||||
|  |   // 创建代理请求 | ||||||
|  |   const proxyReq = httpProxy.request(options, (proxyRes) => { | ||||||
|  |     // 将代理服务器的响应头和状态码返回给客户端 | ||||||
|  |     res.writeHead(proxyRes.statusCode, proxyRes.headers); | ||||||
|  |     // 将代理响应流写入客户端响应 | ||||||
|  |     proxyRes.pipe(res, { end: true }); | ||||||
|  |   }); | ||||||
|  |   // 处理代理请求的错误事件 | ||||||
|  |   proxyReq.on('error', (err) => { | ||||||
|  |     console.error(`Proxy request error: ${err.message}`); | ||||||
|  |     res.writeHead(500, { 'Content-Type': 'text/plain' }); | ||||||
|  |     res.write(`Proxy request error: ${err.message}`); | ||||||
|  |   }); | ||||||
|  |   // 处理 POST 请求的请求体(传递数据到目标服务器),end:true 表示当请求体结束时,关闭请求 | ||||||
|  |   req.pipe(proxyReq, { end: true }); | ||||||
|  |   return; | ||||||
|  | }; | ||||||
							
								
								
									
										47
									
								
								assistant-module/src/proxy/file-proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								assistant-module/src/proxy/file-proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | import http from 'http'; | ||||||
|  | import send from 'send'; | ||||||
|  | import fs from 'fs'; | ||||||
|  | import { fileIsExist } from '@kevisual/use-config'; | ||||||
|  | import path from 'path'; | ||||||
|  | import { ProxyInfo } from './proxy.ts'; | ||||||
|  |  | ||||||
|  | export const fileProxy = (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => { | ||||||
|  |   // url开头的文件 | ||||||
|  |   const url = new URL(req.url, 'http://localhost'); | ||||||
|  |   let pathname = url.pathname.slice(1); | ||||||
|  |   const { indexPath = '', target = '', rootPath = process.cwd() } = proxyApi; | ||||||
|  |   try { | ||||||
|  |     if (pathname.endsWith('/')) { | ||||||
|  |       pathname = pathname + 'index.html'; | ||||||
|  |     } | ||||||
|  |     // 检测文件是否存在,如果文件不存在,则返回404 | ||||||
|  |     let filePath = path.join(rootPath, target, pathname); | ||||||
|  |     let exist = fileIsExist(filePath); | ||||||
|  |     if (!exist) { | ||||||
|  |       filePath = path.join(rootPath, target, '/' + indexPath); | ||||||
|  |       exist = fileIsExist(filePath); | ||||||
|  |     } | ||||||
|  |     console.log('filePath', filePath, exist); | ||||||
|  |      | ||||||
|  |     if (!exist) { | ||||||
|  |       res.statusCode = 404; | ||||||
|  |       res.end('Not Found File'); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     const ext = path.extname(filePath); | ||||||
|  |     let maxAge = 24 * 60 * 60 * 1000; // 24小时 | ||||||
|  |     if (ext === '.html') { | ||||||
|  |       maxAge = 0; | ||||||
|  |     } | ||||||
|  |     let sendFilePath = filePath.replace(rootPath + '/', ''); | ||||||
|  |     const file = send(req, sendFilePath, { | ||||||
|  |       root: rootPath, | ||||||
|  |       maxAge, | ||||||
|  |     }); | ||||||
|  |     file.pipe(res); | ||||||
|  |   } catch (error) { | ||||||
|  |     res.statusCode = 404; | ||||||
|  |     res.end('Error:Not Found File'); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  | }; | ||||||
							
								
								
									
										5
									
								
								assistant-module/src/proxy/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								assistant-module/src/proxy/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | export * from './proxy.ts'; | ||||||
|  | export * from './file-proxy.ts'; | ||||||
|  | export { default as send } from 'send'; | ||||||
|  | export * from './api-proxy.ts'; | ||||||
|  | export * from './wx-proxy.ts'; | ||||||
							
								
								
									
										35
									
								
								assistant-module/src/proxy/proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								assistant-module/src/proxy/proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | export type ProxyInfo = { | ||||||
|  |   path?: string; | ||||||
|  |   target?: string; | ||||||
|  |   type?: 'static' | 'dynamic' | 'minio'; | ||||||
|  |   /** | ||||||
|  |    * 首要文件,比如index.html, 设置了首要文件,如果文件不存在,则访问首要文件 | ||||||
|  |    */ | ||||||
|  |   indexPath?: string; | ||||||
|  |   /** | ||||||
|  |    * 根路径, 默认是process.cwd() | ||||||
|  |    */ | ||||||
|  |   rootPath?: string; | ||||||
|  | }; | ||||||
|  | export type ApiList = { | ||||||
|  |   path: string; | ||||||
|  |   /** | ||||||
|  |    * url或者相对路径 | ||||||
|  |    */ | ||||||
|  |   target: string; | ||||||
|  |   /** | ||||||
|  |    * 类型 | ||||||
|  |    */ | ||||||
|  |   type?: 'static' | 'dynamic' | 'minio'; | ||||||
|  | }[]; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  | ||||||
|  | [ | ||||||
|  |   { | ||||||
|  |     path: '/api/v1/user', | ||||||
|  |     target: 'http://localhost:3000/api/v1/user', | ||||||
|  |     type: 'dynamic', | ||||||
|  |   }, | ||||||
|  | ] | ||||||
|  |  */ | ||||||
							
								
								
									
										48
									
								
								assistant-module/src/proxy/wx-proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								assistant-module/src/proxy/wx-proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | import { Server } from 'http'; | ||||||
|  | import WebSocket from 'ws'; | ||||||
|  | /** | ||||||
|  |  * websocket代理 | ||||||
|  |  * apiList: [{ path: '/api/router', target: 'https://kevisual.xiongxiao.me' }] | ||||||
|  |  * @param server | ||||||
|  |  * @param config | ||||||
|  |  */ | ||||||
|  | export const wsProxy = (server: Server, config: { apiList: any[] }) => { | ||||||
|  |   console.log('Upgrade initialization started'); | ||||||
|  |  | ||||||
|  |   server.on('upgrade', (req, socket, head) => { | ||||||
|  |     const proxyApiList = config?.apiList || []; | ||||||
|  |     const proxyApi = proxyApiList.find((item) => req.url.startsWith(item.path)); | ||||||
|  |  | ||||||
|  |     if (proxyApi) { | ||||||
|  |       const _u = new URL(req.url, `${proxyApi.target}`); | ||||||
|  |       const isHttps = _u.protocol === 'https:'; | ||||||
|  |       const wsProtocol = isHttps ? 'wss' : 'ws'; | ||||||
|  |       const wsUrl = `${wsProtocol}://${_u.hostname}${_u.pathname}`; | ||||||
|  |  | ||||||
|  |       const proxySocket = new WebSocket(wsUrl, { | ||||||
|  |         headers: req.headers, | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       proxySocket.on('open', () => { | ||||||
|  |         socket.on('data', (data) => { | ||||||
|  |           proxySocket.send(data); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         proxySocket.on('message', (message) => { | ||||||
|  |           socket.write(message); | ||||||
|  |         }); | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       proxySocket.on('error', (err) => { | ||||||
|  |         console.error(`WebSocket proxy error: ${err.message}`); | ||||||
|  |         socket.end(); | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       socket.on('error', () => { | ||||||
|  |         proxySocket.close(); | ||||||
|  |       }); | ||||||
|  |     } else { | ||||||
|  |       socket.end(); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | }; | ||||||
							
								
								
									
										33
									
								
								assistant-module/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								assistant-module/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     "module": "nodenext", | ||||||
|  |     "target": "esnext", | ||||||
|  |     "noImplicitAny": false, | ||||||
|  |     "outDir": "./dist", | ||||||
|  |     "sourceMap": false, | ||||||
|  |     "allowJs": true, | ||||||
|  |     "newLine": "LF", | ||||||
|  |     "baseUrl": "./", | ||||||
|  |     "typeRoots": [ | ||||||
|  |       "node_modules/@types", | ||||||
|  |       "node_modules/@kevisual/types" | ||||||
|  |     ], | ||||||
|  |     "declaration": true, | ||||||
|  |     "noEmit": false, | ||||||
|  |     "allowImportingTsExtensions": true, | ||||||
|  |     "emitDeclarationOnly": true, | ||||||
|  |     "moduleResolution": "NodeNext", | ||||||
|  |     "experimentalDecorators": true, | ||||||
|  |     "emitDecoratorMetadata": true, | ||||||
|  |     "esModuleInterop": true, | ||||||
|  |     "paths": { | ||||||
|  |       "@/*": [ | ||||||
|  |         "src/*" | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "include": [ | ||||||
|  |     "src/**/*.ts", | ||||||
|  |   ], | ||||||
|  |   "exclude": [], | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,19 +1,21 @@ | |||||||
| { | { | ||||||
|   "name": "demo-app", |   "name": "assistant-center", | ||||||
|   "version": "0.0.1", |   "version": "0.0.1", | ||||||
|   "description": "", |   "description": "", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|   "app": { |   "app": { | ||||||
|     "key": "demo-app", |     "key": "assistant-center", | ||||||
|     "entry": "dist/app.mjs", |     "entry": "dist/app.mjs", | ||||||
|     "type": "system-app", |     "type": "system-app", | ||||||
|     "files": [ |     "files": [ | ||||||
|       "dist" |       "dist", | ||||||
|  |       "pem" | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "watch": "rollup -c rollup.config.mjs -w", |     "watch": "rollup -c rollup.config.mjs -w", | ||||||
|     "dev": "cross-env NODE_ENV=development nodemon --delay 2.5 -e js,cjs,mjs --exec node dist/app.mjs", |     "dev": "cross-env NODE_ENV=development nodemon --delay 2.5 -e js,cjs,mjs --exec node dist/app.mjs", | ||||||
|  |     "build": "rollup -c rollup.config.mjs", | ||||||
|     "test": "tsx  test/**/*.ts", |     "test": "tsx  test/**/*.ts", | ||||||
|     "dev:watch": "cross-env NODE_ENV=development concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ", |     "dev:watch": "cross-env NODE_ENV=development concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ", | ||||||
|     "clean": "rm -rf dist", |     "clean": "rm -rf dist", | ||||||
| @@ -31,20 +33,22 @@ | |||||||
|     "src" |     "src" | ||||||
|   ], |   ], | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@kevisual/code-center-module": "0.0.11-alpha.1", |     "@kevisual/code-center-module": "0.0.13", | ||||||
|     "@kevisual/mark": "0.0.6", |     "@kevisual/mark": "0.0.7", | ||||||
|     "@kevisual/router": "0.0.8-alpha.3", |     "@kevisual/router": "0.0.9", | ||||||
|     "cookie": "^1.0.2", |     "cookie": "^1.0.2", | ||||||
|     "dayjs": "^1.11.13", |     "dayjs": "^1.11.13", | ||||||
|     "formidable": "^3.5.2", |     "formidable": "^3.5.2", | ||||||
|     "json5": "^2.2.3", |     "json5": "^2.2.3", | ||||||
|     "lodash-es": "^4.17.21" |     "lodash-es": "^4.17.21", | ||||||
|  |     "ws": "^8.18.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "@kevisual/assistant-module": "workspace:*", | ||||||
|     "@kevisual/types": "^0.0.6", |     "@kevisual/types": "^0.0.6", | ||||||
|     "@kevisual/use-config": "^1.0.9", |     "@kevisual/use-config": "^1.0.9", | ||||||
|     "@rollup/plugin-alias": "^5.1.1", |     "@rollup/plugin-alias": "^5.1.1", | ||||||
|     "@rollup/plugin-commonjs": "^28.0.2", |     "@rollup/plugin-commonjs": "^28.0.3", | ||||||
|     "@rollup/plugin-json": "^6.1.0", |     "@rollup/plugin-json": "^6.1.0", | ||||||
|     "@rollup/plugin-node-resolve": "^16.0.0", |     "@rollup/plugin-node-resolve": "^16.0.0", | ||||||
|     "@rollup/plugin-replace": "^6.0.2", |     "@rollup/plugin-replace": "^6.0.2", | ||||||
| @@ -52,7 +56,8 @@ | |||||||
|     "@types/crypto-js": "^4.2.2", |     "@types/crypto-js": "^4.2.2", | ||||||
|     "@types/formidable": "^3.4.5", |     "@types/formidable": "^3.4.5", | ||||||
|     "@types/lodash-es": "^4.17.12", |     "@types/lodash-es": "^4.17.12", | ||||||
|     "@types/node": "^22.13.8", |     "@types/node": "^22.13.9", | ||||||
|  |     "@types/ws": "^8.18.0", | ||||||
|     "concurrently": "^9.1.2", |     "concurrently": "^9.1.2", | ||||||
|     "cross-env": "^7.0.3", |     "cross-env": "^7.0.3", | ||||||
|     "nodemon": "^3.1.9", |     "nodemon": "^3.1.9", | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								pem/https-cert.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								pem/https-cert.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | -----BEGIN CERTIFICATE----- | ||||||
|  | MIICXTCCAcagAwIBAgIJHsP036vqWER/MA0GCSqGSIb3DQEBBQUAMF8xCjAIBgNV | ||||||
|  | BAMTASoxCzAJBgNVBAYTAkNOMREwDwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMI | ||||||
|  | SGFuZ3pob3UxETAPBgNVBAoTCEVudmlzaW9uMQswCQYDVQQLEwJJVDAeFw0yNTAz | ||||||
|  | MDcxNDIwMTJaFw0yNjAzMDcxNDIwMTJaMF8xCjAIBgNVBAMTASoxCzAJBgNVBAYT | ||||||
|  | AkNOMREwDwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ3pob3UxETAPBgNV | ||||||
|  | BAoTCEVudmlzaW9uMQswCQYDVQQLEwJJVDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw | ||||||
|  | gYkCgYEAquA2XnwduVSJHvnTW4r5yodz/joTPUi+r8kS/KJyR/NQ5xovtDY2gJoO | ||||||
|  | nJk8qekcLKuofskIIu4HFsCE7AYBkQGaYmc+0cCQCmEpwivesbeMB0ydz+6NwLQn | ||||||
|  | 32HVjtMtx3gUcywGdMntiQb/P9FIhtE132wOmW9PeSl0dx/nyrUCAwEAAaMhMB8w | ||||||
|  | HQYDVR0RBBYwFIIBKoIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBBQUAA4GB | ||||||
|  | AJsjIZgb6iE4OTXoEDiBPmHM+byWs20K2eCvi79V9/vns90IroBQfGirIsovv923 | ||||||
|  | SqjmdAFsZkRUbZvX99lBX0mmZK9KTE4K9YUm7bv+d8+fBPxAgNFSTRiSNBeNh0Lh | ||||||
|  | HdJUiI/tzIfI6RRg1pFDC1tOG083Cl/YElN879w3Iipi | ||||||
|  | -----END CERTIFICATE----- | ||||||
							
								
								
									
										15
									
								
								pem/https-key.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								pem/https-key.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | -----BEGIN RSA PRIVATE KEY----- | ||||||
|  | MIICXAIBAAKBgQCq4DZefB25VIke+dNbivnKh3P+OhM9SL6vyRL8onJH81DnGi+0 | ||||||
|  | NjaAmg6cmTyp6Rwsq6h+yQgi7gcWwITsBgGRAZpiZz7RwJAKYSnCK96xt4wHTJ3P | ||||||
|  | 7o3AtCffYdWO0y3HeBRzLAZ0ye2JBv8/0UiG0TXfbA6Zb095KXR3H+fKtQIDAQAB | ||||||
|  | AoGADDEbL/qjFEoXzoH8tpdf4zdu60CxhrneASTTmfrtNH0D1LlllfIYSWy0hi/Y | ||||||
|  | yDa9r+I/j2xAjF13XAQ4d66mBdjCRATLx/aL495o+e6NkIBEAgdP88hHm13F6gg+ | ||||||
|  | h8iMixs5mkwU41sghnCYeBqlziKPi8fsoTmhK0VETFUtDQECQQDT0kZ7OCEVNcz0 | ||||||
|  | LAUPO7ukeHAYnGYns+Q3F3kgonzHPGflClH5dsg0NS1HFQj6Ny2oyUupjNePOCJK | ||||||
|  | 88zNehIlAkEAzoO9zrE+AoTPleVpe7TAUlZB1YMa7W1C5owjyEkv4TjIe8mpwWM/ | ||||||
|  | 9vVe+SGUnc6DZy6xkk5zWmA2w18SexXJUQJBAJQbcyy1EmzCMYyJOwBrw8g8biTH | ||||||
|  | NqaMIgZjY05uTtEAa6S6kpbbdyEKDZ6mFqDd9A8QsNbco9yAY3oE/i6uLAECQHOt | ||||||
|  | a9aphZiXmEfYl3uJxejZFEtrAtxXxY+qlCiOhllcG0Drt0DyPVQyIZ7fZoX2tbhI | ||||||
|  | eYMAmrDXEBXj3VBA5eECQCLGpQKqo06QwP2qZ9mEaPB9KvVcABo97b9Lf7VUqcJx | ||||||
|  | tFWRSlpeICpDQZHqX92nwoD/2fGCH3br3o94k1oyApI= | ||||||
|  | -----END RSA PRIVATE KEY----- | ||||||
							
								
								
									
										240
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										240
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -9,14 +9,14 @@ importers: | |||||||
|   .: |   .: | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@kevisual/code-center-module': |       '@kevisual/code-center-module': | ||||||
|         specifier: 0.0.11-alpha.1 |         specifier: 0.0.13 | ||||||
|         version: 0.0.11-alpha.1(@kevisual/auth@1.0.5)(@kevisual/router@0.0.8-alpha.3)(@kevisual/use-config@1.0.9)(ioredis@5.5.0)(pg@8.13.3)(sequelize@6.37.5(pg@8.13.3)) |         version: 0.0.13(@kevisual/auth@1.0.5)(@kevisual/router@0.0.9)(@kevisual/use-config@1.0.9)(ioredis@5.5.0)(pg@8.13.3)(sequelize@6.37.5(pg@8.13.3)) | ||||||
|       '@kevisual/mark': |       '@kevisual/mark': | ||||||
|         specifier: 0.0.6 |         specifier: 0.0.7 | ||||||
|         version: 0.0.6(esbuild@0.25.0) |         version: 0.0.7(esbuild@0.25.0) | ||||||
|       '@kevisual/router': |       '@kevisual/router': | ||||||
|         specifier: 0.0.8-alpha.3 |         specifier: 0.0.9 | ||||||
|         version: 0.0.8-alpha.3 |         version: 0.0.9 | ||||||
|       cookie: |       cookie: | ||||||
|         specifier: ^1.0.2 |         specifier: ^1.0.2 | ||||||
|         version: 1.0.2 |         version: 1.0.2 | ||||||
| @@ -32,7 +32,13 @@ importers: | |||||||
|       lodash-es: |       lodash-es: | ||||||
|         specifier: ^4.17.21 |         specifier: ^4.17.21 | ||||||
|         version: 4.17.21 |         version: 4.17.21 | ||||||
|  |       ws: | ||||||
|  |         specifier: ^8.18.1 | ||||||
|  |         version: 8.18.1 | ||||||
|     devDependencies: |     devDependencies: | ||||||
|  |       '@kevisual/assistant-module': | ||||||
|  |         specifier: workspace:* | ||||||
|  |         version: link:assistant-module | ||||||
|       '@kevisual/types': |       '@kevisual/types': | ||||||
|         specifier: ^0.0.6 |         specifier: ^0.0.6 | ||||||
|         version: 0.0.6 |         version: 0.0.6 | ||||||
| @@ -43,8 +49,8 @@ importers: | |||||||
|         specifier: ^5.1.1 |         specifier: ^5.1.1 | ||||||
|         version: 5.1.1(rollup@4.34.9) |         version: 5.1.1(rollup@4.34.9) | ||||||
|       '@rollup/plugin-commonjs': |       '@rollup/plugin-commonjs': | ||||||
|         specifier: ^28.0.2 |         specifier: ^28.0.3 | ||||||
|         version: 28.0.2(rollup@4.34.9) |         version: 28.0.3(rollup@4.34.9) | ||||||
|       '@rollup/plugin-json': |       '@rollup/plugin-json': | ||||||
|         specifier: ^6.1.0 |         specifier: ^6.1.0 | ||||||
|         version: 6.1.0(rollup@4.34.9) |         version: 6.1.0(rollup@4.34.9) | ||||||
| @@ -67,8 +73,11 @@ importers: | |||||||
|         specifier: ^4.17.12 |         specifier: ^4.17.12 | ||||||
|         version: 4.17.12 |         version: 4.17.12 | ||||||
|       '@types/node': |       '@types/node': | ||||||
|         specifier: ^22.13.8 |         specifier: ^22.13.9 | ||||||
|         version: 22.13.8 |         version: 22.13.9 | ||||||
|  |       '@types/ws': | ||||||
|  |         specifier: ^8.18.0 | ||||||
|  |         version: 8.18.0 | ||||||
|       concurrently: |       concurrently: | ||||||
|         specifier: ^9.1.2 |         specifier: ^9.1.2 | ||||||
|         version: 9.1.2 |         version: 9.1.2 | ||||||
| @@ -106,6 +115,25 @@ importers: | |||||||
|         specifier: ^5.8.2 |         specifier: ^5.8.2 | ||||||
|         version: 5.8.2 |         version: 5.8.2 | ||||||
|  |  | ||||||
|  |   assistant-module: | ||||||
|  |     dependencies: | ||||||
|  |       send: | ||||||
|  |         specifier: ^1.1.0 | ||||||
|  |         version: 1.1.0 | ||||||
|  |       ws: | ||||||
|  |         specifier: ^8.18.1 | ||||||
|  |         version: 8.18.1 | ||||||
|  |     devDependencies: | ||||||
|  |       '@types/node': | ||||||
|  |         specifier: ^22.13.10 | ||||||
|  |         version: 22.13.10 | ||||||
|  |       '@types/send': | ||||||
|  |         specifier: ^0.17.4 | ||||||
|  |         version: 0.17.4 | ||||||
|  |       '@types/ws': | ||||||
|  |         specifier: ^8.18.0 | ||||||
|  |         version: 8.18.0 | ||||||
|  |  | ||||||
| packages: | packages: | ||||||
|  |  | ||||||
|   '@babel/code-frame@7.26.2': |   '@babel/code-frame@7.26.2': | ||||||
| @@ -279,8 +307,8 @@ packages: | |||||||
|   '@kevisual/auth@1.0.5': |   '@kevisual/auth@1.0.5': | ||||||
|     resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==} |     resolution: {integrity: sha512-GwsLj7unKXi7lmMiIIgdig4LwwLiDJnOy15HHZR5gMbyK6s5/uJiMY5RXPB2+onGzTNDqFo/hXjsD2wkerHPVg==} | ||||||
|  |  | ||||||
|   '@kevisual/code-center-module@0.0.11-alpha.1': |   '@kevisual/code-center-module@0.0.13': | ||||||
|     resolution: {integrity: sha512-0HPSZw4PmhejE7p4cBIe174/h434XE3dgrwHoRZLYZSZyJ/aaBfR+3RybdvDN5dnyusLkPdgRq+Qern53Lqp1A==} |     resolution: {integrity: sha512-A82sX8rdG2igyVLIF+0dagcUsGfk2b0JAga1BDDr9mrChrG1HbG1uYN7JJdjJbGE6zGYqGxRZwxKZmzB/+KMnw==} | ||||||
|     peerDependencies: |     peerDependencies: | ||||||
|       '@kevisual/auth': ^1.0.5 |       '@kevisual/auth': ^1.0.5 | ||||||
|       '@kevisual/router': ^0.0.7 |       '@kevisual/router': ^0.0.7 | ||||||
| @@ -292,8 +320,8 @@ packages: | |||||||
|   '@kevisual/load@0.0.4': |   '@kevisual/load@0.0.4': | ||||||
|     resolution: {integrity: sha512-TJBieKsEoEPfP4+tDyhNZdMX2LMAGiDZ/IrAXPFWB4jeFP0Ywm1W5xDV52LhhHq4nwTmuhyTVmPxJYiEVYTHtA==} |     resolution: {integrity: sha512-TJBieKsEoEPfP4+tDyhNZdMX2LMAGiDZ/IrAXPFWB4jeFP0Ywm1W5xDV52LhhHq4nwTmuhyTVmPxJYiEVYTHtA==} | ||||||
|  |  | ||||||
|   '@kevisual/mark@0.0.6': |   '@kevisual/mark@0.0.7': | ||||||
|     resolution: {integrity: sha512-QhJXeJbeQIbouitqE3s67G92tkx44XoC4dDZUXCd28xGJyeCegkkQ6n4uxKPLBCh3XhDtek1e2EZjhK97wyZJA==} |     resolution: {integrity: sha512-PiEEy4yvWEpixw76PzgrIWeNelzm+FrhtzFmqJU92o5GkgawaFwighcvIxqcVZRKeEFF4uvlTjFrGeQvXw6F4A==} | ||||||
|  |  | ||||||
|   '@kevisual/rollup-tools@0.0.1': |   '@kevisual/rollup-tools@0.0.1': | ||||||
|     resolution: {integrity: sha512-TdCN+IU0fyHudiiqYvobXQ8r5MltfM/cKmSS59iopyL8YYwXwcipOS4S24NWA79g7uwJfSUNk5lg3yVhom79fQ==} |     resolution: {integrity: sha512-TdCN+IU0fyHudiiqYvobXQ8r5MltfM/cKmSS59iopyL8YYwXwcipOS4S24NWA79g7uwJfSUNk5lg3yVhom79fQ==} | ||||||
| @@ -302,8 +330,8 @@ packages: | |||||||
|   '@kevisual/router@0.0.7': |   '@kevisual/router@0.0.7': | ||||||
|     resolution: {integrity: sha512-4n1Tp4YLoraJv7jtfy7jbuLGyAj0B2QkTlnlEDHCUTlEUOvOkjtf7DHAe2SL92fTgXhSbod0I/0vUcDF85oj/w==} |     resolution: {integrity: sha512-4n1Tp4YLoraJv7jtfy7jbuLGyAj0B2QkTlnlEDHCUTlEUOvOkjtf7DHAe2SL92fTgXhSbod0I/0vUcDF85oj/w==} | ||||||
|  |  | ||||||
|   '@kevisual/router@0.0.8-alpha.3': |   '@kevisual/router@0.0.9': | ||||||
|     resolution: {integrity: sha512-iWFatFe0ggBTpSmCqtRIVbMq8YnekM2beIciWmoE9kIfadosdyKW/vWoK5wfTUu4nB4GORCiDO3YrAYnoCaQug==} |     resolution: {integrity: sha512-qPyC2GVJ7iOIdJCCKNDsWMAKOQeSJW9HBpL5ZWKHTbi+t4jJBGTzIlXmjKeMHRd0lr/Qq1imQvlkSh4hlrbodA==} | ||||||
|  |  | ||||||
|   '@kevisual/types@0.0.6': |   '@kevisual/types@0.0.6': | ||||||
|     resolution: {integrity: sha512-7yxe1QmuC5g7lI/1Hm+zXly8if0z+ZqGM1SVOVv2VNRwRAVYBJDc365zWCCfRwE+5YaB2daWTe5zBOU4EkltkQ==} |     resolution: {integrity: sha512-7yxe1QmuC5g7lI/1Hm+zXly8if0z+ZqGM1SVOVv2VNRwRAVYBJDc365zWCCfRwE+5YaB2daWTe5zBOU4EkltkQ==} | ||||||
| @@ -354,8 +382,8 @@ packages: | |||||||
|       rollup: |       rollup: | ||||||
|         optional: true |         optional: true | ||||||
|  |  | ||||||
|   '@rollup/plugin-commonjs@28.0.2': |   '@rollup/plugin-commonjs@28.0.3': | ||||||
|     resolution: {integrity: sha512-BEFI2EDqzl+vA1rl97IDRZ61AIwGH093d9nz8+dThxJNH8oSoB7MjWvPCX3dkaK1/RCJ/1v/R1XB15FuSs0fQw==} |     resolution: {integrity: sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==} | ||||||
|     engines: {node: '>=16.0.0 || 14 >= 14.17'} |     engines: {node: '>=16.0.0 || 14 >= 14.17'} | ||||||
|     peerDependencies: |     peerDependencies: | ||||||
|       rollup: ^2.68.0||^3.0.0||^4.0.0 |       rollup: ^2.68.0||^3.0.0||^4.0.0 | ||||||
| @@ -549,6 +577,9 @@ packages: | |||||||
|   '@types/lodash@4.17.15': |   '@types/lodash@4.17.15': | ||||||
|     resolution: {integrity: sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==} |     resolution: {integrity: sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==} | ||||||
|  |  | ||||||
|  |   '@types/mime@1.3.5': | ||||||
|  |     resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} | ||||||
|  |  | ||||||
|   '@types/minimatch@5.1.2': |   '@types/minimatch@5.1.2': | ||||||
|     resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} |     resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} | ||||||
|  |  | ||||||
| @@ -558,15 +589,24 @@ packages: | |||||||
|   '@types/node-forge@1.3.11': |   '@types/node-forge@1.3.11': | ||||||
|     resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} |     resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} | ||||||
|  |  | ||||||
|   '@types/node@22.13.8': |   '@types/node@22.13.10': | ||||||
|     resolution: {integrity: sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==} |     resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} | ||||||
|  |  | ||||||
|  |   '@types/node@22.13.9': | ||||||
|  |     resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==} | ||||||
|  |  | ||||||
|   '@types/resolve@1.20.2': |   '@types/resolve@1.20.2': | ||||||
|     resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} |     resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} | ||||||
|  |  | ||||||
|  |   '@types/send@0.17.4': | ||||||
|  |     resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} | ||||||
|  |  | ||||||
|   '@types/validator@13.12.2': |   '@types/validator@13.12.2': | ||||||
|     resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} |     resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} | ||||||
|  |  | ||||||
|  |   '@types/ws@8.18.0': | ||||||
|  |     resolution: {integrity: sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==} | ||||||
|  |  | ||||||
|   accepts@1.3.8: |   accepts@1.3.8: | ||||||
|     resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} |     resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} | ||||||
|     engines: {node: '>= 0.6'} |     engines: {node: '>= 0.6'} | ||||||
| @@ -854,6 +894,14 @@ packages: | |||||||
|     resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} |     resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} | ||||||
|     engines: {node: '>=0.10'} |     engines: {node: '>=0.10'} | ||||||
|  |  | ||||||
|  |   depd@2.0.0: | ||||||
|  |     resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} | ||||||
|  |     engines: {node: '>= 0.8'} | ||||||
|  |  | ||||||
|  |   destroy@1.2.0: | ||||||
|  |     resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} | ||||||
|  |     engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} | ||||||
|  |  | ||||||
|   dezalgo@1.0.4: |   dezalgo@1.0.4: | ||||||
|     resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} |     resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} | ||||||
|  |  | ||||||
| @@ -875,12 +923,19 @@ packages: | |||||||
|   eastasianwidth@0.2.0: |   eastasianwidth@0.2.0: | ||||||
|     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} |     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} | ||||||
|  |  | ||||||
|  |   ee-first@1.1.1: | ||||||
|  |     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} | ||||||
|  |  | ||||||
|   emoji-regex@8.0.0: |   emoji-regex@8.0.0: | ||||||
|     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} |     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} | ||||||
|  |  | ||||||
|   emoji-regex@9.2.2: |   emoji-regex@9.2.2: | ||||||
|     resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} |     resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} | ||||||
|  |  | ||||||
|  |   encodeurl@2.0.0: | ||||||
|  |     resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} | ||||||
|  |     engines: {node: '>= 0.8'} | ||||||
|  |  | ||||||
|   engine.io-parser@5.2.3: |   engine.io-parser@5.2.3: | ||||||
|     resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} |     resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} | ||||||
|     engines: {node: '>=10.0.0'} |     engines: {node: '>=10.0.0'} | ||||||
| @@ -932,6 +987,9 @@ packages: | |||||||
|     resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} |     resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} | ||||||
|     engines: {node: '>=6'} |     engines: {node: '>=6'} | ||||||
|  |  | ||||||
|  |   escape-html@1.0.3: | ||||||
|  |     resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} | ||||||
|  |  | ||||||
|   escape-string-regexp@4.0.0: |   escape-string-regexp@4.0.0: | ||||||
|     resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} |     resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} | ||||||
|     engines: {node: '>=10'} |     engines: {node: '>=10'} | ||||||
| @@ -960,6 +1018,10 @@ packages: | |||||||
|     resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} |     resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} | ||||||
|     engines: {node: '>=0.10.0'} |     engines: {node: '>=0.10.0'} | ||||||
|  |  | ||||||
|  |   etag@1.8.1: | ||||||
|  |     resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} | ||||||
|  |     engines: {node: '>= 0.6'} | ||||||
|  |  | ||||||
|   eventemitter2@0.4.14: |   eventemitter2@0.4.14: | ||||||
|     resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==} |     resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==} | ||||||
|  |  | ||||||
| @@ -1020,6 +1082,10 @@ packages: | |||||||
|   formidable@3.5.2: |   formidable@3.5.2: | ||||||
|     resolution: {integrity: sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==} |     resolution: {integrity: sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==} | ||||||
|  |  | ||||||
|  |   fresh@0.5.2: | ||||||
|  |     resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} | ||||||
|  |     engines: {node: '>= 0.6'} | ||||||
|  |  | ||||||
|   fs-extra@8.1.0: |   fs-extra@8.1.0: | ||||||
|     resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} |     resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} | ||||||
|     engines: {node: '>=6 <7 || >=8'} |     engines: {node: '>=6 <7 || >=8'} | ||||||
| @@ -1147,6 +1213,10 @@ packages: | |||||||
|     resolution: {integrity: sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==} |     resolution: {integrity: sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|  |  | ||||||
|  |   http-errors@2.0.0: | ||||||
|  |     resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} | ||||||
|  |     engines: {node: '>= 0.8'} | ||||||
|  |  | ||||||
|   http-proxy-agent@7.0.2: |   http-proxy-agent@7.0.2: | ||||||
|     resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} |     resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} | ||||||
|     engines: {node: '>= 14'} |     engines: {node: '>= 14'} | ||||||
| @@ -1491,6 +1561,10 @@ packages: | |||||||
|     resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} |     resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} | ||||||
|     engines: {node: '>= 0.4'} |     engines: {node: '>= 0.4'} | ||||||
|  |  | ||||||
|  |   on-finished@2.4.1: | ||||||
|  |     resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} | ||||||
|  |     engines: {node: '>= 0.8'} | ||||||
|  |  | ||||||
|   once@1.4.0: |   once@1.4.0: | ||||||
|     resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} |     resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} | ||||||
|  |  | ||||||
| @@ -1650,6 +1724,10 @@ packages: | |||||||
|   queue-microtask@1.2.3: |   queue-microtask@1.2.3: | ||||||
|     resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} |     resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} | ||||||
|  |  | ||||||
|  |   range-parser@1.2.1: | ||||||
|  |     resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} | ||||||
|  |     engines: {node: '>= 0.6'} | ||||||
|  |  | ||||||
|   read@1.0.7: |   read@1.0.7: | ||||||
|     resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} |     resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} | ||||||
|     engines: {node: '>=0.8'} |     engines: {node: '>=0.8'} | ||||||
| @@ -1780,6 +1858,10 @@ packages: | |||||||
|     engines: {node: '>=10'} |     engines: {node: '>=10'} | ||||||
|     hasBin: true |     hasBin: true | ||||||
|  |  | ||||||
|  |   send@1.1.0: | ||||||
|  |     resolution: {integrity: sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==} | ||||||
|  |     engines: {node: '>= 18'} | ||||||
|  |  | ||||||
|   sequelize-pool@7.1.0: |   sequelize-pool@7.1.0: | ||||||
|     resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==} |     resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==} | ||||||
|     engines: {node: '>= 10.0.0'} |     engines: {node: '>= 10.0.0'} | ||||||
| @@ -1829,6 +1911,9 @@ packages: | |||||||
|     resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} |     resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} | ||||||
|     engines: {node: '>= 0.4'} |     engines: {node: '>= 0.4'} | ||||||
|  |  | ||||||
|  |   setprototypeof@1.2.0: | ||||||
|  |     resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} | ||||||
|  |  | ||||||
|   shebang-command@2.0.0: |   shebang-command@2.0.0: | ||||||
|     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} |     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
| @@ -1922,6 +2007,10 @@ packages: | |||||||
|   standard-as-callback@2.1.0: |   standard-as-callback@2.1.0: | ||||||
|     resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} |     resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} | ||||||
|  |  | ||||||
|  |   statuses@2.0.1: | ||||||
|  |     resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} | ||||||
|  |     engines: {node: '>= 0.8'} | ||||||
|  |  | ||||||
|   stop-iteration-iterator@1.1.0: |   stop-iteration-iterator@1.1.0: | ||||||
|     resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} |     resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} | ||||||
|     engines: {node: '>= 0.4'} |     engines: {node: '>= 0.4'} | ||||||
| @@ -1984,6 +2073,10 @@ packages: | |||||||
|     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} |     resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} | ||||||
|     engines: {node: '>=8.0'} |     engines: {node: '>=8.0'} | ||||||
|  |  | ||||||
|  |   toidentifier@1.0.1: | ||||||
|  |     resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} | ||||||
|  |     engines: {node: '>=0.6'} | ||||||
|  |  | ||||||
|   toposort-class@1.0.1: |   toposort-class@1.0.1: | ||||||
|     resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} |     resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} | ||||||
|  |  | ||||||
| @@ -2127,8 +2220,8 @@ packages: | |||||||
|       utf-8-validate: |       utf-8-validate: | ||||||
|         optional: true |         optional: true | ||||||
|  |  | ||||||
|   ws@8.18.0: |   ws@8.18.1: | ||||||
|     resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} |     resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} | ||||||
|     engines: {node: '>=10.0.0'} |     engines: {node: '>=10.0.0'} | ||||||
|     peerDependencies: |     peerDependencies: | ||||||
|       bufferutil: ^4.0.1 |       bufferutil: ^4.0.1 | ||||||
| @@ -2263,10 +2356,10 @@ snapshots: | |||||||
|  |  | ||||||
|   '@kevisual/auth@1.0.5': {} |   '@kevisual/auth@1.0.5': {} | ||||||
|  |  | ||||||
|   '@kevisual/code-center-module@0.0.11-alpha.1(@kevisual/auth@1.0.5)(@kevisual/router@0.0.8-alpha.3)(@kevisual/use-config@1.0.9)(ioredis@5.5.0)(pg@8.13.3)(sequelize@6.37.5(pg@8.13.3))': |   '@kevisual/code-center-module@0.0.13(@kevisual/auth@1.0.5)(@kevisual/router@0.0.9)(@kevisual/use-config@1.0.9)(ioredis@5.5.0)(pg@8.13.3)(sequelize@6.37.5(pg@8.13.3))': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@kevisual/auth': 1.0.5 |       '@kevisual/auth': 1.0.5 | ||||||
|       '@kevisual/router': 0.0.8-alpha.3 |       '@kevisual/router': 0.0.9 | ||||||
|       '@kevisual/use-config': 1.0.9 |       '@kevisual/use-config': 1.0.9 | ||||||
|       ioredis: 5.5.0 |       ioredis: 5.5.0 | ||||||
|       nanoid: 5.1.2 |       nanoid: 5.1.2 | ||||||
| @@ -2283,13 +2376,14 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       eventemitter3: 5.0.1 |       eventemitter3: 5.0.1 | ||||||
|  |  | ||||||
|   '@kevisual/mark@0.0.6(esbuild@0.25.0)': |   '@kevisual/mark@0.0.7(esbuild@0.25.0)': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@kevisual/auth': 1.0.5 |       '@kevisual/auth': 1.0.5 | ||||||
|       '@kevisual/rollup-tools': 0.0.1(esbuild@0.25.0) |       '@kevisual/rollup-tools': 0.0.1(esbuild@0.25.0) | ||||||
|       '@kevisual/router': 0.0.7 |       '@kevisual/router': 0.0.7 | ||||||
|       '@kevisual/use-config': 1.0.9 |       '@kevisual/use-config': 1.0.9 | ||||||
|       cookie: 1.0.2 |       cookie: 1.0.2 | ||||||
|  |       nanoid: 5.1.2 | ||||||
|       pg: 8.13.3 |       pg: 8.13.3 | ||||||
|       sequelize: 6.37.5(pg@8.13.3) |       sequelize: 6.37.5(pg@8.13.3) | ||||||
|     transitivePeerDependencies: |     transitivePeerDependencies: | ||||||
| @@ -2310,12 +2404,12 @@ snapshots: | |||||||
|   '@kevisual/rollup-tools@0.0.1(esbuild@0.25.0)': |   '@kevisual/rollup-tools@0.0.1(esbuild@0.25.0)': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@rollup/plugin-alias': 5.1.1(rollup@4.34.9) |       '@rollup/plugin-alias': 5.1.1(rollup@4.34.9) | ||||||
|       '@rollup/plugin-commonjs': 28.0.2(rollup@4.34.9) |       '@rollup/plugin-commonjs': 28.0.3(rollup@4.34.9) | ||||||
|       '@rollup/plugin-json': 6.1.0(rollup@4.34.9) |       '@rollup/plugin-json': 6.1.0(rollup@4.34.9) | ||||||
|       '@rollup/plugin-node-resolve': 15.3.1(rollup@4.34.9) |       '@rollup/plugin-node-resolve': 15.3.1(rollup@4.34.9) | ||||||
|       '@rollup/plugin-replace': 6.0.2(rollup@4.34.9) |       '@rollup/plugin-replace': 6.0.2(rollup@4.34.9) | ||||||
|       '@rollup/plugin-typescript': 12.1.2(rollup@4.34.9)(tslib@2.8.1)(typescript@5.8.2) |       '@rollup/plugin-typescript': 12.1.2(rollup@4.34.9)(tslib@2.8.1)(typescript@5.8.2) | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|       chalk: 5.4.1 |       chalk: 5.4.1 | ||||||
|       commander: 12.1.0 |       commander: 12.1.0 | ||||||
|       glob: 11.0.1 |       glob: 11.0.1 | ||||||
| @@ -2334,16 +2428,16 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       path-to-regexp: 8.2.0 |       path-to-regexp: 8.2.0 | ||||||
|       selfsigned: 2.4.1 |       selfsigned: 2.4.1 | ||||||
|       ws: 8.18.0 |       ws: 8.18.1 | ||||||
|     transitivePeerDependencies: |     transitivePeerDependencies: | ||||||
|       - bufferutil |       - bufferutil | ||||||
|       - utf-8-validate |       - utf-8-validate | ||||||
|  |  | ||||||
|   '@kevisual/router@0.0.8-alpha.3': |   '@kevisual/router@0.0.9': | ||||||
|     dependencies: |     dependencies: | ||||||
|       path-to-regexp: 8.2.0 |       path-to-regexp: 8.2.0 | ||||||
|       selfsigned: 2.4.1 |       selfsigned: 2.4.1 | ||||||
|       ws: 8.18.0 |       ws: 8.18.1 | ||||||
|     transitivePeerDependencies: |     transitivePeerDependencies: | ||||||
|       - bufferutil |       - bufferutil | ||||||
|       - utf-8-validate |       - utf-8-validate | ||||||
| @@ -2430,7 +2524,7 @@ snapshots: | |||||||
|     optionalDependencies: |     optionalDependencies: | ||||||
|       rollup: 4.34.9 |       rollup: 4.34.9 | ||||||
|  |  | ||||||
|   '@rollup/plugin-commonjs@28.0.2(rollup@4.34.9)': |   '@rollup/plugin-commonjs@28.0.3(rollup@4.34.9)': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@rollup/pluginutils': 5.1.4(rollup@4.34.9) |       '@rollup/pluginutils': 5.1.4(rollup@4.34.9) | ||||||
|       commondir: 1.0.1 |       commondir: 1.0.1 | ||||||
| @@ -2555,7 +2649,7 @@ snapshots: | |||||||
|  |  | ||||||
|   '@types/cors@2.8.17': |   '@types/cors@2.8.17': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   '@types/crypto-js@4.2.2': {} |   '@types/crypto-js@4.2.2': {} | ||||||
|  |  | ||||||
| @@ -2567,16 +2661,16 @@ snapshots: | |||||||
|  |  | ||||||
|   '@types/formidable@3.4.5': |   '@types/formidable@3.4.5': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   '@types/fs-extra@8.1.5': |   '@types/fs-extra@8.1.5': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   '@types/glob@7.2.0': |   '@types/glob@7.2.0': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/minimatch': 5.1.2 |       '@types/minimatch': 5.1.2 | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   '@types/lodash-es@4.17.12': |   '@types/lodash-es@4.17.12': | ||||||
|     dependencies: |     dependencies: | ||||||
| @@ -2584,22 +2678,37 @@ snapshots: | |||||||
|  |  | ||||||
|   '@types/lodash@4.17.15': {} |   '@types/lodash@4.17.15': {} | ||||||
|  |  | ||||||
|  |   '@types/mime@1.3.5': {} | ||||||
|  |  | ||||||
|   '@types/minimatch@5.1.2': {} |   '@types/minimatch@5.1.2': {} | ||||||
|  |  | ||||||
|   '@types/ms@2.1.0': {} |   '@types/ms@2.1.0': {} | ||||||
|  |  | ||||||
|   '@types/node-forge@1.3.11': |   '@types/node-forge@1.3.11': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   '@types/node@22.13.8': |   '@types/node@22.13.10': | ||||||
|  |     dependencies: | ||||||
|  |       undici-types: 6.20.0 | ||||||
|  |  | ||||||
|  |   '@types/node@22.13.9': | ||||||
|     dependencies: |     dependencies: | ||||||
|       undici-types: 6.20.0 |       undici-types: 6.20.0 | ||||||
|  |  | ||||||
|   '@types/resolve@1.20.2': {} |   '@types/resolve@1.20.2': {} | ||||||
|  |  | ||||||
|  |   '@types/send@0.17.4': | ||||||
|  |     dependencies: | ||||||
|  |       '@types/mime': 1.3.5 | ||||||
|  |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   '@types/validator@13.12.2': {} |   '@types/validator@13.12.2': {} | ||||||
|  |  | ||||||
|  |   '@types/ws@8.18.0': | ||||||
|  |     dependencies: | ||||||
|  |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   accepts@1.3.8: |   accepts@1.3.8: | ||||||
|     dependencies: |     dependencies: | ||||||
|       mime-types: 2.1.35 |       mime-types: 2.1.35 | ||||||
| @@ -2889,6 +2998,10 @@ snapshots: | |||||||
|  |  | ||||||
|   denque@2.1.0: {} |   denque@2.1.0: {} | ||||||
|  |  | ||||||
|  |   depd@2.0.0: {} | ||||||
|  |  | ||||||
|  |   destroy@1.2.0: {} | ||||||
|  |  | ||||||
|   dezalgo@1.0.4: |   dezalgo@1.0.4: | ||||||
|     dependencies: |     dependencies: | ||||||
|       asap: 2.0.6 |       asap: 2.0.6 | ||||||
| @@ -2912,16 +3025,20 @@ snapshots: | |||||||
|  |  | ||||||
|   eastasianwidth@0.2.0: {} |   eastasianwidth@0.2.0: {} | ||||||
|  |  | ||||||
|  |   ee-first@1.1.1: {} | ||||||
|  |  | ||||||
|   emoji-regex@8.0.0: {} |   emoji-regex@8.0.0: {} | ||||||
|  |  | ||||||
|   emoji-regex@9.2.2: {} |   emoji-regex@9.2.2: {} | ||||||
|  |  | ||||||
|  |   encodeurl@2.0.0: {} | ||||||
|  |  | ||||||
|   engine.io-parser@5.2.3: {} |   engine.io-parser@5.2.3: {} | ||||||
|  |  | ||||||
|   engine.io@6.6.4: |   engine.io@6.6.4: | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/cors': 2.8.17 |       '@types/cors': 2.8.17 | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|       accepts: 1.3.8 |       accepts: 1.3.8 | ||||||
|       base64id: 2.0.0 |       base64id: 2.0.0 | ||||||
|       cookie: 0.7.2 |       cookie: 0.7.2 | ||||||
| @@ -3057,6 +3174,8 @@ snapshots: | |||||||
|  |  | ||||||
|   escalade@3.2.0: {} |   escalade@3.2.0: {} | ||||||
|  |  | ||||||
|  |   escape-html@1.0.3: {} | ||||||
|  |  | ||||||
|   escape-string-regexp@4.0.0: {} |   escape-string-regexp@4.0.0: {} | ||||||
|  |  | ||||||
|   escodegen@2.1.0: |   escodegen@2.1.0: | ||||||
| @@ -3077,6 +3196,8 @@ snapshots: | |||||||
|  |  | ||||||
|   esutils@2.0.3: {} |   esutils@2.0.3: {} | ||||||
|  |  | ||||||
|  |   etag@1.8.1: {} | ||||||
|  |  | ||||||
|   eventemitter2@0.4.14: {} |   eventemitter2@0.4.14: {} | ||||||
|  |  | ||||||
|   eventemitter2@5.0.1: {} |   eventemitter2@5.0.1: {} | ||||||
| @@ -3134,6 +3255,8 @@ snapshots: | |||||||
|       hexoid: 2.0.0 |       hexoid: 2.0.0 | ||||||
|       once: 1.4.0 |       once: 1.4.0 | ||||||
|  |  | ||||||
|  |   fresh@0.5.2: {} | ||||||
|  |  | ||||||
|   fs-extra@8.1.0: |   fs-extra@8.1.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       graceful-fs: 4.2.11 |       graceful-fs: 4.2.11 | ||||||
| @@ -3278,6 +3401,14 @@ snapshots: | |||||||
|  |  | ||||||
|   hexoid@2.0.0: {} |   hexoid@2.0.0: {} | ||||||
|  |  | ||||||
|  |   http-errors@2.0.0: | ||||||
|  |     dependencies: | ||||||
|  |       depd: 2.0.0 | ||||||
|  |       inherits: 2.0.4 | ||||||
|  |       setprototypeof: 1.2.0 | ||||||
|  |       statuses: 2.0.1 | ||||||
|  |       toidentifier: 1.0.1 | ||||||
|  |  | ||||||
|   http-proxy-agent@7.0.2: |   http-proxy-agent@7.0.2: | ||||||
|     dependencies: |     dependencies: | ||||||
|       agent-base: 7.1.3 |       agent-base: 7.1.3 | ||||||
| @@ -3626,6 +3757,10 @@ snapshots: | |||||||
|       has-symbols: 1.1.0 |       has-symbols: 1.1.0 | ||||||
|       object-keys: 1.1.1 |       object-keys: 1.1.1 | ||||||
|  |  | ||||||
|  |   on-finished@2.4.1: | ||||||
|  |     dependencies: | ||||||
|  |       ee-first: 1.1.1 | ||||||
|  |  | ||||||
|   once@1.4.0: |   once@1.4.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       wrappy: 1.0.2 |       wrappy: 1.0.2 | ||||||
| @@ -3834,6 +3969,8 @@ snapshots: | |||||||
|  |  | ||||||
|   queue-microtask@1.2.3: {} |   queue-microtask@1.2.3: {} | ||||||
|  |  | ||||||
|  |   range-parser@1.2.1: {} | ||||||
|  |  | ||||||
|   read@1.0.7: |   read@1.0.7: | ||||||
|     dependencies: |     dependencies: | ||||||
|       mute-stream: 0.0.8 |       mute-stream: 0.0.8 | ||||||
| @@ -4009,6 +4146,23 @@ snapshots: | |||||||
|  |  | ||||||
|   semver@7.7.1: {} |   semver@7.7.1: {} | ||||||
|  |  | ||||||
|  |   send@1.1.0: | ||||||
|  |     dependencies: | ||||||
|  |       debug: 4.4.0(supports-color@5.5.0) | ||||||
|  |       destroy: 1.2.0 | ||||||
|  |       encodeurl: 2.0.0 | ||||||
|  |       escape-html: 1.0.3 | ||||||
|  |       etag: 1.8.1 | ||||||
|  |       fresh: 0.5.2 | ||||||
|  |       http-errors: 2.0.0 | ||||||
|  |       mime-types: 2.1.35 | ||||||
|  |       ms: 2.1.3 | ||||||
|  |       on-finished: 2.4.1 | ||||||
|  |       range-parser: 1.2.1 | ||||||
|  |       statuses: 2.0.1 | ||||||
|  |     transitivePeerDependencies: | ||||||
|  |       - supports-color | ||||||
|  |  | ||||||
|   sequelize-pool@7.1.0: {} |   sequelize-pool@7.1.0: {} | ||||||
|  |  | ||||||
|   sequelize@6.37.5(pg@8.13.3): |   sequelize@6.37.5(pg@8.13.3): | ||||||
| @@ -4056,6 +4210,8 @@ snapshots: | |||||||
|       es-errors: 1.3.0 |       es-errors: 1.3.0 | ||||||
|       es-object-atoms: 1.1.1 |       es-object-atoms: 1.1.1 | ||||||
|  |  | ||||||
|  |   setprototypeof@1.2.0: {} | ||||||
|  |  | ||||||
|   shebang-command@2.0.0: |   shebang-command@2.0.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       shebang-regex: 3.0.0 |       shebang-regex: 3.0.0 | ||||||
| @@ -4166,6 +4322,8 @@ snapshots: | |||||||
|  |  | ||||||
|   standard-as-callback@2.1.0: {} |   standard-as-callback@2.1.0: {} | ||||||
|  |  | ||||||
|  |   statuses@2.0.1: {} | ||||||
|  |  | ||||||
|   stop-iteration-iterator@1.1.0: |   stop-iteration-iterator@1.1.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       es-errors: 1.3.0 |       es-errors: 1.3.0 | ||||||
| @@ -4260,6 +4418,8 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       is-number: 7.0.0 |       is-number: 7.0.0 | ||||||
|  |  | ||||||
|  |   toidentifier@1.0.1: {} | ||||||
|  |  | ||||||
|   toposort-class@1.0.1: {} |   toposort-class@1.0.1: {} | ||||||
|  |  | ||||||
|   touch@3.1.1: {} |   touch@3.1.1: {} | ||||||
| @@ -4396,7 +4556,7 @@ snapshots: | |||||||
|  |  | ||||||
|   wkx@0.5.0: |   wkx@0.5.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@types/node': 22.13.8 |       '@types/node': 22.13.10 | ||||||
|  |  | ||||||
|   wrap-ansi@7.0.0: |   wrap-ansi@7.0.0: | ||||||
|     dependencies: |     dependencies: | ||||||
| @@ -4416,7 +4576,7 @@ snapshots: | |||||||
|  |  | ||||||
|   ws@8.17.1: {} |   ws@8.17.1: {} | ||||||
|  |  | ||||||
|   ws@8.18.0: {} |   ws@8.18.1: {} | ||||||
|  |  | ||||||
|   xtend@4.0.2: {} |   xtend@4.0.2: {} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								pnpm-workspace.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pnpm-workspace.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | packages: | ||||||
|  |   - 'assistant-module' | ||||||
							
								
								
									
										13
									
								
								src/app.ts
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/app.ts
									
									
									
									
									
								
							| @@ -1,8 +1,19 @@ | |||||||
| import { App } from '@kevisual/router'; | import { App } from '@kevisual/router'; | ||||||
| import { useContextKey } from '@kevisual/use-config/context'; | import { useContextKey } from '@kevisual/use-config/context'; | ||||||
|  | import { httpsConfig } from './modules/config.ts'; | ||||||
|  |  | ||||||
| const init = () => { | const init = () => { | ||||||
|   return new App(); |   const app = new App({ | ||||||
|  |     serverOptions: { | ||||||
|  |       path: '/client/router', | ||||||
|  |       httpType: 'https', | ||||||
|  |       httpsCert: httpsConfig.cert.toString(), | ||||||
|  |       httpsKey: httpsConfig.key.toString(), | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
|  |   return app; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| export const app = useContextKey('app', init); | export const app = useContextKey('app', init); | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,16 +0,0 @@ | |||||||
| import { app } from './app.ts'; |  | ||||||
| import { useConfig } from '@kevisual/use-config'; |  | ||||||
|  |  | ||||||
| app |  | ||||||
|   .route({ |  | ||||||
|     path: 'demo', |  | ||||||
|     key: 'demo', |  | ||||||
|   }) |  | ||||||
|   .define(async (ctx) => { |  | ||||||
|     ctx.body = '123'; |  | ||||||
|   }) |  | ||||||
|   .addTo(app); |  | ||||||
|  |  | ||||||
| const config = useConfig(); |  | ||||||
|  |  | ||||||
| console.log('run demo: http://localhost:' + config.port + '/api/router?path=demo&key=demo'); |  | ||||||
							
								
								
									
										18
									
								
								src/dev.ts
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/dev.ts
									
									
									
									
									
								
							| @@ -1,8 +1,18 @@ | |||||||
| import { useConfig } from '@kevisual/use-config'; |  | ||||||
| import { app } from './index.ts'; | import { app } from './index.ts'; | ||||||
|  | import { proxyRoute } from './proxy-route/index.ts'; | ||||||
|  |  | ||||||
| const config = useConfig(); | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'demo', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     ctx.body = 'hello world'; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
| app.listen(config.port, () => { | console.log('httpsConfig', `https://localhost:51015/client/router?path=demo`); | ||||||
|   console.log(`server is running at http://localhost:${config.port}`); | app.listen(51015, () => { | ||||||
|  |   console.log('Router App is running on https://localhost:51015'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | app.server.on(proxyRoute); | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import { app } from './app.ts'; | import { app } from './app.ts'; | ||||||
| import './demo-route.ts'; | import './route/index.ts'; | ||||||
|  |  | ||||||
| export { app }; | export { app }; | ||||||
							
								
								
									
										9
									
								
								src/modules/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/modules/config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | import fs from 'fs'; | ||||||
|  | import path from 'path'; | ||||||
|  |  | ||||||
|  | const pemDir = path.join(process.cwd(), 'pem'); | ||||||
|  |  | ||||||
|  | export const httpsConfig = { | ||||||
|  |   key: fs.readFileSync(path.join(pemDir, 'https-key.pem')), | ||||||
|  |   cert: fs.readFileSync(path.join(pemDir, 'https-cert.pem')), | ||||||
|  | }; | ||||||
							
								
								
									
										108
									
								
								src/modules/config/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/modules/config/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | |||||||
|  | import path from 'path'; | ||||||
|  | import { homedir } from 'os'; | ||||||
|  | import fs from 'fs'; | ||||||
|  | import { checkFileExists, createDir } from '../file/index.ts'; | ||||||
|  |  | ||||||
|  | export const kevisualUrl = 'https://kevisual.xiongxiao.me'; | ||||||
|  | const configDir = createDir(path.join(homedir(), '.config/envision')); | ||||||
|  | export const configPath = path.join(configDir, 'assistant-config.json'); | ||||||
|  | export const appConfigPath = path.join(configDir, 'assistant-app-config.json'); | ||||||
|  | export const appDir = createDir(path.join(configDir, 'assistant-app/frontend')); | ||||||
|  | export const LocalElectronAppUrl = 'https://assistant.app/user/tiptap/'; | ||||||
|  |  | ||||||
|  | type AssistantConfig = { | ||||||
|  |   pageApi?: string; // https://kevisual.silkyai.cn | ||||||
|  |   loadURL?: string; // https://assistant.app/user/tiptap/ | ||||||
|  |   proxy?: { user: string; key: string; path: string }[]; | ||||||
|  | }; | ||||||
|  | let assistantConfig: AssistantConfig; | ||||||
|  | export const getConfig = () => { | ||||||
|  |   try { | ||||||
|  |     if (!checkFileExists(configPath)) { | ||||||
|  |       fs.writeFileSync(configPath, JSON.stringify({ proxy: [] }, null, 2)); | ||||||
|  |       return { | ||||||
|  |         loadURL: LocalElectronAppUrl, | ||||||
|  |         pageApi: '', | ||||||
|  |         proxy: [], | ||||||
|  |       }; | ||||||
|  |     } | ||||||
|  |     assistantConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')); | ||||||
|  |     return assistantConfig; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error(error); | ||||||
|  |     return { | ||||||
|  |       loadURL: LocalElectronAppUrl, | ||||||
|  |       pageApi: '', | ||||||
|  |       proxy: [], | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | export const getCacheAssistantConfig = () => { | ||||||
|  |   if (assistantConfig) { | ||||||
|  |     return assistantConfig; | ||||||
|  |   } | ||||||
|  |   return getConfig(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const setConfig = (config?: AssistantConfig) => { | ||||||
|  |   if (!config) { | ||||||
|  |     return assistantConfig; | ||||||
|  |   } | ||||||
|  |   assistantConfig = config; | ||||||
|  |   fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); | ||||||
|  |   return assistantConfig; | ||||||
|  | }; | ||||||
|  | type AppConfig = { | ||||||
|  |   list: any[]; | ||||||
|  | }; | ||||||
|  | /** | ||||||
|  |  * 应用配置 | ||||||
|  |  * @returns | ||||||
|  |  */ | ||||||
|  | export const getAppConfig = (): AppConfig => { | ||||||
|  |   if (!checkFileExists(appConfigPath)) { | ||||||
|  |     return { | ||||||
|  |       list: [], | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |   return JSON.parse(fs.readFileSync(appConfigPath, 'utf8')); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const setAppConfig = (config: AppConfig) => { | ||||||
|  |   fs.writeFileSync(appConfigPath, JSON.stringify(config, null, 2)); | ||||||
|  |   return config; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const addAppConfig = (app: any) => { | ||||||
|  |   const config = getAppConfig(); | ||||||
|  |   const assistantConfig = getCacheAssistantConfig(); | ||||||
|  |   const _apps = config.list; | ||||||
|  |   const _proxy = assistantConfig.proxy || []; | ||||||
|  |   const { user, key } = app; | ||||||
|  |   const newProxyInfo = { | ||||||
|  |     user, | ||||||
|  |     key, | ||||||
|  |     path: `/${user}/${key}`, | ||||||
|  |   }; | ||||||
|  |   const _proxyIndex = _proxy.findIndex((_proxy: any) => _proxy.path === newProxyInfo.path); | ||||||
|  |   if (_proxyIndex !== -1) { | ||||||
|  |     _proxy[_proxyIndex] = newProxyInfo; | ||||||
|  |   } else { | ||||||
|  |     _proxy.push(newProxyInfo); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const _app = _apps.findIndex((_app: any) => _app.id === app.id); | ||||||
|  |   if (_app !== -1) { | ||||||
|  |     _apps[_app] = app; | ||||||
|  |   } else { | ||||||
|  |     _apps.push(app); | ||||||
|  |   } | ||||||
|  |   setAppConfig({ ...config, list: _apps }); | ||||||
|  |   setConfig({ ...assistantConfig, proxy: _proxy }); | ||||||
|  |   return config; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const getAppList = () => { | ||||||
|  |   const config = getAppConfig(); | ||||||
|  |   return config.list || []; | ||||||
|  | }; | ||||||
							
								
								
									
										20
									
								
								src/modules/file/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/modules/file/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | import fs from 'fs'; | ||||||
|  |  | ||||||
|  | export const checkFileExists = (filePath: string, checkIsFile = false) => { | ||||||
|  |   try { | ||||||
|  |     fs.accessSync(filePath); | ||||||
|  |     if (checkIsFile) { | ||||||
|  |       return fs.statSync(filePath).isFile(); | ||||||
|  |     } | ||||||
|  |     return true; | ||||||
|  |   } catch (error) { | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const createDir = (dirPath: string) => { | ||||||
|  |   if (!checkFileExists(dirPath)) { | ||||||
|  |     fs.mkdirSync(dirPath, { recursive: true }); | ||||||
|  |   } | ||||||
|  |   return dirPath; | ||||||
|  | }; | ||||||
							
								
								
									
										156
									
								
								src/modules/install.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								src/modules/install.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | |||||||
|  | import path from 'path'; | ||||||
|  | import fs from 'fs'; | ||||||
|  | import { appDir, kevisualUrl, addAppConfig, getAppConfig, setAppConfig, getCacheAssistantConfig, setConfig } from './config/index.ts'; | ||||||
|  |  | ||||||
|  | export const demoData = { | ||||||
|  |   id: '471ee96f-d7d8-4da1-b84f-4a34f4732f16', | ||||||
|  |   title: 'tiptap', | ||||||
|  |   description: '', | ||||||
|  |   data: { | ||||||
|  |     files: [ | ||||||
|  |       { | ||||||
|  |         name: 'README.md', | ||||||
|  |         path: 'user/tiptap/0.0.1/README.md', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'app.css', | ||||||
|  |         path: 'user/tiptap/0.0.1/app.css', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'app.js', | ||||||
|  |         path: 'user/tiptap/0.0.1/app.js', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'create-BxEwtceK.js', | ||||||
|  |         path: 'user/tiptap/0.0.1/create-BxEwtceK.js', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'index.CrTXFMOJ.js', | ||||||
|  |         path: 'user/tiptap/0.0.1/index.CrTXFMOJ.js', | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'index.html', | ||||||
|  |         path: 'user/tiptap/0.0.1/index.html', | ||||||
|  |       }, | ||||||
|  |     ], | ||||||
|  |   }, | ||||||
|  |   version: '0.0.1', | ||||||
|  |   domain: '', | ||||||
|  |   appType: '', | ||||||
|  |   key: 'tiptap', | ||||||
|  |   type: '', | ||||||
|  |   uid: '2bebe6a0-3c64-4a64-89f9-cc47fd082a07', | ||||||
|  |   pid: null, | ||||||
|  |   proxy: false, | ||||||
|  |   user: 'user', | ||||||
|  |   status: 'running', | ||||||
|  |   createdAt: '2024-12-14T15:39:30.684Z', | ||||||
|  |   updatedAt: '2024-12-14T15:39:55.714Z', | ||||||
|  |   deletedAt: null, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | type DownloadTask = { | ||||||
|  |   downloadPath: string; | ||||||
|  |   downloadUrl: string; | ||||||
|  |   user: string; | ||||||
|  |   key: string; | ||||||
|  |   version: string; | ||||||
|  | }; | ||||||
|  | export type Package = { | ||||||
|  |   id: string; | ||||||
|  |   name?: string; | ||||||
|  |   version?: string; | ||||||
|  |   description?: string; | ||||||
|  |   title?: string; | ||||||
|  |   user?: string; | ||||||
|  |   key?: string; | ||||||
|  |   [key: string]: any; | ||||||
|  | }; | ||||||
|  | export const installApp = async (app: Package) => { | ||||||
|  |   // const _app = demoData; | ||||||
|  |   const _app = app; | ||||||
|  |   try { | ||||||
|  |     let files = _app.data.files || []; | ||||||
|  |     const version = _app.version; | ||||||
|  |     const user = _app.user; | ||||||
|  |     const key = _app.key; | ||||||
|  |  | ||||||
|  |     const downFiles = files.map((file: any) => { | ||||||
|  |       const noVersionPath = file.path.replace(`/${version}`, ''); | ||||||
|  |       return { | ||||||
|  |         ...file, | ||||||
|  |         downloadPath: path.join(appDir, noVersionPath), | ||||||
|  |         downloadUrl: `${kevisualUrl}/${noVersionPath}`, | ||||||
|  |       }; | ||||||
|  |     }); | ||||||
|  |     const downloadTasks: DownloadTask[] = downFiles as any; | ||||||
|  |     for (const file of downloadTasks) { | ||||||
|  |       const downloadPath = file.downloadPath; | ||||||
|  |       const downloadUrl = file.downloadUrl; | ||||||
|  |       const dir = path.dirname(downloadPath); | ||||||
|  |       if (!fs.existsSync(dir)) { | ||||||
|  |         fs.mkdirSync(dir, { recursive: true }); | ||||||
|  |       } | ||||||
|  |       const res = await fetch(downloadUrl); | ||||||
|  |       const blob = await res.blob(); | ||||||
|  |       fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); | ||||||
|  |     } | ||||||
|  |     let indexHtml = files.find((file: any) => file.name === 'index.html'); | ||||||
|  |     if (!indexHtml) { | ||||||
|  |       files.push({ | ||||||
|  |         name: 'index.html', | ||||||
|  |         path: `${user}/${key}/index.html`, | ||||||
|  |       }); | ||||||
|  |       fs.writeFileSync(path.join(appDir, `${user}/${key}/index.html`), JSON.stringify(app, null, 2)); | ||||||
|  |     } | ||||||
|  |     _app.data.files = files; | ||||||
|  |     addAppConfig(_app); | ||||||
|  |     return { | ||||||
|  |       code: 200, | ||||||
|  |       data: _app, | ||||||
|  |       message: 'Install app success', | ||||||
|  |     }; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error(error); | ||||||
|  |     return { | ||||||
|  |       code: 500, | ||||||
|  |       message: 'Install app failed', | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const uninstallApp = async (app: Package) => { | ||||||
|  |   try { | ||||||
|  |     const { user, key } = app; | ||||||
|  |     const appConfig = getAppConfig(); | ||||||
|  |     const index = appConfig.list.findIndex((item: any) => item.user === user && item.key === key); | ||||||
|  |     if (index !== -1) { | ||||||
|  |       appConfig.list.splice(index, 1); | ||||||
|  |       setAppConfig(appConfig); | ||||||
|  |       // 删除appDir和文件 | ||||||
|  |       fs.rmSync(path.join(appDir, user, key), { recursive: true }); | ||||||
|  |       // 删除proxy | ||||||
|  |       const proxyConfig = getCacheAssistantConfig(); | ||||||
|  |       const proxyIndex = proxyConfig.proxy.findIndex((item: any) => item.user === user && item.key === key); | ||||||
|  |       if (proxyIndex !== -1) { | ||||||
|  |         proxyConfig.proxy.splice(proxyIndex, 1); | ||||||
|  |         setConfig(proxyConfig); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return { | ||||||
|  |       code: 200, | ||||||
|  |       message: 'Uninstall app success', | ||||||
|  |     }; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error(error); | ||||||
|  |     return { | ||||||
|  |       code: 500, | ||||||
|  |       message: 'Uninstall app failed', | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export const getInstallList = async () => { | ||||||
|  |   const appConfig = getAppConfig(); | ||||||
|  |   return appConfig.list; | ||||||
|  | }; | ||||||
							
								
								
									
										61
									
								
								src/proxy-route/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/proxy-route/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | import { fileProxy, apiProxy, createApiProxy } from '@kevisual/assistant-module/proxy'; | ||||||
|  | import { getCacheAssistantConfig, appDir } from '@kevisual/assistant-module'; | ||||||
|  | import http from 'http'; | ||||||
|  |  | ||||||
|  | // https://localhost:51015/user/tiptap/ | ||||||
|  | export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResponse) => { | ||||||
|  |   const assistantConfig = getCacheAssistantConfig(); | ||||||
|  |   // const { apiList } = assistantConfig; | ||||||
|  |   const url = new URL(req.url, 'http://localhost'); | ||||||
|  |   const pathname = url.pathname; | ||||||
|  |   if (pathname.startsWith('/favicon.ico')) { | ||||||
|  |     res.statusCode = 404; | ||||||
|  |     res.end('Not Found Favicon'); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (pathname.startsWith('/client')) { | ||||||
|  |     console.log('handle by router'); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   const apiProxyList = assistantConfig?.apiProxyList || []; | ||||||
|  |   const defaultApiProxy = createApiProxy(assistantConfig?.pageApi || 'https://kevisual.xiongxiao.me'); | ||||||
|  |   const apiBackendProxy = [...apiProxyList, ...defaultApiProxy].find((item) => pathname.startsWith(item.path)); | ||||||
|  |   if (apiBackendProxy) { | ||||||
|  |     console.log('apiBackendProxy', apiBackendProxy); | ||||||
|  |     return apiProxy(req, res, { | ||||||
|  |       path: apiBackendProxy.path, | ||||||
|  |       target: apiBackendProxy.target, | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |   // client, api, v1, serve 开头的拦截 | ||||||
|  |   const proxyApiList = assistantConfig?.proxy || []; | ||||||
|  |   const proxyApi = proxyApiList.find((item) => pathname.startsWith(item.path)); | ||||||
|  |   if (proxyApi) { | ||||||
|  |     console.log('proxyApi', proxyApi, pathname); | ||||||
|  |     const { user, key } = proxyApi; | ||||||
|  |     return fileProxy(req, res, { | ||||||
|  |       path: proxyApi.path, | ||||||
|  |       rootPath: appDir, | ||||||
|  |       indexPath: `${user}/${key}/index.html`, | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |   const localProxyProxy = localProxyProxyList.find((item) => pathname.startsWith(item.path)); | ||||||
|  |   if (localProxyProxy) { | ||||||
|  |     return fileProxy(req, res, { | ||||||
|  |       path: localProxyProxy.path, | ||||||
|  |       rootPath: process.cwd(), | ||||||
|  |       indexPath: localProxyProxy.indexPath, | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |   console.log('handle by router 404'); | ||||||
|  |   res.statusCode = 404; | ||||||
|  |   res.end('Not Found Proxy'); | ||||||
|  | }; | ||||||
|  | const localProxyProxyList = [ | ||||||
|  |   { | ||||||
|  |     user: 'root', | ||||||
|  |     key: 'assistant-base-app', | ||||||
|  |     path: '/root/assistant-base-app', | ||||||
|  |     indexPath: 'root/assistant-base-app/index.html', | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
							
								
								
									
										42
									
								
								src/proxy-route/ws-proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/proxy-route/ws-proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | import net from 'net'; | ||||||
|  | import { App } from '@kevisual/router'; | ||||||
|  |  | ||||||
|  | export const wsProxy = (app: App, config: { apiList: any[] }) => { | ||||||
|  |   console.log('Upgrade initialization started'); | ||||||
|  |  | ||||||
|  |   app.server.server.on('upgrade', (req, socket, head) => { | ||||||
|  |     const proxyApiList = config?.apiList || []; | ||||||
|  |     const proxyApi = proxyApiList.find((item) => req.url.startsWith(item.path)); | ||||||
|  |  | ||||||
|  |     if (proxyApi) { | ||||||
|  |       const _u = new URL(req.url, `${proxyApi.target}`); | ||||||
|  |       const options = { | ||||||
|  |         hostname: _u.hostname, | ||||||
|  |         port: Number(_u.port) || 80, | ||||||
|  |         path: _u.pathname, | ||||||
|  |         headers: req.headers, | ||||||
|  |       }; | ||||||
|  |  | ||||||
|  |       const proxySocket = net.connect(options.port, options.hostname, () => { | ||||||
|  |         proxySocket.write( | ||||||
|  |           `GET ${options.path} HTTP/1.1\r\n` + | ||||||
|  |             `Host: ${options.hostname}\r\n` + | ||||||
|  |             `Connection: Upgrade\r\n` + | ||||||
|  |             `Upgrade: websocket\r\n` + | ||||||
|  |             `Sec-WebSocket-Key: ${req.headers['sec-websocket-key']}\r\n` + | ||||||
|  |             `Sec-WebSocket-Version: ${req.headers['sec-websocket-version']}\r\n` + | ||||||
|  |             `\r\n`, | ||||||
|  |         ); | ||||||
|  |         proxySocket.pipe(socket); | ||||||
|  |         socket.pipe(proxySocket); | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |       proxySocket.on('error', (err) => { | ||||||
|  |         console.error(`WebSocket proxy error: ${err.message}`); | ||||||
|  |         socket.end(); | ||||||
|  |       }); | ||||||
|  |     } else { | ||||||
|  |       socket.end(); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | }; | ||||||
							
								
								
									
										10
									
								
								src/route/client/check.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/route/client/check.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | import { app } from '@/app.ts'; | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'check', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     ctx.body = 'ok'; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
							
								
								
									
										25
									
								
								src/route/config/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/route/config/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | import { app } from '@/app.ts'; | ||||||
|  | import { getCacheAssistantConfig, setConfig } from '@/modules/config/index.ts'; | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'config', | ||||||
|  |     description: '获取配置', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     ctx.body = getCacheAssistantConfig(); | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'config', | ||||||
|  |     key: 'set', | ||||||
|  |     description: '设置配置', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     const { data } = ctx.query; | ||||||
|  |  | ||||||
|  |     ctx.body = setConfig(data); | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
							
								
								
									
										3
									
								
								src/route/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/route/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | import './shop-install/index.ts'; | ||||||
|  | import './client/check.ts'; | ||||||
|  | import './config/index.ts'; | ||||||
							
								
								
									
										40
									
								
								src/route/shop-install/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/route/shop-install/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | import { app } from '@/app.ts'; | ||||||
|  | import { getInstallList, installApp, uninstallApp } from '@/modules/install.ts'; | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'shop', | ||||||
|  |     key: 'list-installed', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     // https://localhost:51015/client/router?path=shop&key=list-installed | ||||||
|  |     const list = await getInstallList(); | ||||||
|  |     ctx.body = list; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'shop', | ||||||
|  |     key: 'install', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     // https://localhost:51015/client/router?path=shop&key=install | ||||||
|  |     const { pkg } = ctx.query.data; | ||||||
|  |     const res = await installApp(pkg); | ||||||
|  |     ctx.body = res; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'shop', | ||||||
|  |     key: 'uninstall', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     // https://localhost:51015/client/router?path=shop&key=uninstall | ||||||
|  |     const { pkg } = ctx.query.data; | ||||||
|  |     const res = await uninstallApp(pkg); | ||||||
|  |     ctx.body = res; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
							
								
								
									
										8
									
								
								src/scripts/assistant-config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/scripts/assistant-config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | import { getCacheAssistantConfig, appConfigPath, appDir } from '@kevisual/assistant-module'; | ||||||
|  | import fs from 'fs'; | ||||||
|  |  | ||||||
|  | const assistantConfig = getCacheAssistantConfig(); | ||||||
|  | console.log(assistantConfig); | ||||||
|  |  | ||||||
|  | console.log('appConfigPath', appConfigPath); | ||||||
|  | console.log('appDir', appDir); | ||||||
		Reference in New Issue
	
	Block a user