UNPKG

@daiyu-5577/quickbuild

Version:

front-end build service

245 lines (244 loc) 10.7 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import dayjs from "dayjs"; import { Buffer } from "node:buffer"; import { formatMsg } from "../commandBuild/type.js"; import { decrypt } from '../../utils/crypto.js'; import { generateUid } from '../../database/index.js'; import logger from "../../utils/log.js"; import { getWriteStream } from "../../utils/fileLog.js"; import { catchImagePath } from '../config.js'; import { baseRoute } from '../config.js'; import { updateDatabaseFile } from '../../database/index.js'; import { getFromatTime } from '../../utils/time.js'; import { IdType } from '../commandBuild/type.js'; const __dirname = new URL('.', import.meta.url).pathname; const getCommondMsg = (data) => { return Object.assign(Object.assign({ socketId: '', msg: '', ctxType: 'ctx:txt' }, data), { id: generateUid(IdType.M), name: '系统消息', time: getFromatTime(), timestamp: +dayjs() }); }; export const commands = [ { command: '/getAllCommand', desc: '查询所有命令', fn(buildServer, socket) { const { io } = buildServer; const list = commands.map(v => { return { command: v.command, desc: v.desc }; }); socket.emit('on:msg-chat', formatMsg('on:msg-chat', getCommondMsg({ msg: JSON.stringify(list, null, 2) }))); } }, { command: '/getAllTask', desc: '查询任务队列', fn(buildServer, socket) { const { io, builder } = buildServer; const buildTasks = builder.buildTasks; socket.emit('on:msg-chat', formatMsg('on:msg-chat', getCommondMsg({ msg: !!buildTasks.length ? JSON.stringify(buildTasks, null, 2) : '暂无任务队列', }))); } }, { command: '/getCurTask', desc: '查询当前执行任务', fn(buildServer, socket) { const { io, builder } = buildServer; const curTask = builder.curTask; socket.emit('on:msg-chat', formatMsg('on:msg-chat', getCommondMsg({ msg: !!curTask ? JSON.stringify(curTask, null, 2) : '当前暂无任务执行', }))); } }, { command: '/getAllPackage', desc: '查询当前可构建目录', fn(buildServer, socket) { const { io, builder } = buildServer; const packages = builder.packages; socket.emit('on:msg-chat', formatMsg('on:msg-chat', getCommondMsg({ msg: !!packages.length ? JSON.stringify(packages, null, 2) : '当前暂无可构建目录', }))); } }, ]; class Websocket { constructor() { this.buildServer = null; this.chatMsgCache = new Set(); this.buildMsgCatch = new Set(); this.socketSet = new Set(); } use(inst) { this.buildServer = inst; return this; } start() { const buildServer = this.buildServer; const { io, database } = buildServer; const chatTable = database.get('message_chat') || new Set(); const buildTable = database.get('message_build') || new Set(); for (const v of chatTable) { this.chatMsgCache.add(v); } for (const v of buildTable) { this.buildMsgCatch.add(v); } io.use((socket, next) => { const { database } = buildServer; const token = socket.handshake.auth.token; if (!token) { return next(new Error('invalid token')); } decrypt(token) .then(txt => { const { id, name, time } = JSON.parse(txt); const table_user = database.get('user'); const curUser = table_user.find(v => v.id === id); if (!curUser) { return next(new Error('invalid token')); } if (curUser.name !== name) { return next(new Error('invalid token')); } if (+dayjs() - time > 1000 * 60 * 60 * 24 * 7) { return next(new Error('invalid token')); } socket.data.user = curUser; this.socketSet.add(socket); }) .catch(err => { return next(new Error('invalid token')); }) .finally(() => { next(); }); }); io.on('connection', (socket) => { const lastChatId = socket.handshake.auth.lastChatId; const lastBuildId = socket.handshake.auth.lastBuildId; if (!!lastChatId) { const curMsgIndex = [...this.chatMsgCache].findIndex(v => v.id == lastChatId); if (curMsgIndex != -1) { socket.emit('on:msg-getAllChat', [...this.chatMsgCache].splice(curMsgIndex + 1)); } } else { socket.emit('on:msg-getAllChat', [...this.chatMsgCache]); } if (!!lastBuildId) { const curBuildMsgIndex = [...this.buildMsgCatch].findIndex(v => v.id == lastBuildId); if (curBuildMsgIndex != -1) { socket.emit('on:msg-getAllBuild', [...this.buildMsgCatch].splice(curBuildMsgIndex + 1)); } } else { socket.emit('on:msg-getAllBuild', [...this.buildMsgCatch]); } socket.onAny((event, data, ...args) => { var _a; let _data = data; if ((data === null || data === void 0 ? void 0 : data.ctxType) === 'ctx:imgs' && ((_a = data === null || data === void 0 ? void 0 : data.files) === null || _a === void 0 ? void 0 : _a.length)) { try { const files = data.files || []; _data = Object.assign(Object.assign({}, data), { files: files.map((v) => ({ name: v.name, size: v.size, type: v.type, })) }); } catch (error) { console.log(error); } } logger.log({ level: 'socket', message: `OnEvent: ${event}`, user: { name: socket.data.user.name, id: socket.data.user.id }, data: _data, args }); }); socket.on('disconnect', () => { this.socketSet.delete(socket); }); socket.on('on:msg-chat', (data) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d; const curCommand = commands.find(v => v.command === (data === null || data === void 0 ? void 0 : data.msg)); if (!!curCommand) { curCommand.fn(buildServer, socket); return; } if ((data === null || data === void 0 ? void 0 : data.ctxType) === 'ctx:imgs') { try { const files = data.files; const filePaths = []; if (!(files === null || files === void 0 ? void 0 : files.length)) return; for (const item of files) { if (!Buffer.isBuffer(item.file)) continue; const { writeStream, localFileName } = yield getWriteStream(catchImagePath, item.name); writeStream.end(item.file); filePaths.push(`${baseRoute}/api/showLog?type=image&name=${localFileName}`); } data.files = filePaths; } catch (error) { console.log(error); return; } } this.sendMsg('on:msg-chat', formatMsg('on:msg-chat', Object.assign(Object.assign({ id: generateUid(IdType.M), userId: ((_b = (_a = socket.data) === null || _a === void 0 ? void 0 : _a.user) === null || _b === void 0 ? void 0 : _b.id) || '', socketId: socket.id, name: ((_d = (_c = socket.data) === null || _c === void 0 ? void 0 : _c.user) === null || _d === void 0 ? void 0 : _d.name) || '匿名用户' }, data), { time: getFromatTime(), timestamp: +dayjs() }))); })); socket.on('disconnect', () => { }); }); } sendMsg(type, data) { clearTimeout(Websocket.catchTimer); const buildServer = this.buildServer; const { io, database } = buildServer; if (type == 'on:msg-chat') { const _data = data; this.chatMsgCache.add(_data); if (this.chatMsgCache.size > 100) { this.chatMsgCache = new Set([...this.chatMsgCache].slice(-100)); } } if (type == 'on:msg-build') { const _data = data; const curMsg = [...this.buildMsgCatch].find(v => v.taskId == _data.taskId); if (!!curMsg) { curMsg.msg = curMsg.msg + _data.msg; curMsg.status = _data.status; } else { this.buildMsgCatch.add(data); } if (this.buildMsgCatch.size > 10) { this.buildMsgCatch = new Set([...this.buildMsgCatch].slice(-10)); } } Websocket.catchTimer = setTimeout(() => { updateDatabaseFile('message_chat', [...this.chatMsgCache]); updateDatabaseFile('message_build', [...this.buildMsgCatch]); }, 10000); io.emit(type, data); } } export default new Websocket;