import { program as app, Command } from '@/program.ts'; import glob from 'fast-glob'; import path from 'path'; import fs from 'fs'; import FormData from 'form-data'; import { getBaseURL, query } from '@/module/query.ts'; import { getConfig } from '@/module/index.ts'; import inquirer from 'inquirer'; import { packLib, unpackLib } from './publish.ts'; import chalk from 'chalk'; import { installDeps } from '@/uitls/npm.ts'; const command = new Command('deploy') .description('把前端文件传到服务器') .argument('', 'Path to the file to be uploaded') // 定义文件路径参数 .option('-v, --version ', 'verbose') .option('-k, --key ', 'key') .option('-y, --yes ', 'yes') .action(async (filePath, options) => { try { let { version, key, yes } = options; if (!version || !key) { const answers = await inquirer.prompt([ { type: 'input', name: 'version', message: 'Enter your version:', when: () => !version, }, { type: 'input', name: 'key', message: 'Enter your key:', when: () => !key, }, ]); version = answers.version || version; key = answers.key || key; } const pwd = process.cwd(); const directory = path.join(pwd, filePath); const gPath = path.join(directory, '**/*'); const files = await glob(gPath, { cwd: pwd, ignore: ['node_modules/**/*'], onlyFiles: true }); const _relativeFiles = files.map((file) => path.relative(directory, file)); console.log('upload Files', _relativeFiles); console.log('upload Files Key', key, version); if (!yes) { // 确认是否上传 const confirm = await inquirer.prompt([ { type: 'confirm', name: 'confirm', message: 'Do you want to upload these files?', }, ]); if (!confirm.confirm) { return; } } const res = await uploadFiles(_relativeFiles, directory, { key, version }); if (res?.code === 200) { console.log('File uploaded successfully!'); res.data?.data?.files?.map?.((d) => { console.log('uploaded file', d?.name, d?.path); }); } else { console.error('File upload failed', res?.message); } } catch (error) { console.error('error', error); } }); const uploadFiles = async (files: string[], directory: string, { key, version }: { key: string; version: string }): Promise => { const config = await getConfig(); const form = new FormData(); for (const file of files) { const filePath = path.join(directory, file); form.append('file', fs.createReadStream(filePath), { filename: file, filepath: file, }); } form.append('appKey', key); form.append('version', version); return new Promise((resolve) => { const _baseURL = getBaseURL(); const url = new URL(_baseURL); console.log('upload url', url.hostname, url.protocol, url.port); form.submit( { path: '/api/app/upload', host: url.hostname, protocol: url.protocol as any, port: url.port, method: 'POST', headers: { Authorization: 'Bearer ' + config.token, ...form.getHeaders(), }, }, (err, res) => { if (err) { console.error('Error uploading file:', err.message); return; } // 处理服务器响应 let body = ''; res.on('data', (chunk) => { body += chunk; }); res.on('end', () => { try { const res = JSON.parse(body); resolve(res); } catch (e) { resolve({ code: 500, message: body }); } }); }, ); }); }; app.addCommand(command); const local = new Command('local') .description('本地部署') .argument('', 'key') .option('-i, --ignore', '使用 .npmignore 文件模式去忽略文件进行打包, 不需要package.json中的files字段') .option('-u, --update', 'query查询 127.0.0.1:11015/api/router?path=local-apps&key=detect') .action(async (key, opts) => { console.log('local deploy'); const { outputFilePath } = await packLib(opts?.ignore); const mainAppPath = getConfig().mainAppPath; const appsPath = getConfig().appsPath || path.join(mainAppPath, 'apps'); if (!key) { console.error(chalk.red('key is required')); return; } const appPath = path.join(appsPath, key); if (!fs.existsSync(appPath)) { fs.mkdirSync(appPath, { recursive: true }); } // 复制应用到apps目录下 if (outputFilePath) { await unpackLib(outputFilePath, appPath); fs.unlinkSync(outputFilePath); installDeps({ appPath }); if (opts?.update) { const res = await query.post( { path: 'local-apps', key: 'detect' }, { url: `http://127.0.0.1:11015/api/router?path=local-apps&key=detect`, }, ); if (res.code === 200) { console.log('local deploy success'); } else { console.error('local deploy failed', res.message); } } } }); app.addCommand(local);