mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-01-03 00:19:05 +08:00
* feat: pnpm new * Refactor build and release workflows, update dependencies Switch build scripts and workflows from npm to pnpm, update build and artifact paths, and simplify release workflow by removing version detection and changelog steps. Add new dependencies (silk-wasm, express, ws, node-pty-prebuilt-multiarch), update exports in package.json files, and add vite config for napcat-framework. Also, rename manifest.json for framework package and fix static asset copying in shell build config.
81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import type { RequestHandler } from 'express';
|
||
import { sendError, sendSuccess } from '../utils/response';
|
||
import { logSubscription } from 'napcat-common/src/log';
|
||
import { terminalManager } from '../terminal/terminal_manager';
|
||
import { WebUiConfig } from '@/napcat-webui-backend/index';
|
||
// 判断是否是 macos
|
||
const isMacOS = process.platform === 'darwin';
|
||
|
||
// 日志脱敏函数
|
||
const sanitizeLog = (log: string): string => {
|
||
// 脱敏 token 参数,将 token=xxx 替换为 token=***
|
||
return log.replace(/token=[\w\d]+/gi, 'token=***');
|
||
};
|
||
// 日志记录
|
||
export const LogHandler: RequestHandler = async (req, res) => {
|
||
const filename = req.query['id'];
|
||
if (!filename || typeof filename !== 'string') {
|
||
return sendError(res, 'ID不能为空');
|
||
}
|
||
|
||
if (filename.includes('..')) {
|
||
return sendError(res, 'ID不合法');
|
||
}
|
||
const logContent = await WebUiConfig.GetLogContent(filename);
|
||
const sanitizedLogContent = sanitizeLog(logContent);
|
||
return sendSuccess(res, sanitizedLogContent);
|
||
};
|
||
|
||
// 日志列表
|
||
export const LogListHandler: RequestHandler = async (_, res) => {
|
||
const logList = await WebUiConfig.GetLogsList();
|
||
return sendSuccess(res, logList);
|
||
};
|
||
|
||
// 实时日志(SSE)
|
||
export const LogRealTimeHandler: RequestHandler = async (req, res) => {
|
||
res.setHeader('Content-Type', 'text/event-stream');
|
||
res.setHeader('Connection', 'keep-alive');
|
||
const listener = (log: string) => {
|
||
try {
|
||
const sanitizedLog = sanitizeLog(log);
|
||
res.write(`data: ${sanitizedLog}\n\n`);
|
||
} catch (error) {
|
||
console.error('向客户端写入日志数据时出错:', error);
|
||
}
|
||
};
|
||
logSubscription.subscribe(listener);
|
||
req.on('close', () => {
|
||
logSubscription.unsubscribe(listener);
|
||
});
|
||
};
|
||
|
||
// 终端相关处理器
|
||
export const CreateTerminalHandler: RequestHandler = async (req, res) => {
|
||
if (isMacOS) {
|
||
return sendError(res, 'MacOS不支持终端');
|
||
}
|
||
try {
|
||
const { cols, rows } = req.body;
|
||
const { id } = terminalManager.createTerminal(cols, rows);
|
||
return sendSuccess(res, { id });
|
||
} catch (error) {
|
||
console.error('Failed to create terminal:', error);
|
||
return sendError(res, '创建终端失败');
|
||
}
|
||
};
|
||
|
||
export const GetTerminalListHandler: RequestHandler = (_, res) => {
|
||
const list = terminalManager.getTerminalList();
|
||
return sendSuccess(res, list);
|
||
};
|
||
|
||
export const CloseTerminalHandler: RequestHandler = (req, res) => {
|
||
const id = req.params['id'];
|
||
if (!id) {
|
||
return sendError(res, 'ID不能为空');
|
||
}
|
||
terminalManager.closeTerminal(id);
|
||
return sendSuccess(res, {});
|
||
};
|