generated from tailored/router-template
	test
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -15,3 +15,6 @@ logs | ||||
| root/ | ||||
|  | ||||
| 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": { | ||||
|     "send": "^1.1.0", | ||||
|     "ws": "^8.18.1" | ||||
|     "ws": "npm:@kevisual/ws" | ||||
|   } | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| import path from 'path'; | ||||
| import fs from 'fs'; | ||||
| import path from 'node:path'; | ||||
| import fs from 'node:fs'; | ||||
|  | ||||
| type DownloadTask = { | ||||
|   downloadPath: string; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import http from 'http'; | ||||
| import https from 'https'; | ||||
| import http from 'node:http'; | ||||
| import https from 'node:https'; | ||||
| import { rewriteCookieDomain } from '../https/cookie-rewrite.ts'; | ||||
| import { ProxyInfo } from './proxy.ts'; | ||||
| export const defaultApiProxy = [ | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import http from 'http'; | ||||
| import http from 'node:http'; | ||||
| import send from 'send'; | ||||
| import fs from 'fs'; | ||||
| import fs from 'node:fs'; | ||||
| import path from 'path'; | ||||
| import { ProxyInfo } from './proxy.ts'; | ||||
| import { checkFileExists } from '@/file/index.ts'; | ||||
|   | ||||
| @@ -2,4 +2,4 @@ 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'; | ||||
| export * from './ws-proxy.ts'; | ||||
| @@ -8,6 +8,11 @@ export type ProxyInfo = { | ||||
|    * 类型 | ||||
|    */ | ||||
|   type?: 'static' | 'dynamic' | 'minio'; | ||||
|   /** | ||||
|    * 是否使用websocket | ||||
|    * @default false | ||||
|    */ | ||||
|   ws?: boolean; | ||||
|   /** | ||||
|    * 首要文件,比如index.html, 设置了首要文件,如果文件不存在,则访问首要文件 | ||||
|    */ | ||||
| @@ -23,6 +28,10 @@ export type ApiList = { | ||||
|    * url或者相对路径 | ||||
|    */ | ||||
|   target: string; | ||||
|   /** | ||||
|    * 目标地址 | ||||
|    */ | ||||
|   ws?: boolean; | ||||
|   /** | ||||
|    * 类型 | ||||
|    */ | ||||
|   | ||||
| @@ -1,19 +1,20 @@ | ||||
| import { Server } from 'http'; | ||||
| import WebSocket from 'ws'; | ||||
| import { ProxyInfo } from './proxy.ts'; | ||||
| /** | ||||
|  * websocket代理 | ||||
|  * apiList: [{ path: '/api/router', target: 'https://kevisual.xiongxiao.me' }] | ||||
|  * @param server | ||||
|  * @param config | ||||
|  */ | ||||
| export const wsProxy = (server: Server, config: { apiList: any[] }) => { | ||||
| export const wsProxy = (server: Server, config: { apiList: ProxyInfo[] }) => { | ||||
|   console.log('Upgrade initialization started'); | ||||
| 
 | ||||
|   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)); | ||||
| 
 | ||||
|     if (proxyApi) { | ||||
|     if (proxyApi && proxyApi.ws) { | ||||
|       const _u = new URL(req.url, `${proxyApi.target}`); | ||||
|       const isHttps = _u.protocol === 'https:'; | ||||
|       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", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
|   "app": { | ||||
|     "key": "assistant-center", | ||||
|     "entry": "dist/app.mjs", | ||||
|     "type": "system-app", | ||||
|     "files": [ | ||||
|       "dist", | ||||
|       "pem", | ||||
|       "root" | ||||
|     ] | ||||
|     "type": "system-app" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "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", | ||||
|     "bun": "bun run --watch --hot --inspect src/main.ts", | ||||
|     "build": "rollup -c rollup.config.mjs", | ||||
|     "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\" ", | ||||
| @@ -35,12 +31,12 @@ | ||||
|     "root" | ||||
|   ], | ||||
|   "dependencies": { | ||||
|     "@kevisual/code-center-module": "0.0.13", | ||||
|     "@kevisual/code-center-module": "0.0.18", | ||||
|     "@kevisual/mark": "0.0.7", | ||||
|     "@kevisual/router": "0.0.9", | ||||
|     "@kevisual/router": "0.0.13", | ||||
|     "cookie": "^1.0.2", | ||||
|     "dayjs": "^1.11.13", | ||||
|     "formidable": "^3.5.2", | ||||
|     "formidable": "^3.5.4", | ||||
|     "get-port": "^7.1.0", | ||||
|     "json5": "^2.2.3", | ||||
|     "lodash-es": "^4.17.21", | ||||
| @@ -49,31 +45,31 @@ | ||||
|   "devDependencies": { | ||||
|     "@kevisual/assistant-module": "workspace:*", | ||||
|     "@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-commonjs": "^28.0.3", | ||||
|     "@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-typescript": "^12.1.2", | ||||
|     "@types/crypto-js": "^4.2.2", | ||||
|     "@types/formidable": "^3.4.5", | ||||
|     "@types/lodash-es": "^4.17.12", | ||||
|     "@types/node": "^22.13.9", | ||||
|     "@types/ws": "^8.18.0", | ||||
|     "@types/node": "^22.14.1", | ||||
|     "@types/ws": "^8.18.1", | ||||
|     "concurrently": "^9.1.2", | ||||
|     "cross-env": "^7.0.3", | ||||
|     "nodemon": "^3.1.9", | ||||
|     "pm2": "^5.4.3", | ||||
|     "nodemon": "^3.1.10", | ||||
|     "pm2": "^6.0.5", | ||||
|     "rimraf": "^6.0.1", | ||||
|     "rollup": "^4.34.9", | ||||
|     "rollup": "^4.40.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", | ||||
|     "tape": "^5.9.0", | ||||
|     "tsx": "^4.19.3", | ||||
|     "typescript": "^5.8.2" | ||||
|     "typescript": "^5.8.3" | ||||
|   }, | ||||
|   "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, | ||||
| } 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 { getCacheAssistantConfig, setConfig, getConfig, getAppConfig, setAppConfig }; | ||||
|  | ||||
| export const addAppConfig = (app: any) => { | ||||
|   const config = getAppConfig(); | ||||
|   const assistantConfig = getCacheAssistantConfig(); | ||||
|   | ||||
| @@ -66,8 +66,9 @@ export type Package = { | ||||
|   key?: string; | ||||
|   [key: string]: any; | ||||
| }; | ||||
| export const installApp = async (app: Package) => { | ||||
| export const installApp = async (app: Package, opts?: { baseURL?: string }) => { | ||||
|   // const _app = demoData; | ||||
|   const _u = opts?.baseURL || kevisualUrl; | ||||
|   const _app = app; | ||||
|   try { | ||||
|     let files = _app.data.files || []; | ||||
| @@ -80,18 +81,24 @@ export const installApp = async (app: Package) => { | ||||
|       return { | ||||
|         ...file, | ||||
|         downloadPath: path.join(appDir, noVersionPath), | ||||
|         downloadUrl: `${kevisualUrl}/${noVersionPath}`, | ||||
|         downloadUrl: `${_u}/${noVersionPath}`, | ||||
|       }; | ||||
|     }); | ||||
|     const downloadTasks: DownloadTask[] = downFiles as any; | ||||
|     for (const file of downloadTasks) { | ||||
|       const downloadPath = file.downloadPath; | ||||
|       const downloadUrl = file.downloadUrl; | ||||
|       const downloadUrl = new URL(file.downloadUrl); | ||||
|       const dir = path.dirname(downloadPath); | ||||
|       if (!fs.existsSync(dir)) { | ||||
|         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(); | ||||
|       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 { getCacheAssistantConfig, appDir } from '@kevisual/assistant-module'; | ||||
| import http from 'http'; | ||||
|  | ||||
| import { LocalProxy } from './get-local-proxy.ts'; | ||||
| const localProxy = new LocalProxy(); | ||||
| // https://localhost:51015/user/tiptap/ | ||||
| export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResponse) => { | ||||
|   const assistantConfig = getCacheAssistantConfig(); | ||||
| @@ -51,6 +52,7 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp | ||||
|       indexPath: `${user}/${key}/index.html`, // 首页路径 | ||||
|     }); | ||||
|   } | ||||
|   const localProxyProxyList = localProxy.getLocalProxyList(); | ||||
|   const localProxyProxy = localProxyProxyList.find((item) => pathname.startsWith(item.path)); | ||||
|   if (localProxyProxy) { | ||||
|     console.log('localProxyProxy', localProxyProxy, req.url); | ||||
| @@ -69,11 +71,3 @@ export const proxyRoute = async (req: http.IncomingMessage, res: http.ServerResp | ||||
|   //   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 tls from 'tls' | ||||
| import { App } from '@kevisual/router'; | ||||
|  | ||||
| export const wsProxy = (app: App, config: { apiList: any[] }) => { | ||||
|   | ||||
| @@ -22,6 +22,9 @@ app | ||||
|     // https://localhost:51015/client/router?path=shop&key=install | ||||
|     const { pkg } = ctx.query.data; | ||||
|     const res = await installApp(pkg); | ||||
|     if (res.code !== 200) { | ||||
|       ctx.throw(res.code, res.message); | ||||
|     } | ||||
|     ctx.body = res; | ||||
|   }) | ||||
|   .addTo(app); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user