做适配
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -6,3 +6,6 @@ coverage | |||||||
| upload | upload | ||||||
|  |  | ||||||
| app.config.json5 | app.config.json5 | ||||||
|  |  | ||||||
|  | release/* | ||||||
|  | !release/.gitkeep | ||||||
							
								
								
									
										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', | ||||||
|  | } | ||||||
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								package.json
									
									
									
									
									
								
							| @@ -20,29 +20,32 @@ | |||||||
|     "build": "rimraf dist && rollup -c", |     "build": "rimraf dist && rollup -c", | ||||||
|     "deploy": "rsync -avz dist/ light:~/apps/var-proxy/backend", |     "deploy": "rsync -avz dist/ light:~/apps/var-proxy/backend", | ||||||
|     "reload": "ssh light pm2 restart proxy", |     "reload": "ssh light pm2 restart proxy", | ||||||
|     "pub": "npm run build && npm run deploy && npm run reload" |     "pub": "npm run build && npm run deploy && npm run reload", | ||||||
|  |     "demo": "rsync -avz dist/ on:~/docker/page-proxy/dist", | ||||||
|  |     "start": "pm2 start dist/app.mjs --name page-proxy", | ||||||
|  |     "release": "node ./scripts/release/index.mjs" | ||||||
|   }, |   }, | ||||||
|   "keywords": [], |   "keywords": [], | ||||||
|   "author": "", |   "author": "", | ||||||
|   "license": "ISC", |   "license": "ISC", | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@rollup/plugin-commonjs": "^28.0.1", |     "@rollup/plugin-commonjs": "^28.0.2", | ||||||
|     "@rollup/plugin-json": "^6.1.0", |     "@rollup/plugin-json": "^6.1.0", | ||||||
|     "@rollup/plugin-node-resolve": "^15.3.0", |     "@rollup/plugin-node-resolve": "^16.0.0", | ||||||
|     "@rollup/plugin-typescript": "^12.1.1", |     "@rollup/plugin-typescript": "^12.1.2", | ||||||
|     "@types/http-proxy": "^1.17.15", |     "@types/http-proxy": "^1.17.16", | ||||||
|     "@types/node": "^22.10.1", |     "@types/node": "^22.13.4", | ||||||
|     "cross-env": "^7.0.3", |     "cross-env": "^7.0.3", | ||||||
|     "nodemon": "^3.1.7", |     "nodemon": "^3.1.9", | ||||||
|     "rollup": "^4.28.1", |     "rollup": "^4.34.8", | ||||||
|     "tslib": "^2.8.1", |     "tslib": "^2.8.1", | ||||||
|     "typescript": "^5.7.2" |     "typescript": "^5.7.3" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@kevisual/router": "0.0.6-alpha-2", |     "@kevisual/router": "0.0.6-alpha-5", | ||||||
|     "@kevisual/use-config": "^1.0.7", |     "@kevisual/use-config": "^1.0.7", | ||||||
|     "ioredis": "^5.4.1", |     "ioredis": "^5.5.0", | ||||||
|     "nanoid": "^5.0.9" |     "nanoid": "^5.1.0" | ||||||
|   }, |   }, | ||||||
|   "resolutions": { |   "resolutions": { | ||||||
|     "picomatch": "^4.0.2" |     "picomatch": "^4.0.2" | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								release/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								release/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										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}`); | ||||||
|  | }); | ||||||
| @@ -255,7 +255,10 @@ export const downloadUserAppFiles = async (user: string, app: string, data: type | |||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
|   if (data.type === 'oss') { |   if (data.type === 'oss') { | ||||||
|     const serverPath = 'https://' + resources + '/'; |     let serverPath = 'https://' + resources + '/'; | ||||||
|  |     if(resources.includes('localhost')) { | ||||||
|  |       serverPath = 'http://' + resources + '/'; | ||||||
|  |     } | ||||||
|     // server download file |     // server download file | ||||||
|     for (let i = 0; i < files.length; i++) { |     for (let i = 0; i < files.length; i++) { | ||||||
|       const file = files[i]; |       const file = files[i]; | ||||||
|   | |||||||
| @@ -24,13 +24,18 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR | |||||||
|     res.write('proxy no favicon.ico\n'); |     res.write('proxy no favicon.ico\n'); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (req.url.startsWith('/api/router')) { |   if (req.url.startsWith('/api/proxy')) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if (req.url.startsWith('/api')) { | ||||||
|     // 代理到 http://codeflow.xiongxiao.me/api |     // 代理到 http://codeflow.xiongxiao.me/api | ||||||
|     const _u = new URL(req.url, `http://${api.host}`); |     const _u = new URL(req.url, `http://${api.host}`); | ||||||
|     // 设置代理请求的目标 URL 和请求头 |     // 设置代理请求的目标 URL 和请求头 | ||||||
|     let header: any = {}; |     let header: any = {}; | ||||||
|     if (req.headers?.['Authroization']) { |     if (req.headers?.['Authorization']) { | ||||||
|       header.Authorization = req.headers?.['Authroization']; |       header.authorization = req.headers['Authorization']; | ||||||
|  |     } else if(req.headers?.['authorization']) { | ||||||
|  |       header.authorization = req.headers['authorization']; | ||||||
|     } |     } | ||||||
|     if (req.headers?.['Content-Type']) { |     if (req.headers?.['Content-Type']) { | ||||||
|       header['Content-Type'] = req.headers?.['Content-Type']; |       header['Content-Type'] = req.headers?.['Content-Type']; | ||||||
| @@ -64,9 +69,6 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR | |||||||
|     req.pipe(proxyReq, { end: true }); |     req.pipe(proxyReq, { end: true }); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (req.url.startsWith('/api/proxy')) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   if (req.url.startsWith('/api')) { |   if (req.url.startsWith('/api')) { | ||||||
|     res.end('not catch api'); |     res.end('not catch api'); | ||||||
|     return; |     return; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user