generated from tailored/router-template
	test
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,3 +15,6 @@ logs | |||||||
| root/ | root/ | ||||||
|  |  | ||||||
| release/*.tgz | release/*.tgz | ||||||
|  |  | ||||||
|  | .env* | ||||||
|  | !.env*example | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| { |  | ||||||
|   port: 3000, |  | ||||||
|   postgres: { |  | ||||||
|     username: 'postgres', |  | ||||||
|     host: 'localhost', |  | ||||||
|     database: 'postgres', |  | ||||||
|     password: 'postgres', |  | ||||||
|     port: 5432, |  | ||||||
|   }, |  | ||||||
|   tableName: { |  | ||||||
|     table: 'name', |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -44,6 +44,6 @@ | |||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "send": "^1.1.0", |     "send": "^1.1.0", | ||||||
|     "ws": "^8.18.1" |     "ws": "npm:@kevisual/ws" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| import path from 'path'; | import path from 'node:path'; | ||||||
| import fs from 'fs'; | import fs from 'node:fs'; | ||||||
|  |  | ||||||
| type DownloadTask = { | type DownloadTask = { | ||||||
|   downloadPath: string; |   downloadPath: string; | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import http from 'http'; | import http from 'node:http'; | ||||||
| import https from 'https'; | import https from 'node:https'; | ||||||
| import { rewriteCookieDomain } from '../https/cookie-rewrite.ts'; | import { rewriteCookieDomain } from '../https/cookie-rewrite.ts'; | ||||||
| import { ProxyInfo } from './proxy.ts'; | import { ProxyInfo } from './proxy.ts'; | ||||||
| export const defaultApiProxy = [ | export const defaultApiProxy = [ | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import http from 'http'; | import http from 'node:http'; | ||||||
| import send from 'send'; | import send from 'send'; | ||||||
| import fs from 'fs'; | import fs from 'node:fs'; | ||||||
| import path from 'path'; | import path from 'path'; | ||||||
| import { ProxyInfo } from './proxy.ts'; | import { ProxyInfo } from './proxy.ts'; | ||||||
| import { checkFileExists } from '@/file/index.ts'; | import { checkFileExists } from '@/file/index.ts'; | ||||||
|   | |||||||
| @@ -2,4 +2,4 @@ export * from './proxy.ts'; | |||||||
| export * from './file-proxy.ts'; | export * from './file-proxy.ts'; | ||||||
| export { default as send } from 'send'; | export { default as send } from 'send'; | ||||||
| export * from './api-proxy.ts'; | export * from './api-proxy.ts'; | ||||||
| export * from './wx-proxy.ts'; | export * from './ws-proxy.ts'; | ||||||
| @@ -8,6 +8,11 @@ export type ProxyInfo = { | |||||||
|    * 类型 |    * 类型 | ||||||
|    */ |    */ | ||||||
|   type?: 'static' | 'dynamic' | 'minio'; |   type?: 'static' | 'dynamic' | 'minio'; | ||||||
|  |   /** | ||||||
|  |    * 是否使用websocket | ||||||
|  |    * @default false | ||||||
|  |    */ | ||||||
|  |   ws?: boolean; | ||||||
|   /** |   /** | ||||||
|    * 首要文件,比如index.html, 设置了首要文件,如果文件不存在,则访问首要文件 |    * 首要文件,比如index.html, 设置了首要文件,如果文件不存在,则访问首要文件 | ||||||
|    */ |    */ | ||||||
| @@ -23,6 +28,10 @@ export type ApiList = { | |||||||
|    * url或者相对路径 |    * url或者相对路径 | ||||||
|    */ |    */ | ||||||
|   target: string; |   target: string; | ||||||
|  |   /** | ||||||
|  |    * 目标地址 | ||||||
|  |    */ | ||||||
|  |   ws?: boolean; | ||||||
|   /** |   /** | ||||||
|    * 类型 |    * 类型 | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -1,19 +1,20 @@ | |||||||
| import { Server } from 'http'; | import { Server } from 'http'; | ||||||
| import WebSocket from 'ws'; | import WebSocket from 'ws'; | ||||||
|  | import { ProxyInfo } from './proxy.ts'; | ||||||
| /** | /** | ||||||
|  * websocket代理 |  * websocket代理 | ||||||
|  * apiList: [{ path: '/api/router', target: 'https://kevisual.xiongxiao.me' }] |  * apiList: [{ path: '/api/router', target: 'https://kevisual.xiongxiao.me' }] | ||||||
|  * @param server |  * @param server | ||||||
|  * @param config |  * @param config | ||||||
|  */ |  */ | ||||||
| export const wsProxy = (server: Server, config: { apiList: any[] }) => { | export const wsProxy = (server: Server, config: { apiList: ProxyInfo[] }) => { | ||||||
|   console.log('Upgrade initialization started'); |   console.log('Upgrade initialization started'); | ||||||
| 
 | 
 | ||||||
|   server.on('upgrade', (req, socket, head) => { |   server.on('upgrade', (req, socket, head) => { | ||||||
|     const proxyApiList = config?.apiList || []; |     const proxyApiList: ProxyInfo[] = config?.apiList || []; | ||||||
|     const proxyApi = proxyApiList.find((item) => req.url.startsWith(item.path)); |     const proxyApi = proxyApiList.find((item) => req.url.startsWith(item.path)); | ||||||
| 
 | 
 | ||||||
|     if (proxyApi) { |     if (proxyApi && proxyApi.ws) { | ||||||
|       const _u = new URL(req.url, `${proxyApi.target}`); |       const _u = new URL(req.url, `${proxyApi.target}`); | ||||||
|       const isHttps = _u.protocol === 'https:'; |       const isHttps = _u.protocol === 'https:'; | ||||||
|       const wsProtocol = isHttps ? 'wss' : 'ws'; |       const wsProtocol = isHttps ? 'wss' : 'ws'; | ||||||
							
								
								
									
										9
									
								
								bun.config.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								bun.config.mjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | // https://bun.sh/docs/bundler | ||||||
|  |  | ||||||
|  | await Bun.build({ | ||||||
|  |   target: 'node', | ||||||
|  |   format: 'esm', | ||||||
|  |   entrypoints: ['./src/main.ts'], | ||||||
|  |   outdir: './dist', | ||||||
|  |   env: 'ASSISTANT_*', | ||||||
|  | }); | ||||||
							
								
								
									
										38
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,21 +1,17 @@ | |||||||
| { | { | ||||||
|   "name": "assistant-center", |   "name": "@kevisual/assistant-center", | ||||||
|   "version": "0.0.4", |   "version": "0.0.4", | ||||||
|   "description": "", |   "description": "", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|   "app": { |   "app": { | ||||||
|     "key": "assistant-center", |     "key": "assistant-center", | ||||||
|     "entry": "dist/app.mjs", |     "entry": "dist/app.mjs", | ||||||
|     "type": "system-app", |     "type": "system-app" | ||||||
|     "files": [ |  | ||||||
|       "dist", |  | ||||||
|       "pem", |  | ||||||
|       "root" |  | ||||||
|     ] |  | ||||||
|   }, |   }, | ||||||
|   "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", | ||||||
|  |     "bun": "bun run --watch --hot --inspect src/main.ts", | ||||||
|     "build": "rollup -c rollup.config.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\" ", | ||||||
| @@ -35,12 +31,12 @@ | |||||||
|     "root" |     "root" | ||||||
|   ], |   ], | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@kevisual/code-center-module": "0.0.13", |     "@kevisual/code-center-module": "0.0.18", | ||||||
|     "@kevisual/mark": "0.0.7", |     "@kevisual/mark": "0.0.7", | ||||||
|     "@kevisual/router": "0.0.9", |     "@kevisual/router": "0.0.13", | ||||||
|     "cookie": "^1.0.2", |     "cookie": "^1.0.2", | ||||||
|     "dayjs": "^1.11.13", |     "dayjs": "^1.11.13", | ||||||
|     "formidable": "^3.5.2", |     "formidable": "^3.5.4", | ||||||
|     "get-port": "^7.1.0", |     "get-port": "^7.1.0", | ||||||
|     "json5": "^2.2.3", |     "json5": "^2.2.3", | ||||||
|     "lodash-es": "^4.17.21", |     "lodash-es": "^4.17.21", | ||||||
| @@ -49,31 +45,31 @@ | |||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@kevisual/assistant-module": "workspace:*", |     "@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.11", | ||||||
|     "@rollup/plugin-alias": "^5.1.1", |     "@rollup/plugin-alias": "^5.1.1", | ||||||
|     "@rollup/plugin-commonjs": "^28.0.3", |     "@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.1", | ||||||
|     "@rollup/plugin-replace": "^6.0.2", |     "@rollup/plugin-replace": "^6.0.2", | ||||||
|     "@rollup/plugin-typescript": "^12.1.2", |     "@rollup/plugin-typescript": "^12.1.2", | ||||||
|     "@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.9", |     "@types/node": "^22.14.1", | ||||||
|     "@types/ws": "^8.18.0", |     "@types/ws": "^8.18.1", | ||||||
|     "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.10", | ||||||
|     "pm2": "^5.4.3", |     "pm2": "^6.0.5", | ||||||
|     "rimraf": "^6.0.1", |     "rimraf": "^6.0.1", | ||||||
|     "rollup": "^4.34.9", |     "rollup": "^4.40.0", | ||||||
|     "rollup-plugin-copy": "^3.5.0", |     "rollup-plugin-copy": "^3.5.0", | ||||||
|     "rollup-plugin-dts": "^6.1.1", |     "rollup-plugin-dts": "^6.2.1", | ||||||
|     "rollup-plugin-esbuild": "^6.2.1", |     "rollup-plugin-esbuild": "^6.2.1", | ||||||
|     "tape": "^5.9.0", |     "tape": "^5.9.0", | ||||||
|     "tsx": "^4.19.3", |     "tsx": "^4.19.3", | ||||||
|     "typescript": "^5.8.2" |     "typescript": "^5.8.3" | ||||||
|   }, |   }, | ||||||
|   "pnpm": {}, |   "pnpm": {}, | ||||||
|   "packageManager": "pnpm@9.14.4" |   "packageManager": "pnpm@10.9.0" | ||||||
| } | } | ||||||
							
								
								
									
										680
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										680
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								src-cli/program.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src-cli/program.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | import { Comander } from 'commander'; | ||||||
| @@ -10,12 +10,10 @@ import { | |||||||
|   LocalElectronAppUrl, |   LocalElectronAppUrl, | ||||||
| } from '@kevisual/assistant-module/assistant-config'; | } from '@kevisual/assistant-module/assistant-config'; | ||||||
|  |  | ||||||
| export const kevisualUrl = process.env.KEVISUAL_URL || 'https://kevisual.xiongxiao.me'; | export const kevisualUrl = process.env.KEVISUAL_URL || 'https://kevisual.cn'; | ||||||
|  |  | ||||||
| export { configPath, appConfigPath, appDir, LocalElectronAppUrl }; | export { configPath, appConfigPath, appDir, LocalElectronAppUrl }; | ||||||
|  |  | ||||||
| export { getCacheAssistantConfig, setConfig, getConfig, getAppConfig, setAppConfig }; | export { getCacheAssistantConfig, setConfig, getConfig, getAppConfig, setAppConfig }; | ||||||
|  |  | ||||||
| export const addAppConfig = (app: any) => { | export const addAppConfig = (app: any) => { | ||||||
|   const config = getAppConfig(); |   const config = getAppConfig(); | ||||||
|   const assistantConfig = getCacheAssistantConfig(); |   const assistantConfig = getCacheAssistantConfig(); | ||||||
|   | |||||||
| @@ -66,8 +66,9 @@ export type Package = { | |||||||
|   key?: string; |   key?: string; | ||||||
|   [key: string]: any; |   [key: string]: any; | ||||||
| }; | }; | ||||||
| export const installApp = async (app: Package) => { | export const installApp = async (app: Package, opts?: { baseURL?: string }) => { | ||||||
|   // const _app = demoData; |   // const _app = demoData; | ||||||
|  |   const _u = opts?.baseURL || kevisualUrl; | ||||||
|   const _app = app; |   const _app = app; | ||||||
|   try { |   try { | ||||||
|     let files = _app.data.files || []; |     let files = _app.data.files || []; | ||||||
| @@ -80,18 +81,24 @@ export const installApp = async (app: Package) => { | |||||||
|       return { |       return { | ||||||
|         ...file, |         ...file, | ||||||
|         downloadPath: path.join(appDir, noVersionPath), |         downloadPath: path.join(appDir, noVersionPath), | ||||||
|         downloadUrl: `${kevisualUrl}/${noVersionPath}`, |         downloadUrl: `${_u}/${noVersionPath}`, | ||||||
|       }; |       }; | ||||||
|     }); |     }); | ||||||
|     const downloadTasks: DownloadTask[] = downFiles as any; |     const downloadTasks: DownloadTask[] = downFiles as any; | ||||||
|     for (const file of downloadTasks) { |     for (const file of downloadTasks) { | ||||||
|       const downloadPath = file.downloadPath; |       const downloadPath = file.downloadPath; | ||||||
|       const downloadUrl = file.downloadUrl; |       const downloadUrl = new URL(file.downloadUrl); | ||||||
|       const dir = path.dirname(downloadPath); |       const dir = path.dirname(downloadPath); | ||||||
|       if (!fs.existsSync(dir)) { |       if (!fs.existsSync(dir)) { | ||||||
|         fs.mkdirSync(dir, { recursive: true }); |         fs.mkdirSync(dir, { recursive: true }); | ||||||
|       } |       } | ||||||
|       const res = await fetch(downloadUrl); |       downloadUrl.searchParams.set('download', 'true'); | ||||||
|  |       const res = await fetch(downloadUrl.toString()); | ||||||
|  |       const resStatus = res.status; | ||||||
|  |       if (resStatus !== 200) { | ||||||
|  |         console.error(`Download file failed: ${resStatus}\n`, downloadUrl.toString(),'\npath:', downloadPath); | ||||||
|  |         throw new Error(`Download file failed: ${resStatus}`); | ||||||
|  |       } | ||||||
|       const blob = await res.blob(); |       const blob = await res.blob(); | ||||||
|       fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); |       fs.writeFileSync(downloadPath, Buffer.from(await blob.arrayBuffer())); | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								src/proxy-route/get-local-proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/proxy-route/get-local-proxy.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | import { appDir } from '@kevisual/assistant-module'; | ||||||
|  |  | ||||||
|  | export const localProxyProxyList = [ | ||||||
|  |   { | ||||||
|  |     user: 'root', | ||||||
|  |     key: 'assistant-base-app', | ||||||
|  |     path: '/root/assistant-base-app', | ||||||
|  |     indexPath: 'root/assistant-base-app/index.html', | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     user: 'root', | ||||||
|  |     key: 'talkshow-admin', | ||||||
|  |     path: '/root/talkshow-admin', | ||||||
|  |     indexPath: 'root/talkshow-admin/index.html', | ||||||
|  |   }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | type ProxyType = { | ||||||
|  |   user: string; | ||||||
|  |   key: string; | ||||||
|  |   path: string; | ||||||
|  |   indexPath: string; | ||||||
|  | }; | ||||||
|  | export class LocalProxy { | ||||||
|  |   localProxyProxyList: ProxyType[] = []; | ||||||
|  |   currentEnvPath: string = ''; | ||||||
|  |   constructor() { | ||||||
|  |     console.log('LocalProxy', appDir); | ||||||
|  |     this.init(); | ||||||
|  |     this.currentEnvPath = process.cwd(); | ||||||
|  |   } | ||||||
|  |   init() { | ||||||
|  |     this.localProxyProxyList = localProxyProxyList; | ||||||
|  |   } | ||||||
|  |   getLocalProxyList() { | ||||||
|  |     return this.localProxyProxyList; | ||||||
|  |   } | ||||||
|  |   reload() { | ||||||
|  |     // 重新加载本地代理列表 | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,7 +1,8 @@ | |||||||
| import { fileProxy, apiProxy, createApiProxy } from '@kevisual/assistant-module/proxy'; | import { fileProxy, apiProxy, createApiProxy } from '@kevisual/assistant-module/proxy'; | ||||||
| import { getCacheAssistantConfig, appDir } from '@kevisual/assistant-module'; | import { getCacheAssistantConfig, appDir } from '@kevisual/assistant-module'; | ||||||
| import http from 'http'; | import http from 'http'; | ||||||
|  | import { LocalProxy } from './get-local-proxy.ts'; | ||||||
|  | const localProxy = new LocalProxy(); | ||||||
| // https://localhost:51015/user/tiptap/ | // https://localhost:51015/user/tiptap/ | ||||||
| export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResponse) => { | export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResponse) => { | ||||||
|   const assistantConfig = getCacheAssistantConfig(); |   const assistantConfig = getCacheAssistantConfig(); | ||||||
| @@ -51,6 +52,7 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp | |||||||
|       indexPath: `${user}/${key}/index.html`, // 首页路径 |       indexPath: `${user}/${key}/index.html`, // 首页路径 | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |   const localProxyProxyList = localProxy.getLocalProxyList(); | ||||||
|   const localProxyProxy = localProxyProxyList.find((item) => pathname.startsWith(item.path)); |   const localProxyProxy = localProxyProxyList.find((item) => pathname.startsWith(item.path)); | ||||||
|   if (localProxyProxy) { |   if (localProxyProxy) { | ||||||
|     console.log('localProxyProxy', localProxyProxy, req.url); |     console.log('localProxyProxy', localProxyProxy, req.url); | ||||||
| @@ -69,11 +71,3 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp | |||||||
|   //   target: getCacheAssistantConfig().pageApi, |   //   target: getCacheAssistantConfig().pageApi, | ||||||
|   // }); |   // }); | ||||||
| }; | }; | ||||||
| const localProxyProxyList = [ |  | ||||||
|   { |  | ||||||
|     user: 'root', |  | ||||||
|     key: 'assistant-base-app', |  | ||||||
|     path: '/root/assistant-base-app', |  | ||||||
|     indexPath: 'root/assistant-base-app/index.html', |  | ||||||
|   }, |  | ||||||
| ]; |  | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import net from 'net'; | import net from 'net'; | ||||||
|  | import tls from 'tls' | ||||||
| import { App } from '@kevisual/router'; | import { App } from '@kevisual/router'; | ||||||
|  |  | ||||||
| export const wsProxy = (app: App, config: { apiList: any[] }) => { | export const wsProxy = (app: App, config: { apiList: any[] }) => { | ||||||
|   | |||||||
| @@ -22,6 +22,9 @@ app | |||||||
|     // https://localhost:51015/client/router?path=shop&key=install |     // https://localhost:51015/client/router?path=shop&key=install | ||||||
|     const { pkg } = ctx.query.data; |     const { pkg } = ctx.query.data; | ||||||
|     const res = await installApp(pkg); |     const res = await installApp(pkg); | ||||||
|  |     if (res.code !== 200) { | ||||||
|  |       ctx.throw(res.code, res.message); | ||||||
|  |     } | ||||||
|     ctx.body = res; |     ctx.body = res; | ||||||
|   }) |   }) | ||||||
|   .addTo(app); |   .addTo(app); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user