const express = require('express'); const cors = require('cors'); const cookieParser = require('cookie-parser'); const http = require('http'); const config = require('./config'); const app = express(); const server = http.createServer(app); // ─── 中间件 ─── app.use(cors(config.cors)); app.use(cookieParser()); // 控制字符净化:Agent 通过 curl 发送的 JSON body 可能含原始换行符导致解析失败 app.use((req, res, next) => { if (req.headers['content-type']?.includes('application/json')) { let rawBody = ''; req.on('data', chunk => rawBody += chunk); req.on('end', () => { if (!rawBody) return next(); try { req.body = JSON.parse(rawBody); req._bodyParsed = true; next(); } catch (e) { try { // eslint-disable-next-line no-control-regex const cleaned = rawBody.replace(/[\x00-\x1F\x7F]/g, (ch) => { if (ch === '\n') return '\\n'; if (ch === '\r') return '\\r'; if (ch === '\t') return '\\t'; return ''; }); req.body = JSON.parse(cleaned); req._bodyParsed = true; next(); } catch (e2) { res.status(400).json({ error: 'Invalid JSON: ' + e2.message }); } } }); } else { next(); } }); app.use((req, res, next) => { if (req._bodyParsed) return next(); express.json()(req, res, next); }); app.use((err, req, res, next) => { if (err instanceof SyntaxError && err['status'] === 400 && 'body' in err) { return res.status(400).json({ error: 'Invalid JSON', details: err.message }); } next(err); }); // ─── API 路由 ─── app.use('/api/config', require('./routes/config')); app.use('/api/master', require('./routes/master-chat')); // ─── 系统端点 ─── app.get('/api/health', (req, res) => res.json({ status: 'ok', timestamp: new Date().toISOString(), })); app.use((err, req, res, next) => { console.error('Server error:', err); res.status(500).json({ error: err.message }); }); // ─── 启动 ─── async function start() { try { const host = config.host || '0.0.0.0'; server.listen(Number(config.port), host, () => { console.log(`✅ LemonACP 启动: http://${host}:${config.port}`); }); } catch (error) { console.error('Failed to start server:', error); process.exit(1); } } process.on('SIGTERM', () => { console.log('\n正在关闭...'); process.exit(0); }); process.on('SIGINT', () => { console.log('\n正在关闭...'); process.exit(0); }); start(); module.exports = app;