@daiyu-5577/buildsystem 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +485 -0
  2. package/dist/artifact.js +59 -0
  3. package/dist/artifact.js.map +1 -0
  4. package/dist/cli.js +25 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/build.js +39 -0
  7. package/dist/commands/build.js.map +1 -0
  8. package/dist/commands/server.js +28 -0
  9. package/dist/commands/server.js.map +1 -0
  10. package/dist/config.js +42 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/cron.js +163 -0
  13. package/dist/cron.js.map +1 -0
  14. package/dist/crypto.js +40 -0
  15. package/dist/crypto.js.map +1 -0
  16. package/dist/custError.js +10 -0
  17. package/dist/custError.js.map +1 -0
  18. package/dist/database/index.js +64 -0
  19. package/dist/database/index.js.map +1 -0
  20. package/dist/database/types.js +8 -0
  21. package/dist/database/types.js.map +1 -0
  22. package/dist/fsHelpers.js +93 -0
  23. package/dist/fsHelpers.js.map +1 -0
  24. package/dist/git.js +67 -0
  25. package/dist/git.js.map +1 -0
  26. package/dist/logger.js +80 -0
  27. package/dist/logger.js.map +1 -0
  28. package/dist/notifier.js +66 -0
  29. package/dist/notifier.js.map +1 -0
  30. package/dist/pm.js +21 -0
  31. package/dist/pm.js.map +1 -0
  32. package/dist/queue.js +273 -0
  33. package/dist/queue.js.map +1 -0
  34. package/dist/server/index.js +189 -0
  35. package/dist/server/index.js.map +1 -0
  36. package/dist/server/routes.js +395 -0
  37. package/dist/server/routes.js.map +1 -0
  38. package/dist/server/websocket.js +230 -0
  39. package/dist/server/websocket.js.map +1 -0
  40. package/dist/static/web/assets/index-BzSDdMyu.js +304 -0
  41. package/dist/static/web/assets/index-DptBjpyJ.css +1 -0
  42. package/dist/static/web/index.html +13 -0
  43. package/dist/types.js +33 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/utils.js +66 -0
  46. package/dist/utils.js.map +1 -0
  47. package/dist/web/assets/index-Ds-OtVY9.js +76 -0
  48. package/dist/web/assets/index-F5jE8yX9.css +1 -0
  49. package/dist/web/index.html +13 -0
  50. package/package.json +61 -0
