Compare commits
	
		
			8 Commits
		
	
	
		
			42e32adf86
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 02c505c83a | |||
| e59484e3c7 | |||
| 6a4ff85683 | |||
| b3c2587903 | |||
| 79a9568a87 | |||
| a9afc2ffea | |||
| 5c91ac8b8d | |||
| 73118f8454 | 
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -5,4 +5,9 @@ coverage | ||||
| .DS_Store | ||||
| upload | ||||
|  | ||||
| app.config.json5 | ||||
| app.config.json5 | ||||
|  | ||||
| release/* | ||||
| !release/.gitkeep | ||||
|  | ||||
| /*.tgz | ||||
							
								
								
									
										5
									
								
								.npmrc
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								.npmrc
									
									
									
									
									
								
							| @@ -1 +1,4 @@ | ||||
| @abearxiong:registry=https://npm.pkg.github.com | ||||
| //npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} | ||||
| @abearxiong:registry=https://npm.pkg.github.com | ||||
| //registry.npmjs.org/:_authToken=${NPM_TOKEN} | ||||
| @kevisual:registry=https://npm.xiongxiao.me | ||||
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| # page proxy | ||||
|  | ||||
| # 部署方案 | ||||
|  | ||||
| ```sh | ||||
| envision pack -p -u | ||||
| envision pack-deploy 330bc5f8-1ae7-4be5-a44c-0ea0b3da184b page-proxy # key和id是人设置的 | ||||
| # 会复制到对应的文件夹里面了,现在。启动时后台启动 | ||||
| # 需要调用类似,但需要token | ||||
| # token ev token会显示当前登陆的用户的token | ||||
| # https://kevisual.xiongxiao.me/api/router?path=local-apps&key=updateStatus&appKey=page-proxy&status=start&token=****** | ||||
| ``` | ||||
|  | ||||
|  | ||||
| @@ -1,10 +1,12 @@ | ||||
| { | ||||
|   port: 3005, | ||||
|   api: { | ||||
|     host: 'localhost:4002', // 后台代理 | ||||
|     path: '/api/router', | ||||
|   }, | ||||
|   allowedOrigins: ['localhost', 'xiongxiao.me', 'zxj.im'], | ||||
|   domain: 'kevisual.xiongxiao.me', | ||||
|   resources: 'minio.xiongxiao.me/resources', | ||||
|   proxy: { | ||||
|     port: 3005, | ||||
|     domain: 'kevisual.xiongxiao.me', | ||||
|     resources: 'https://minio.xiongxiao.me/resources', | ||||
|     allowedOrigins: ['localhost', 'xiongxiao.me', 'zxj.im', 'silkyai.cn'], | ||||
|   }, | ||||
| } | ||||
|   | ||||
							
								
								
									
										10
									
								
								app.config.json5.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app.config.json5.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| { | ||||
|   port: 3005, | ||||
|   api: { | ||||
|     host: 'localhost:3000', // 后台代理 | ||||
|     path: '/api/router', | ||||
|   }, | ||||
|   allowedOrigins: ['localhost', 'xiongxiao.me', 'zxj.im'], | ||||
|   domain: 'demo.kevisual.xiongxiao.me', | ||||
|   resources: 'localhost:9000/resources', | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								docs/after-pub-deploy.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/after-pub-deploy.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 51 KiB | 
							
								
								
									
										50
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,39 +1,49 @@ | ||||
| { | ||||
|   "name": "var-proxy", | ||||
|   "name": "page-proxy", | ||||
|   "version": "0.0.1", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
|   "type": "module", | ||||
|   "app": { | ||||
|     "key": "page-proxy", | ||||
|     "entry": "dist/app.mjs", | ||||
|     "type": "pm2-system-app", | ||||
|     "files": [ | ||||
|       "dist" | ||||
|     ] | ||||
|   }, | ||||
|   "files": [ | ||||
|     "dist" | ||||
|   ], | ||||
|   "scripts": { | ||||
|     "dev": "cross-env NODE_ENV=development nodemon --exec tsx src/index.ts", | ||||
|     "dev": "cross-env NODE_ENV=development nodemon --ignore upload --exec tsx src/index.ts", | ||||
|     "build": "rimraf dist && rollup -c", | ||||
|     "deploy": "rsync -avz dist/ light:~/apps/var-proxy/backend", | ||||
|     "reload": "ssh light pm2 restart proxy", | ||||
|     "pub": "npm run build && npm run deploy && npm run reload" | ||||
|     "start": "pm2 start dist/app.mjs --name page-proxy", | ||||
|     "release": "node ./scripts/release/index.mjs", | ||||
|     "deploy": "envision switch root && envision pack -p -u", | ||||
|     "pub": "npm run build && npm run deploy" | ||||
|   }, | ||||
|   "keywords": [], | ||||
|   "author": "", | ||||
|   "license": "ISC", | ||||
|   "devDependencies": { | ||||
|     "@rollup/plugin-commonjs": "^28.0.0", | ||||
|     "@rollup/plugin-commonjs": "^28.0.2", | ||||
|     "@rollup/plugin-json": "^6.1.0", | ||||
|     "@rollup/plugin-node-resolve": "^15.3.0", | ||||
|     "@rollup/plugin-typescript": "^12.1.0", | ||||
|     "@types/http-proxy": "^1.17.15", | ||||
|     "@types/node": "^22.7.5", | ||||
|     "@rollup/plugin-node-resolve": "^16.0.0", | ||||
|     "@rollup/plugin-typescript": "^12.1.2", | ||||
|     "@types/http-proxy": "^1.17.16", | ||||
|     "@types/node": "^22.13.4", | ||||
|     "cross-env": "^7.0.3", | ||||
|     "nodemon": "^3.1.7", | ||||
|     "rollup": "^4.24.0", | ||||
|     "ts-lib": "^0.0.5", | ||||
|     "tslib": "^2.7.0", | ||||
|     "typescript": "^5.6.3" | ||||
|     "nodemon": "^3.1.9", | ||||
|     "rollup": "^4.34.8", | ||||
|     "tslib": "^2.8.1", | ||||
|     "typescript": "^5.7.3" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@abearxiong/router": "0.0.1-alpha.43", | ||||
|     "@abearxiong/use-config": "^0.0.2", | ||||
|     "@abearxiong/use-file-store": "^0.0.1", | ||||
|     "ioredis": "^5.4.1", | ||||
|     "nanoid": "^5.0.7" | ||||
|     "@kevisual/router": "0.0.6-alpha-5", | ||||
|     "@kevisual/use-config": "^1.0.7", | ||||
|     "ioredis": "^5.5.0", | ||||
|     "nanoid": "^5.1.0" | ||||
|   }, | ||||
|   "resolutions": { | ||||
|     "picomatch": "^4.0.2" | ||||
|   | ||||
							
								
								
									
										8
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -14,7 +14,7 @@ importers: | ||||
|       '@abearxiong/router': | ||||
|         specifier: 0.0.1-alpha.43 | ||||
|         version: 0.0.1-alpha.43 | ||||
|       '@abearxiong/use-config': | ||||
|       '@kevisual/use-config': | ||||
|         specifier: ^0.0.2 | ||||
|         version: 0.0.2 | ||||
|       '@abearxiong/use-file-store': | ||||
| @@ -66,8 +66,8 @@ packages: | ||||
|   '@abearxiong/router@0.0.1-alpha.43': | ||||
|     resolution: {integrity: sha512-umwi4T5s54Zb8ItseGw3uB7PDG8BqnHyAughlXH2dhub4f49fO+rwR+Zth7scUONkmc21Z27/lPgLBHXrYOkYw==, tarball: https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.43/287c6e2597b36c5e3ed351b473e38f468b5f49ea} | ||||
|  | ||||
|   '@abearxiong/use-config@0.0.2': | ||||
|     resolution: {integrity: sha512-IBOmeP46ykbDlkplFS65UsAHjyPDKnvS2oqbkpLWhbSwDbF5zhBnD4ibsFZKPCyc3lMlPeRqYva4x6puX3E/qQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/use-config/0.0.2/59fbeec8c8e086ec48e55024fe39020b079e6fa5} | ||||
|   '@kevisual/use-config@0.0.2': | ||||
|     resolution: {integrity: sha512-IBOmeP46ykbDlkplFS65UsAHjyPDKnvS2oqbkpLWhbSwDbF5zhBnD4ibsFZKPCyc3lMlPeRqYva4x6puX3E/qQ==, tarball: https://npm.pkg.github.com/download/@kevisual/use-config/0.0.2/59fbeec8c8e086ec48e55024fe39020b079e6fa5} | ||||
|  | ||||
|   '@abearxiong/use-file-store@0.0.1': | ||||
|     resolution: {integrity: sha512-65ZQBHxwr76sAFG+Xd4IQstx8dERhkaX5MLqtqJ0f9m+2NnS/klNe0t4q9tgjMWAEWQxHjnPShpHWzkCENaDnQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/use-file-store/0.0.1/f171e398c078d4940c1ddedf5ad529d17b0eec32} | ||||
| @@ -830,7 +830,7 @@ snapshots: | ||||
|       - bufferutil | ||||
|       - utf-8-validate | ||||
|  | ||||
|   '@abearxiong/use-config@0.0.2': {} | ||||
|   '@kevisual/use-config@0.0.2': {} | ||||
|  | ||||
|   '@abearxiong/use-file-store@0.0.1(typescript@5.6.3)': | ||||
|     dependencies: | ||||
|   | ||||
							
								
								
									
										0
									
								
								release/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								release/.gitkeep
									
									
									
									
									
										Normal file
									
								
							| @@ -11,7 +11,7 @@ import json from '@rollup/plugin-json'; | ||||
| export default { | ||||
|   input: 'src/index.ts', // TypeScript 入口文件 | ||||
|   output: { | ||||
|     file: 'dist/app.js', // 输出文件 | ||||
|     file: 'dist/app.mjs', // 输出文件 | ||||
|     format: 'es', // 输出格式设置为 ES 模块 | ||||
|   }, | ||||
|   plugins: [ | ||||
| @@ -25,5 +25,5 @@ export default { | ||||
|       declaration: false, | ||||
|     }), // 使用 @rollup/plugin-typescript 处理 TypeScript 文件 | ||||
|   ], | ||||
|   // external: ['ws'], | ||||
|   external: ['ioredis', '@kevisual/router', '@kevisual/use-config'], | ||||
| }; | ||||
|   | ||||
							
								
								
									
										114
									
								
								scripts/release/index.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								scripts/release/index.mjs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import archiver from 'archiver'; | ||||
| import { exec } from 'child_process'; | ||||
| import { nanoid } from 'nanoid'; | ||||
|  | ||||
| const cwd = process.cwd(); | ||||
| const pkgPath = path.join(cwd, 'package.json'); | ||||
|  | ||||
| export const checkFileExistsSync = (filePath) => { | ||||
|   try { | ||||
|     // 使用 F_OK 检查文件或目录是否存在 | ||||
|     fs.accessSync(filePath, fs.constants.F_OK); | ||||
|     return true; | ||||
|   } catch (err) { | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | ||||
|  | ||||
| const releasePath = path.join(cwd, 'release'); | ||||
|  | ||||
| const distPath = path.join(cwd, 'dist'); | ||||
|  | ||||
| const zip = archiver('zip', { | ||||
|   zlib: { level: 9 }, | ||||
| }); | ||||
| const zipName = `page-proxy-${pkg.version}.zip`; | ||||
| const zipCache = path.join(releasePath, `page-proxy-${pkg.version}.zip`); | ||||
|  | ||||
| const getZip = async () => { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     const output = fs.createWriteStream(zipCache); | ||||
|     const startTime = (new Date().getTime() / 1000).toFixed(0); | ||||
|     // 监听事件 | ||||
|     output.on('close', async () => { | ||||
|       const bytes = zip.pointer(); | ||||
|       const size = bytes < 1024 ? `${bytes} bytes` : `${(bytes / 1024).toFixed(2)} KB`; | ||||
|       console.log(`Zip file has been created successfully. Total size: ${size} bytes.`); | ||||
|       let time = (new Date().getTime() / 1000).toFixed(0); | ||||
|       console.log('time', time - startTime); | ||||
|       resolve(); | ||||
|     }); | ||||
|  | ||||
|     output.on('end', () => { | ||||
|       console.log('Data has been drained.'); // 数据已被耗尽 | ||||
|       throw new CustomError('Data has been drained.'); | ||||
|     }); | ||||
|  | ||||
|     zip.on('warning', (err) => { | ||||
|       if (err.code === 'ENOENT') { | ||||
|         console.warn('File not found:', err); | ||||
|       } else { | ||||
|         throw err; | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     zip.on('error', (err) => { | ||||
|       throw err; | ||||
|     }); | ||||
|  | ||||
|     // 通过管道将 zip 数据流输出到指定文件 | ||||
|     zip.pipe(output); | ||||
|  | ||||
|     // 添加 sh 字符串作为文件到 zip 中 | ||||
|     const sh = `#!/bin/bash | ||||
|     npm i -g pnpm  | ||||
|     pnpm install --prod | ||||
|     `; | ||||
|     zip.append(sh, { name: 'start.sh' }); | ||||
|     // 把dist目录下的文件添加到zip中 | ||||
|     zip.directory(distPath, 'dist'); | ||||
|     // 把README.md添加到zip中 | ||||
|     zip.file(path.join(cwd, 'README.md'), { name: 'README.md' }); | ||||
|     // 把package.json添加到zip中 | ||||
|     zip.file(pkgPath, { name: 'package.json' }); | ||||
|     const ecosystemContent = `module.exports = { | ||||
|   apps: [ | ||||
|     { | ||||
|       name: 'page-proxy', // 应用名称 | ||||
|       script: './dist/app.mjs', // 入口文件 | ||||
|       // cwd: '.', // 设置当前工作目录 | ||||
|       output: './logs/page-proxy.log', | ||||
|       error: './logs/page-proxy.log', | ||||
|       log_date_format: 'YYYY-MM-DD HH:mm:ss', | ||||
|       // watch: true, // 自动监控文件变化 | ||||
|       watch: ['dist'], // 监控的文件夹 | ||||
|       ignore_watch: ['node_modules', 'logs'], // 忽略的文件夹 | ||||
|     } | ||||
|   ] | ||||
| } | ||||
| `; | ||||
|     zip.append(ecosystemContent, { name: 'ecosystem.config.cjs' }); | ||||
|     const json5Content = fs.readFileSync(path.join(cwd, 'app.config.json5.example'), 'utf8'); | ||||
|     // tokenSecret 是一个随机字符串,用于生成 token | ||||
|     const tokenSecret = 'XX' + nanoid(39); | ||||
|     json5Content.replace('<TOKEN_SECRET>', tokenSecret); | ||||
|     // tokenSecret | ||||
|     //  把app.config.json5.example添加到zip中 | ||||
|     // zip.file(path.join(cwd, 'app.config.json5.example'), { name: 'app.config.json5.example' }); | ||||
|     zip.append(json5Content, { name: 'app.config.json5.example' }); | ||||
|  | ||||
|     // 结束归档(必须调用,否则 zip 文件无法完成) | ||||
|     zip.finalize(); | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| getZip().then(() => { | ||||
|   console.log('zip success'); | ||||
|   console.log(`envision switchOrg system && envision  deploy ./release/${zipName} -v 1.0.0 -k page-proxy -y y -u`); | ||||
|  | ||||
|   console.log(`download zip: https://kevisual.xiongxiao.me/system/page-proxy/${zipName}`); | ||||
| }); | ||||
| @@ -1,4 +1,4 @@ | ||||
| import { App } from '@abearxiong/router'; | ||||
| import { App } from '@kevisual/router'; | ||||
|  | ||||
| export const app = new App({ | ||||
|   serverOptions: { | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import { handleRequest } from './module/index.ts'; | ||||
| import { useConfig } from '@abearxiong/use-config'; | ||||
| import { config } from './module/config.ts'; | ||||
| import { app } from './app.ts'; | ||||
| import './route/route.ts' | ||||
| const { port } = useConfig<{ port: number }>(); | ||||
| import './route/route.ts'; | ||||
| const port = config?.proxy?.port || 3005; | ||||
|  | ||||
| app | ||||
|   .route({ | ||||
|   | ||||
							
								
								
									
										33
									
								
								src/module/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/module/config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| import { useConfig } from '@kevisual/use-config'; | ||||
| import { useFileStore } from '@kevisual/use-config/file-store'; | ||||
| export const fileStore = useFileStore('proxy-upload'); | ||||
|  | ||||
| type ConfigType = { | ||||
|   api: { | ||||
|     /** | ||||
|      * API host address | ||||
|      */ | ||||
|     host: string; | ||||
|     path?: string; | ||||
|     port?: number; | ||||
|   }; | ||||
|   proxy: { | ||||
|     port?: number; | ||||
|     /** | ||||
|      * self domain kevisual.xiongxiao.me | ||||
|      */ | ||||
|     domain: string; | ||||
|     /** | ||||
|      * resources path | ||||
|      * https://minio.xiongxiao.me/resources | ||||
|      */ | ||||
|     resources: string; | ||||
|     /** | ||||
|      * allow origin xiongxiao.me zxj.im silkyai.cn | ||||
|      * 允许跨域访问的地址 | ||||
|      */ | ||||
|     allowOrigin: string[]; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export const config = useConfig<ConfigType>(); | ||||
| @@ -1,7 +1,6 @@ | ||||
| import path from 'path'; | ||||
| import { redis, subscriber } from './redis/redis.ts'; | ||||
| import { useFileStore } from '@abearxiong/use-file-store'; | ||||
| import { useConfig } from '@abearxiong/use-config'; | ||||
| import { config, fileStore } from '../module/config.ts'; | ||||
| import fs from 'fs'; | ||||
| import crypto from 'crypto'; | ||||
| import { nanoid } from 'nanoid'; | ||||
| @@ -10,8 +9,7 @@ import { promisify } from 'util'; | ||||
| import { fetchApp, fetchDomain, fetchTest } from './query/get-router.ts'; | ||||
| const pipelineAsync = promisify(pipeline); | ||||
|  | ||||
| const { resources, api } = useConfig<{ resources: string; api: { host: string; path: string } }>(); | ||||
| const fileStore = useFileStore('upload'); | ||||
| const { resources } = config?.proxy || { resources: 'https://minio.xiongxiao.me/resources' }; | ||||
| const status: { [key: string]: boolean } = {}; | ||||
| const demoData = { | ||||
|   user: 'root', | ||||
| @@ -255,7 +253,7 @@ export const downloadUserAppFiles = async (user: string, app: string, data: type | ||||
|     }; | ||||
|   } | ||||
|   if (data.type === 'oss') { | ||||
|     const serverPath = 'https://' + resources + '/'; | ||||
|     let serverPath = new URL(resources).href + '/'; | ||||
|     // server download file | ||||
|     for (let i = 0; i < files.length; i++) { | ||||
|       const file = files[i]; | ||||
|   | ||||
| @@ -1,35 +1,36 @@ | ||||
| import { getDNS, isLocalhost } from '@/utils/dns.ts'; | ||||
| import http from 'http'; | ||||
| import { UserApp } from './get-user-app.ts'; | ||||
| import { useFileStore } from '@abearxiong/use-file-store'; | ||||
| import { config, fileStore } from '../module/config.ts'; | ||||
| import path from 'path'; | ||||
| import fs from 'fs'; | ||||
| import { useConfig } from '@abearxiong/use-config'; | ||||
| import { redis } from './redis/redis.ts'; | ||||
| import { getContentType } from './get-content-type.ts'; | ||||
| import { sleep } from '@/utils/sleep.ts'; | ||||
| const { api, domain, allowedOrigins } = useConfig<{ | ||||
|   api: { | ||||
|     host: string; | ||||
|     port?: number; | ||||
|   }; | ||||
|   domain: string; | ||||
|   allowedOrigins: string[]; | ||||
| }>(); | ||||
|  | ||||
| const fileStore = useFileStore('upload'); | ||||
| const api = config?.api || { host: 'kevisual.xiongxiao.me', path: '/api/router' }; | ||||
| const domain = config?.proxy?.domain || 'kevisual.xiongxiao.me'; | ||||
| const allowedOrigins = config?.proxy?.allowOrigin || []; | ||||
|  | ||||
|  | ||||
| const noProxyUrl = ['/', '/favicon.ico']; | ||||
| export const handleRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => { | ||||
|   if (req.url === '/favicon.ico') { | ||||
|     res.writeHead(200, { 'Content-Type': 'text/html' }); | ||||
|     res.write('proxy no favicon.ico\n'); | ||||
|     return; | ||||
|   } | ||||
|   if (req.url.startsWith('/api/router')) { | ||||
|   if (req.url.startsWith('/api/proxy')) { | ||||
|     return; | ||||
|   } | ||||
|   if (req.url.startsWith('/api')) { | ||||
|     // 代理到 http://codeflow.xiongxiao.me/api | ||||
|     const _u = new URL(req.url, `http://${api.host}`); | ||||
|     // 设置代理请求的目标 URL 和请求头 | ||||
|     let header: any = {}; | ||||
|     if (req.headers?.['Authroization']) { | ||||
|       header.Authorization = req.headers?.['Authroization']; | ||||
|     if (req.headers?.['Authorization']) { | ||||
|       header.authorization = req.headers['Authorization']; | ||||
|     } else if (req.headers?.['authorization']) { | ||||
|       header.authorization = req.headers['authorization']; | ||||
|     } | ||||
|     if (req.headers?.['Content-Type']) { | ||||
|       header['Content-Type'] = req.headers?.['Content-Type']; | ||||
| @@ -63,9 +64,6 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR | ||||
|     req.pipe(proxyReq, { end: true }); | ||||
|     return; | ||||
|   } | ||||
|   if (req.url.startsWith('/api/proxy')) { | ||||
|     return; | ||||
|   } | ||||
|   if (req.url.startsWith('/api')) { | ||||
|     res.end('not catch api'); | ||||
|     return; | ||||
| @@ -112,8 +110,10 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR | ||||
|       app = data.app; | ||||
|     } | ||||
|   } | ||||
|   const url = req.url; | ||||
|   if (!domainApp && noProxyUrl.includes(req.url)) { | ||||
|   // const url = req.url; | ||||
|   const pathname = new URL(req.url, `http://${dns.hostName}`).pathname; | ||||
|   const url = pathname; | ||||
|   if (!domainApp && noProxyUrl.includes(url)) { | ||||
|     res.write('No proxy for this URL\n'); | ||||
|     return res.end(); | ||||
|   } | ||||
|   | ||||
| @@ -1,11 +1,6 @@ | ||||
| import { useConfig } from '@abearxiong/use-config'; | ||||
|  | ||||
| const { resources, api } = useConfig<{ | ||||
|   resources: string; | ||||
|   api: { host: string; path: string }; | ||||
|   ƒ; | ||||
| }>(); | ||||
| import { config } from '../config.ts'; | ||||
|  | ||||
| const api = config?.api || { host: 'kevisual.xiongxiao.me', path: '/api/router' }; | ||||
| const apiPath = api.path || '/api/router'; | ||||
| export const fetchTest = async (id: string) => { | ||||
|   const fetchUrl = 'http://' + api.host + apiPath; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { Redis } from 'ioredis'; | ||||
| import { useConfig } from '@abearxiong/use-config'; | ||||
| import { useConfig } from '@kevisual/use-config'; | ||||
|  | ||||
| const config = useConfig<{ | ||||
|   redis: ConstructorParameters<typeof Redis>; | ||||
|   | ||||
| @@ -1,10 +1,8 @@ | ||||
| import { UserApp } from '@/module/get-user-app.ts'; | ||||
| import { app } from '../../app.ts'; | ||||
| import { redis } from '@/module/redis/redis.ts'; | ||||
| import { CustomError } from '@abearxiong/router'; | ||||
| import fs from 'fs'; | ||||
| import { useFileStore } from '@abearxiong/use-file-store'; | ||||
| const fileStore = useFileStore('upload'); | ||||
| import { fileStore } from '../../module/config.ts'; | ||||
|  | ||||
| app | ||||
|   .route({ | ||||
| @@ -34,7 +32,7 @@ app | ||||
|       await userApp.clearCacheData(); | ||||
|     } catch (error) { | ||||
|       console.error(error); | ||||
|       throw new CustomError('删除失败'); | ||||
|       ctx.throw('删除失败'); | ||||
|     } | ||||
|     ctx.body = 'successfully'; | ||||
|   }) | ||||
| @@ -83,16 +81,16 @@ app | ||||
|     const { user, app } = ctx.query.data || {}; | ||||
|     if (!user || !app) { | ||||
|       if (!user) { | ||||
|         throw new CustomError('user is required'); | ||||
|         ctx.throw('user is required'); | ||||
|       } | ||||
|       if (!app) { | ||||
|         throw new CustomError('app is required'); | ||||
|         ctx.throw('app is required'); | ||||
|       } | ||||
|     } | ||||
|     const userApp = new UserApp({ user, app }); | ||||
|     const cache = await userApp.getCache(); | ||||
|     if (!cache) { | ||||
|       throw new CustomError('Not Found App'); | ||||
|       ctx.throw('Not Found App'); | ||||
|     } | ||||
|     ctx.body = cache; | ||||
|   }) | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| import { UserApp, clearAllUserApp } from '../module/get-user-app.ts'; | ||||
| import { redis } from '../module/redis/redis.ts'; | ||||
| import path from 'path'; | ||||
| import { useFileStore } from '@abearxiong/use-file-store'; | ||||
| const filePath = useFileStore('upload'); | ||||
| import { config, fileStore } from '../module/config.ts'; | ||||
|  | ||||
| const main = async () => { | ||||
|   const userApp = new UserApp({ user: 'root', app: 'codeflow' }); | ||||
| @@ -33,7 +32,6 @@ const clearData = async () => { | ||||
| // clearData(); | ||||
| // clearAllUserApp(); | ||||
|  | ||||
|  | ||||
| const expireData = async () => { | ||||
|   await redis.set('user:app:exist:' + 'codeflow:root', 'value', 'EX', 2); | ||||
|   process.exit(0); | ||||
| @@ -45,5 +43,5 @@ const keysData = async () => { | ||||
|   const keys = await redis.keys('user:app:exist:*'); | ||||
|   console.log('keys', keys); | ||||
|   process.exit(0); | ||||
| } | ||||
| keysData(); | ||||
| }; | ||||
| keysData(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user