package/dist/config.js ADDED
@@ -0,0 +1,42 @@
1
+ var _a, _b, _c, _d, _e;
2
+ /**
3
+ * 集中配置中心 – 统一读取环境变量并提供默认路径
4
+ */
5
+ import path from 'node:path';
6
+ import fs from 'node:fs';
7
+ /** nginx location 反向代理前缀 */
8
+ export let baseRoute = (_a = process.env.BASE_ROUTE) !== null && _a !== void 0 ? _a : '';
9
+ /** 缓存根目录 */
10
+ export const catchRootPath = path.resolve(process.cwd(), (_b = process.env.CATCH_ROOT) !== null && _b !== void 0 ? _b : '.buildsystemCatch');
11
+ /** 所有项目构建 dist 目录 */
12
+ export const webDistPath = path.resolve(process.cwd(), (_c = process.env.DIST_ROOT) !== null && _c !== void 0 ? _c : 'dist');
13
+ /** dist 回滚缓存目录 */
14
+ export const catchWebDistPath = path.resolve(catchRootPath, 'webBackup');
15
+ /** database 缓存目录 */
16
+ export const catchDatabasePath = path.resolve(catchRootPath, 'database');
17
+ /** http log 缓存目录 */
18
+ export const catchHttpLogPath = path.resolve(catchRootPath, 'log');
19
+ /** build log 缓存目录 */
20
+ export const catchBuildLogPath = path.resolve(catchRootPath, 'buildLog');
21
+ /** image 缓存目录 */
22
+ export const catchImagePath = path.resolve(catchRootPath, 'images');
23
+ /** 最大并发构建数 */
24
+ export const maxConcurrency = Number(process.env.MAX_CONCURRENCY) || 2;
25
+ /** 加密 salt/secret(生产环境应通过环境变量设置) */
26
+ export const cryptoSalt = (_d = process.env.CRYPTO_SALT) !== null && _d !== void 0 ? _d : 'salt_daiyu5577';
27
+ export const cryptoSecret = (_e = process.env.CRYPTO_SECRET) !== null && _e !== void 0 ? _e : 'secret_daiyu5577';
28
+ // 确保缓存目录存在
29
+ const ensureDirs = [
30
+ catchRootPath,
31
+ catchWebDistPath,
32
+ catchDatabasePath,
33
+ catchHttpLogPath,
34
+ catchBuildLogPath,
35
+ catchImagePath,
36
+ ];
37
+ for (const dir of ensureDirs) {
38
+ if (!fs.existsSync(dir)) {
39
+ fs.mkdirSync(dir, { recursive: true });
40
+ }
41
+ }
42
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,SAAS,CAAA;AAExB,4BAA4B;AAC5B,MAAM,CAAC,IAAI,SAAS,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,UAAU,mCAAI,EAAE,CAAA;AAEnD,YAAY;AACZ,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAA,OAAO,CAAC,GAAG,CAAC,UAAU,mCAAI,mBAAmB,CAAC,CAAA;AAEvG,qBAAqB;AACrB,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAA,OAAO,CAAC,GAAG,CAAC,SAAS,mCAAI,MAAM,CAAC,CAAA;AAEvF,kBAAkB;AAClB,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;AAExE,oBAAoB;AACpB,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;AAExE,oBAAoB;AACpB,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;AAElE,qBAAqB;AACrB,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;AAExE,iBAAiB;AACjB,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;AAEnE,cAAc;AACd,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;AAEtE,oCAAoC;AACpC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,WAAW,mCAAI,gBAAgB,CAAA;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,aAAa,mCAAI,kBAAkB,CAAA;AAE3E,WAAW;AACX,MAAM,UAAU,GAAG;IACjB,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;IACjB,cAAc;CACf,CAAA;AACD,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;AACH,CAAC"}
package/dist/cron.js ADDED
@@ -0,0 +1,163 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ /**
11
+ * Cron 定时任务
12
+ */
13
+ import { CronJob } from 'cron';
14
+ import path from 'node:path';
15
+ import axios from 'axios';
16
+ import dayjs from 'dayjs';
17
+ import { autoClearFiles, getWriteStream } from './fsHelpers.js';
18
+ import { websocketHandler } from './server/websocket.js';
19
+ import { formatMsg, IdType } from './types.js';
20
+ import { getFormatTime } from './utils.js';
21
+ import { generateUid } from './database/index.js';
22
+ import { catchBuildLogPath, catchWebDistPath, catchImagePath, baseRoute } from './config.js';
23
+ /** 每周一 12:00 清理旧日志和备份 */
24
+ const clearFileCron = new CronJob('0 0 12 * * 1', () => {
25
+ try {
26
+ console.log(`${dayjs().format('YYYY-MM-DD HH:mm:ss')} run clearFileCron`);
27
+ autoClearFiles(catchBuildLogPath, 50);
28
+ autoClearFiles(catchWebDistPath, 50);
29
+ }
30
+ catch (error) {
31
+ console.log(error);
32
+ }
33
+ }, null, false);
34
+ /** 工作日 10-19 点定时推送(默认注释,保留代码) */
35
+ const getDailyCron = new CronJob('0 0 10-19/1 * * 1-5', () => __awaiter(void 0, void 0, void 0, function* () {
36
+ var _a;
37
+ try {
38
+ console.log(`${dayjs().format('YYYY-MM-DD HH:mm:ss')} run getDailyCron`);
39
+ const res = yield axios('https://api.kuleu.com/api/MP4_xiaojiejie?type=json');
40
+ const mp4_video = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.mp4_video;
41
+ if (!mp4_video)
42
+ return;
43
+ const url = new URL(mp4_video);
44
+ const fileParse = path.parse(url.pathname);
45
+ yield axios({
46
+ url: mp4_video,
47
+ method: 'GET',
48
+ responseType: 'arraybuffer',
49
+ }).then((res) => __awaiter(void 0, void 0, void 0, function* () {
50
+ if ((res === null || res === void 0 ? void 0 : res.status) !== 200)
51
+ return;
52
+ const data = res === null || res === void 0 ? void 0 : res.data;
53
+ if (!Buffer.isBuffer(data))
54
+ return;
55
+ const { writeStream, localFileName } = yield getWriteStream(catchImagePath, `getDailyCron_${dayjs().format('YYYY-MM-DD_HH-mm-ss')}${fileParse.ext}`);
56
+ writeStream.end(data);
57
+ websocketHandler.sendMsg('on:msg-chat', formatMsg('on:msg-chat', {
58
+ id: generateUid(IdType.M),
59
+ socketId: '',
60
+ msg: '轻松一刻',
61
+ name: '系统消息',
62
+ files: [`${baseRoute}/api/showLog?type=image&name=${localFileName}`],
63
+ time: getFormatTime(),
64
+ timestamp: +dayjs(),
65
+ ctxType: 'ctx:imgs',
66
+ }));
67
+ }));
68
+ }
69
+ catch (error) {
70
+ console.error('GetDailyCron Error:', error);
71
+ }
72
+ }), null, false);
73
+ /** 工作日 10:00 天气推送 */
74
+ const getWeatherCron = new CronJob('0 0 10 * * 1-5', () => __awaiter(void 0, void 0, void 0, function* () {
75
+ var _a, _b, _c, _d, _e, _f, _g;
76
+ try {
77
+ console.log(`${dayjs().format('YYYY-MM-DD HH:mm:ss')} run getWeatherCron`);
78
+ const res = yield axios('https://aider.meizu.com/app/weather/listWeather?cityIds=101200101');
79
+ const data = (_b = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b[0];
80
+ if (!data)
81
+ return;
82
+ const msgArr = [
83
+ `${dayjs().format('YYYY年MM月DD日')} ${data.provinceName}${data.city}天气`,
84
+ `天气:${(_c = data === null || data === void 0 ? void 0 : data.realtime) === null || _c === void 0 ? void 0 : _c.weather}`,
85
+ `温度:${(_d = data === null || data === void 0 ? void 0 : data.realtime) === null || _d === void 0 ? void 0 : _d.temp}度`,
86
+ `风向:${(_e = data === null || data === void 0 ? void 0 : data.realtime) === null || _e === void 0 ? void 0 : _e.wD} ${(_f = data === null || data === void 0 ? void 0 : data.realtime) === null || _f === void 0 ? void 0 : _f.wS}`,
87
+ `空气质量:${(_g = data === null || data === void 0 ? void 0 : data.pm25) === null || _g === void 0 ? void 0 : _g.quality}`,
88
+ `\n------ 温馨小贴士 ------`,
89
+ ...(data.indexes || []).map((v) => `${v.content}`),
90
+ `------ 未来天气 ------`,
91
+ ...(data.weathers || []).slice(0, -1).map((v) => {
92
+ return `${v.date} ${v.week} ${v.weather} 白天最高${v.temp_day_c}度,夜晚最低${v.temp_night_c}度`;
93
+ }),
94
+ ];
95
+ websocketHandler.sendMsg('on:msg-chat', formatMsg('on:msg-chat', {
96
+ id: generateUid(IdType.M),
97
+ socketId: '',
98
+ name: '天气小助手',
99
+ msg: msgArr.join('\n'),
100
+ time: getFormatTime(),
101
+ timestamp: +dayjs(),
102
+ ctxType: 'ctx:txt',
103
+ }));
104
+ }
105
+ catch (error) {
106
+ console.error('GetWeatherCron Error:', error);
107
+ }
108
+ }), null, false);
109
+ /** 工作日 9:50 36氪热榜推送 */
110
+ const getNewsCron = new CronJob('0 50 9 * * 1-5', () => __awaiter(void 0, void 0, void 0, function* () {
111
+ var _a, _b;
112
+ try {
113
+ console.log(`${dayjs().format('YYYY-MM-DD HH:mm:ss')} run getNewsCron`);
114
+ const res = yield axios({
115
+ method: 'post',
116
+ url: 'https://gateway.36kr.com/api/mis/nav/home/nav/rank/hot',
117
+ headers: {
118
+ Origin: 'https://m.36kr.com/',
119
+ Referer: 'https://m.36kr.com/',
120
+ },
121
+ data: {
122
+ partner_id: 'wap',
123
+ timestamp: +dayjs(),
124
+ param: { siteId: 1, platformId: 2 },
125
+ },
126
+ });
127
+ const list = ((_b = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.hotRankList) || [];
128
+ if (!(list === null || list === void 0 ? void 0 : list.length))
129
+ return;
130
+ const msgArr = [
131
+ `${dayjs().format('YYYY年MM月DD日')} 今日头条`,
132
+ ...list.map((v, i) => {
133
+ var _a, _b, _c;
134
+ return `${i} ${(_a = v === null || v === void 0 ? void 0 : v.templateMaterial) === null || _a === void 0 ? void 0 : _a.widgetTitle}\n${getFormatTime((_b = v === null || v === void 0 ? void 0 : v.templateMaterial) === null || _b === void 0 ? void 0 : _b.publishTime)} 热度:${(_c = v === null || v === void 0 ? void 0 : v.templateMaterial) === null || _c === void 0 ? void 0 : _c.statRead}`;
135
+ }),
136
+ ];
137
+ websocketHandler.sendMsg('on:msg-chat', formatMsg('on:msg-chat', {
138
+ id: generateUid(IdType.M),
139
+ socketId: '',
140
+ name: '36氪热榜',
141
+ msg: msgArr.join('\n\n'),
142
+ time: getFormatTime(),
143
+ timestamp: +dayjs(),
144
+ ctxType: 'ctx:txt',
145
+ }));
146
+ }
147
+ catch (error) {
148
+ console.error('GetNewsCron Error:', error);
149
+ }
150
+ }), null, false);
151
+ const cronList = [
152
+ clearFileCron,
153
+ // getDailyCron, // 默认不启用
154
+ getWeatherCron,
155
+ getNewsCron,
156
+ ];
157
+ /** 启动所有 cron */
158
+ export const startCron = () => {
159
+ cronList.forEach((cron) => {
160
+ cron.start();
161
+ });
162
+ };
163
+ //# sourceMappingURL=cron.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron.js","sourceRoot":"","sources":["../src/cron.ts"],"names":[],"mappings":"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"}
package/dist/crypto.js ADDED
@@ -0,0 +1,40 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ /**
11
+ * AES-256-CBC 加解密
12
+ */
13
+ import { scrypt, randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';
14
+ import { promisify } from 'node:util';
15
+ import { cryptoSalt, cryptoSecret } from './config.js';
16
+ const scryptAsync = promisify(scrypt);
17
+ /** 加密函数 */
18
+ export function encrypt(text) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const iv = randomBytes(16);
21
+ const key = (yield scryptAsync(cryptoSecret, cryptoSalt, 32));
22
+ const cipher = createCipheriv('aes-256-cbc', key, iv);
23
+ let encrypted = cipher.update(text, 'utf8', 'hex');
24
+ encrypted += cipher.final('hex');
25
+ return `${iv.toString('hex')}:${encrypted}`;
26
+ });
27
+ }
28
+ /** 解密函数 */
29
+ export function decrypt(encryptedText) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ const [ivHex, encryptedHex] = encryptedText.split(':');
32
+ const iv = Buffer.from(ivHex, 'hex');
33
+ const key = (yield scryptAsync(cryptoSecret, cryptoSalt, 32));
34
+ const decipher = createDecipheriv('aes-256-cbc', key, iv);
35
+ let decrypted = decipher.update(encryptedHex, 'hex', 'utf8');
36
+ decrypted += decipher.final('utf8');
37
+ return decrypted;
38
+ });
39
+ }
40
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":";;;;;;;;;AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;AAErC,WAAW;AACX,MAAM,UAAgB,OAAO,CAAC,IAAY;;QACxC,MAAM,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;QAC1B,MAAM,GAAG,GAAG,CAAC,MAAM,WAAW,CAAC,YAAY,EAAE,UAAU,EAAE,EAAE,CAAC,CAAW,CAAA;QACvE,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QACrD,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;QAClD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAChC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAA;IAC7C,CAAC;CAAA;AAED,WAAW;AACX,MAAM,UAAgB,OAAO,CAAC,aAAqB;;QACjD,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACtD,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QACpC,MAAM,GAAG,GAAG,CAAC,MAAM,WAAW,CAAC,YAAY,EAAE,UAAU,EAAE,EAAE,CAAC,CAAW,CAAA;QACvE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QACzD,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;QAC5D,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACnC,OAAO,SAAS,CAAA;IAClB,CAAC;CAAA"}
@@ -0,0 +1,10 @@
1
+ import dayjs from 'dayjs';
2
+ export default class CustError extends Error {
3
+ constructor(custMsg, name = 'CustError') {
4
+ super(custMsg);
5
+ this.name = name;
6
+ this.custMsg = custMsg;
7
+ this.date = dayjs().format('YYYY-MM-DD HH:mm:ss');
8
+ }
9
+ }
10
+ //# sourceMappingURL=custError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custError.js","sourceRoot":"","sources":["../src/custError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,KAAK;IAI1C,YAAY,OAAe,EAAE,IAAI,GAAG,WAAW;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAA;IACnD,CAAC;CACF"}
@@ -0,0 +1,64 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ /**
11
+ * JSON 文件数据库 – 基于文件系统的轻量级存储
12
+ */
13
+ import fse from 'fs-extra';
14
+ import path from 'node:path';
15
+ import dayjs from 'dayjs';
16
+ import { ensureDir } from '../fsHelpers.js';
17
+ import { catchDatabasePath } from '../config.js';
18
+ import { DatabaseEntities } from './types.js';
19
+ /** 生成唯一 ID */
20
+ export const generateUid = (prefix = '') => {
21
+ return `${prefix}${dayjs().format('YYYYMMDDHHmmssSSS')}${Math.floor(Math.random() * 1000000)}`;
22
+ };
23
+ const getAbsTablePath = (name) => path.resolve(catchDatabasePath, `${name}.json`);
24
+ /** 启动时从 JSON 文件加载数据到 Map */
25
+ export function loadDatabase() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ yield ensureDir(catchDatabasePath);
28
+ const database = new Map();
29
+ let dirs = fse.readdirSync(catchDatabasePath);
30
+ for (const name of Object.values(DatabaseEntities)) {
31
+ if (dirs.includes(`${name}.json`))
32
+ continue;
33
+ if (name === DatabaseEntities.User) {
34
+ const defUser = {
35
+ id: generateUid(),
36
+ name: 'daiyu',
37
+ password: '123456',
38
+ role: 'super',
39
+ timestamp: +dayjs(),
40
+ byInviteCode: '',
41
+ };
42
+ updateDatabaseFile(name, [defUser]);
43
+ continue;
44
+ }
45
+ updateDatabaseFile(name, []);
46
+ }
47
+ dirs = fse.readdirSync(catchDatabasePath);
48
+ for (const file of dirs) {
49
+ if (!file.endsWith('.json'))
50
+ continue;
51
+ const name = path.basename(file, '.json');
52
+ const absFilePath = getAbsTablePath(name);
53
+ const data = fse.readJSONSync(absFilePath);
54
+ database.set(name, data);
55
+ }
56
+ return database;
57
+ });
58
+ }
59
+ /** 将数据写回 JSON 文件 */
60
+ export const updateDatabaseFile = (tableName, data) => __awaiter(void 0, void 0, void 0, function* () {
61
+ const absFilePath = getAbsTablePath(tableName);
62
+ yield fse.writeFile(absFilePath, JSON.stringify(data, null, 2));
63
+ });
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA;;GAEG;AACH,OAAO,GAAG,MAAM,UAAU,CAAA;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAI7C,cAAc;AACd,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,EAAU,EAAE;IACjD,OAAO,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAA;AAChG,CAAC,CAAA;AAED,MAAM,eAAe,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,IAAI,OAAO,CAAC,CAAA;AAEjG,4BAA4B;AAC5B,MAAM,UAAgB,YAAY;;QAChC,MAAM,SAAS,CAAC,iBAAiB,CAAC,CAAA;QAElC,MAAM,QAAQ,GAAsD,IAAI,GAAG,EAAE,CAAA;QAE7E,IAAI,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAA;QAE7C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC;gBAAE,SAAQ;YAC3C,IAAI,IAAI,KAAK,gBAAgB,CAAC,IAAI,EAAE,CAAC;gBACnC,MAAM,OAAO,GAAS;oBACpB,EAAE,EAAE,WAAW,EAAE;oBACjB,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,OAAO;oBACb,SAAS,EAAE,CAAC,KAAK,EAAE;oBACnB,YAAY,EAAE,EAAE;iBACjB,CAAA;gBACD,kBAAkB,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;gBACnC,SAAQ;YACV,CAAC;YACD,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC9B,CAAC;QAED,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAA;QAEzC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAQ;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAqB,CAAA;YAC7D,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;YACzC,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,CAAA;YAC1C,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC1B,CAAC;QAED,OAAO,QAAQ,CAAA;IACjB,CAAC;CAAA;AAED,oBAAoB;AACpB,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAmC,SAAY,EAAE,IAAiB,EAAiB,EAAE;IACrH,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAC9C,MAAM,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AACjE,CAAC,CAAA,CAAA"}
@@ -0,0 +1,8 @@
1
+ export var DatabaseEntities;
2
+ (function (DatabaseEntities) {
3
+ DatabaseEntities["User"] = "user";
4
+ DatabaseEntities["MessageChat"] = "message_chat";
5
+ DatabaseEntities["MessageBuild"] = "message_build";
6
+ DatabaseEntities["Invite"] = "invite";
7
+ })(DatabaseEntities || (DatabaseEntities = {}));
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/database/types.ts"],"names":[],"mappings":"AAKA,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,iCAAa,CAAA;IACb,gDAA4B,CAAA;IAC5B,kDAA8B,CAAA;IAC9B,qCAAiB,CAAA;AACnB,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B"}
@@ -0,0 +1,93 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ /**
11
+ * 文件系统工具函数
12
+ */
13
+ import { createWriteStream, constants } from 'node:fs';
14
+ import fse from 'fs-extra';
15
+ import path from 'node:path';
16
+ import fs from 'node:fs/promises';
17
+ import CustError from './custError.js';
18
+ /** 确保目录存在(异步) */
19
+ export const ensureDir = (dir) => __awaiter(void 0, void 0, void 0, function* () {
20
+ yield fse.ensureDir(dir);
21
+ });
22
+ /** 安全读取并解析 package.json */
23
+ export function readPackageJson(pkgPath) {
24
+ if (!fse.existsSync(pkgPath)) {
25
+ throw new Error(`package.json not found at ${pkgPath}`);
26
+ }
27
+ const content = fse.readFileSync(pkgPath, 'utf-8');
28
+ return JSON.parse(content);
29
+ }
30
+ /** 异步复制构建产物 */
31
+ export function moveDist(projectDir, targetDir) {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ const srcDist = path.join(projectDir, 'dist');
34
+ if (!fse.existsSync(srcDist)) {
35
+ throw new Error(`Dist folder not found in ${projectDir}`);
36
+ }
37
+ yield fse.ensureDir(targetDir);
38
+ yield fse.copy(srcDist, targetDir, { overwrite: true });
39
+ });
40
+ }
41
+ /** 获取可写流,自动处理文件重名 */
42
+ export const getWriteStream = (absDir, filename, increase) => __awaiter(void 0, void 0, void 0, function* () {
43
+ yield ensureDir(absDir);
44
+ const fileParse = path.parse(filename);
45
+ const localFileName = `${fileParse.name}${increase ? `(${increase})` : ''}${fileParse.ext}`;
46
+ const absFilePath = path.join(absDir, localFileName);
47
+ try {
48
+ yield fs.access(absFilePath, constants.F_OK);
49
+ return yield getWriteStream(absDir, filename, increase ? increase + 1 : 1);
50
+ }
51
+ catch (_a) {
52
+ const writeStream = createWriteStream(absFilePath, { flags: 'a' });
53
+ writeStream.on('error', (err) => {
54
+ console.error(`写入文件时发生错误: ${err}`);
55
+ });
56
+ return { writeStream, localFileName };
57
+ }
58
+ });
59
+ /** 自动清理文件,保留最新的 maxSize 个 */
60
+ export const autoClearFiles = (absDir_1, ...args_1) => __awaiter(void 0, [absDir_1, ...args_1], void 0, function* (absDir, maxSize = 50) {
61
+ try {
62
+ yield fs.access(absDir, constants.F_OK);
63
+ const files = yield fs.readdir(absDir);
64
+ if (files.length <= maxSize)
65
+ return;
66
+ const stats = yield Promise.all(files.map((f) => __awaiter(void 0, void 0, void 0, function* () {
67
+ const stat = yield fs.stat(path.join(absDir, f));
68
+ return { name: f, mtime: stat.mtime.getTime() };
69
+ })));
70
+ stats.sort((a, b) => a.mtime - b.mtime);
71
+ for (let i = 0; i < stats.length - maxSize; i++) {
72
+ const filePath = path.join(absDir, stats[i].name);
73
+ yield fs.rm(filePath, { recursive: true });
74
+ }
75
+ console.log(`[buildSystem] ${absDir} 限制${maxSize}清理成功`);
76
+ }
77
+ catch (error) {
78
+ console.log(error);
79
+ }
80
+ });
81
+ /** 从给定路径向上查找 index.html */
82
+ export const findIndexHtml = (absPath, basePath) => __awaiter(void 0, void 0, void 0, function* () {
83
+ const arr = absPath.split('/');
84
+ for (let i = arr.length - 1; i >= 0; i--) {
85
+ const curPath = arr.slice(0, i + 1).join('/');
86
+ const filePath = path.join(basePath, curPath, 'index.html');
87
+ if (fse.existsSync(filePath)) {
88
+ return filePath;
89
+ }
90
+ }
91
+ throw new CustError('index.html not found', 'FindIndexHtml Error');
92
+ });
93
+ //# sourceMappingURL=fsHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsHelpers.js","sourceRoot":"","sources":["../src/fsHelpers.ts"],"names":[],"mappings":"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"}
package/dist/git.js ADDED
@@ -0,0 +1,67 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { execPms } from './utils.js';
11
+ import chalk from 'chalk';
12
+ /** 检查并切换分支:本地存在则 checkout,否则从远程创建 */
13
+ export function checkBranch(branchName_1, cwd_1) {
14
+ return __awaiter(this, arguments, void 0, function* (branchName, cwd, option = {}) {
15
+ const localBranchesResult = yield execPms('git branch', Object.assign({ cwd, encoding: 'utf-8' }, option));
16
+ const localBranches = localBranchesResult.stdout.split('\n');
17
+ const localBranchExists = localBranches.some((v) => v.includes(branchName));
18
+ if (localBranchExists) {
19
+ const command = `git checkout ${branchName}`;
20
+ console.log(chalk.green(`------ ${command} ------`));
21
+ yield execPms(command, Object.assign({ cwd, encoding: 'utf-8' }, option));
22
+ return;
23
+ }
24
+ const command = `git checkout -b ${branchName} origin/${branchName}`;
25
+ console.log(chalk.green(`------ ${command} ------`));
26
+ yield execPms(command, Object.assign({ cwd, encoding: 'utf-8' }, option));
27
+ });
28
+ }
29
+ /** 清理 git 工作区:checkout . + clean -df */
30
+ export function gitClean(cwd_1) {
31
+ return __awaiter(this, arguments, void 0, function* (cwd, option = {}) {
32
+ yield execPms('git checkout .', Object.assign({ cwd }, option));
33
+ yield execPms('git clean -df', Object.assign({ cwd }, option));
34
+ });
35
+ }
36
+ /** 异步获取 diff 文件列表 */
37
+ export function getChangedFiles(range_1, cwd_1) {
38
+ return __awaiter(this, arguments, void 0, function* (range, cwd, option = {}) {
39
+ const output = yield execPms(`git diff --name-only ${range}`, Object.assign({ cwd, encoding: 'utf-8' }, option));
40
+ return output.stdout.split('\n').filter(Boolean);
41
+ });
42
+ }
43
+ /** 异步 checkout 分支 */
44
+ export function checkoutBranch(branch_1, cwd_1) {
45
+ return __awaiter(this, arguments, void 0, function* (branch, cwd, option = {}) {
46
+ yield execPms(`git checkout ${branch}`, Object.assign({ cwd, encoding: 'utf-8' }, option));
47
+ });
48
+ }
49
+ /** 异步 pull 分支 */
50
+ export function pullBranch(branch_1, cwd_1) {
51
+ return __awaiter(this, arguments, void 0, function* (branch, cwd, option = {}) {
52
+ yield execPms(`git pull origin ${branch}`, Object.assign({ cwd, encoding: 'utf-8' }, option));
53
+ });
54
+ }
55
+ /** 硬重置 */
56
+ export function resetHard(dir_1) {
57
+ return __awaiter(this, arguments, void 0, function* (dir, option = {}) {
58
+ yield execPms('git reset --hard', Object.assign({ cwd: dir }, option));
59
+ });
60
+ }
61
+ /** 清理未追踪文件 */
62
+ export function cleanUntracked(dir_1) {
63
+ return __awaiter(this, arguments, void 0, function* (dir, option = {}) {
64
+ yield execPms('git clean -fd', Object.assign({ cwd: dir }, option));
65
+ });
66
+ }
67
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":";;;;;;;;;AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,qCAAqC;AACrC,MAAM,UAAgB,WAAW;yDAAC,UAAkB,EAAE,GAAW,EAAE,SAAwC,EAAE;QAC3G,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,YAAY,kBAAI,GAAG,EAAE,QAAQ,EAAE,OAAgB,IAAK,MAAM,EAAG,CAAA;QACvG,MAAM,aAAa,GAAI,mBAAmB,CAAC,MAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACxE,MAAM,iBAAiB,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAA;QACnF,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,gBAAgB,UAAU,EAAE,CAAA;YAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,OAAO,SAAS,CAAC,CAAC,CAAA;YACpD,MAAM,OAAO,CAAC,OAAO,kBAAI,GAAG,EAAE,QAAQ,EAAE,OAAO,IAAK,MAAM,EAAG,CAAA;YAC7D,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,mBAAmB,UAAU,WAAW,UAAU,EAAE,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,OAAO,SAAS,CAAC,CAAC,CAAA;QACpD,MAAM,OAAO,CAAC,OAAO,kBAAI,GAAG,EAAE,QAAQ,EAAE,OAAO,IAAK,MAAM,EAAG,CAAA;IAC/D,CAAC;CAAA;AAED,wCAAwC;AACxC,MAAM,UAAgB,QAAQ;yDAAC,GAAW,EAAE,SAAwC,EAAE;QACpF,MAAM,OAAO,CAAC,gBAAgB,kBAAI,GAAG,IAAK,MAAM,EAAG,CAAA;QACnD,MAAM,OAAO,CAAC,eAAe,kBAAI,GAAG,IAAK,MAAM,EAAG,CAAA;IACpD,CAAC;CAAA;AAED,qBAAqB;AACrB,MAAM,UAAgB,eAAe;yDAAC,KAAa,EAAE,GAAW,EAAE,SAAwC,EAAE;QAC1G,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,wBAAwB,KAAK,EAAE,kBAAI,GAAG,EAAE,QAAQ,EAAE,OAAgB,IAAK,MAAM,EAAG,CAAA;QAC7G,OAAQ,MAAM,CAAC,MAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC9D,CAAC;CAAA;AAED,qBAAqB;AACrB,MAAM,UAAgB,cAAc;yDAAC,MAAc,EAAE,GAAW,EAAE,SAAwC,EAAE;QAC1G,MAAM,OAAO,CAAC,gBAAgB,MAAM,EAAE,kBAAI,GAAG,EAAE,QAAQ,EAAE,OAAO,IAAK,MAAM,EAAG,CAAA;IAChF,CAAC;CAAA;AAED,iBAAiB;AACjB,MAAM,UAAgB,UAAU;yDAAC,MAAc,EAAE,GAAW,EAAE,SAAwC,EAAE;QACtG,MAAM,OAAO,CAAC,mBAAmB,MAAM,EAAE,kBAAI,GAAG,EAAE,QAAQ,EAAE,OAAO,IAAK,MAAM,EAAG,CAAA;IACnF,CAAC;CAAA;AAED,UAAU;AACV,MAAM,UAAgB,SAAS;yDAAC,GAAW,EAAE,SAAwC,EAAE;QACrF,MAAM,OAAO,CAAC,kBAAkB,kBAAI,GAAG,EAAE,GAAG,IAAK,MAAM,EAAG,CAAA;IAC5D,CAAC;CAAA;AAED,cAAc;AACd,MAAM,UAAgB,cAAc;yDAAC,GAAW,EAAE,SAAwC,EAAE;QAC1F,MAAM,OAAO,CAAC,eAAe,kBAAI,GAAG,EAAE,GAAG,IAAK,MAAM,EAAG,CAAA;IACzD,CAAC;CAAA"}
package/dist/logger.js ADDED
@@ -0,0 +1,80 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ /**
13
+ * Winston 日志系统 – 自定义级别 + daily-rotate-file
14
+ */
15
+ import winston, { format } from 'winston';
16
+ import path from 'node:path';
17
+ import 'winston-daily-rotate-file';
18
+ import { catchHttpLogPath } from './config.js';
19
+ const { combine, timestamp, label, printf, errors } = format;
20
+ const customLevels = {
21
+ levels: {
22
+ error: 0,
23
+ warn: 1,
24
+ info: 2,
25
+ socket: 3,
26
+ http: 4,
27
+ },
28
+ colors: {
29
+ error: 'red',
30
+ warn: 'yellow',
31
+ info: 'blue',
32
+ socket: 'green',
33
+ http: 'green',
34
+ },
35
+ };
36
+ const custFormat = printf((params) => {
37
+ const { timestamp, label, level, message } = params, arg = __rest(params, ["timestamp", "label", "level", "message"]);
38
+ const str = `${new Date().toISOString()} [${label}] [${level}] ${message} ${JSON.stringify(arg, null, 2)}`;
39
+ return str;
40
+ });
41
+ // transport 级格式过滤:仅保留指定级别的日志
42
+ const logFilter = (type) => format((info) => {
43
+ return info.level === type ? info : false;
44
+ })();
45
+ // http transport: logger level 'http'(4) 放行所有消息(≤4), 此处用 format 只保留 http
46
+ const httpTransport = new winston.transports.DailyRotateFile({
47
+ level: 'http',
48
+ filename: path.resolve(catchHttpLogPath, '%DATE%_http.log'),
49
+ datePattern: 'YYYY-MM-DD',
50
+ zippedArchive: true,
51
+ maxSize: '20m',
52
+ maxFiles: '14d',
53
+ format: combine(logFilter('http'), timestamp(), label({ label: 'buildSystem' }), errors(), custFormat),
54
+ });
55
+ // socket transport: logger level 'socket'(3) 自动排除 http(4), 无需额外过滤
56
+ const socketTransport = new winston.transports.DailyRotateFile({
57
+ level: 'socket',
58
+ filename: path.resolve(catchHttpLogPath, '%DATE%_socket.log'),
59
+ datePattern: 'YYYY-MM-DD',
60
+ zippedArchive: true,
61
+ maxSize: '20m',
62
+ maxFiles: '14d',
63
+ format: combine(timestamp(), label({ label: 'buildSystem' }), errors(), custFormat),
64
+ });
65
+ export const logger = winston.createLogger({
66
+ level: 'http',
67
+ levels: customLevels.levels,
68
+ defaultMeta: {},
69
+ transports: [
70
+ new winston.transports.Console({
71
+ level: 'info',
72
+ format: combine(format.colorize(), format.simple()),
73
+ }),
74
+ httpTransport,
75
+ socketTransport,
76
+ ],
77
+ exitOnError: false,
78
+ });
79
+ winston.addColors(customLevels.colors);
80
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}