alemonjs 2.1.0-alpha.30 → 2.1.0-alpha.32

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.
package/lib/cbp/index.js CHANGED
@@ -1,64 +1,64 @@
1
1
  import Koa from 'koa';
2
2
  import { WebSocketServer, WebSocket } from 'ws';
3
3
  import router from './router.js';
4
+ import koaStatic from 'koa-static';
4
5
  import koaCors from '@koa/cors';
5
6
  import { ResultCode } from '../core/code.js';
6
- import { platformClient, childrenClient, fullClient, childrenBind, USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, DEVICE_ID_HEADER, FULL_RECEIVE_HEADER } from './config.js';
7
+ import { USER_AGENT_HEADER, DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, platformClient, childrenClient, fullClient, childrenBind } from './config.js';
7
8
  import { getConfig } from '../core/config.js';
8
9
  import * as flattedJSON from 'flatted';
9
- import { connectionTestOne } from './testone.js';
10
10
 
11
- function getReConnectTime() {
12
- const time = 1000 * 1;
13
- const curTime = time;
14
- const mTime = (curTime / 1000 / 60).toFixed(2);
15
- logger.info({
16
- code: ResultCode.Fail,
17
- message: `[ws-discord] 等待 ${mTime} 分钟后重新连接`,
18
- data: null
19
- });
20
- return curTime;
21
- }
22
11
  const cbpServer = (port, listeningListener) => {
23
12
  if (global.chatbotServer) {
24
13
  delete global.chatbotServer;
25
14
  }
26
- const createServer = () => {
27
- try {
28
- // create
29
- const app = new Koa();
30
- // MessageRouter
31
- app.use(router.routes());
32
- app.use(router.allowedMethods());
33
- // Cors
34
- app.use(koaCors({
35
- origin: '*', // 允许所有来源
36
- allowMethods: ['GET', 'POST', 'PUT', 'DELETE'] // 允许的 HTTP 方法
37
- }));
38
- const server = app.listen(port, listeningListener);
39
- // 创建 WebSocketServer 并监听同一个端口
40
- global.chatbotServer = new WebSocketServer({ server });
41
- /**
42
- *
43
- * @param originId
44
- * @param ws
45
- */
46
- const setPlatformClient = (originId, ws) => {
47
- // 仅允许有一个平台连接
48
- if (platformClient.size > 0) {
49
- logger.error({
50
- code: ResultCode.Fail,
51
- message: `平台连接已存在: ${originId}`,
52
- data: null
53
- });
54
- ws.close(); // 关闭新连接
55
- return;
56
- }
57
- // 设置平台客户端
58
- platformClient.set(originId, ws);
59
- // 处理api
60
- const handleApi = (DeviceId, message) => {
15
+ const app = new Koa();
16
+ app.use(router.routes());
17
+ app.use(router.allowedMethods());
18
+ // 读取静态文件夹 gui
19
+ app.use(koaStatic('/gui'));
20
+ // 允许跨域
21
+ app.use(koaCors({
22
+ origin: '*', // 允许所有来源
23
+ allowMethods: ['GET', 'POST', 'PUT', 'DELETE'] // 允许的 HTTP 方法
24
+ }));
25
+ const server = app.listen(port, listeningListener);
26
+ // 创建 WebSocketServer 并监听同一个端口
27
+ global.chatbotServer = new WebSocketServer({ server });
28
+ /**
29
+ *
30
+ * @param originId
31
+ * @param ws
32
+ */
33
+ const setPlatformClient = (originId, ws) => {
34
+ // 仅允许有一个平台连接
35
+ if (platformClient.size > 0) {
36
+ logger.error({
37
+ code: ResultCode.Fail,
38
+ message: `平台连接已存在: ${originId}`,
39
+ data: null
40
+ });
41
+ ws.close(); // 关闭新连接
42
+ return;
43
+ }
44
+ // 设置平台客户端
45
+ platformClient.set(originId, ws);
46
+ // 得到平台客户端的消息
47
+ ws.on('message', (message) => {
48
+ try {
49
+ // 解析消息
50
+ const parsedMessage = flattedJSON.parse(message.toString());
51
+ // 1. 解析得到 actionId ,说明是消费行为请求。要广播告诉所有客户端。
52
+ // 2. 解析得到 name ,说明是一个事件请求。
53
+ // 3. 解析得到 apiId ,说明是一个接口请求。
54
+ logger.debug({
55
+ code: ResultCode.Ok,
56
+ message: '服务端接收到消息',
57
+ data: parsedMessage
58
+ });
59
+ if (parsedMessage.apiId) {
61
60
  // 指定的设备 处理消费。终端有记录每个客户端是谁
61
+ const DeviceId = parsedMessage.DeviceId;
62
62
  if (childrenClient.has(DeviceId)) {
63
63
  const clientWs = childrenClient.get(DeviceId);
64
64
  if (clientWs && clientWs.readyState === WebSocket.OPEN) {
@@ -81,9 +81,10 @@ const cbpServer = (port, listeningListener) => {
81
81
  fullClient.delete(DeviceId);
82
82
  }
83
83
  }
84
- };
85
- // 处理 action
86
- const handleAction = (DeviceId, message) => {
84
+ }
85
+ else if (parsedMessage?.actionId) {
86
+ // 指定的设备 处理消费。终端有记录每个客户端是谁
87
+ const DeviceId = parsedMessage.DeviceId;
87
88
  if (childrenClient.has(DeviceId)) {
88
89
  const clientWs = childrenClient.get(DeviceId);
89
90
  if (clientWs && clientWs.readyState === WebSocket.OPEN) {
@@ -106,9 +107,8 @@ const cbpServer = (port, listeningListener) => {
106
107
  fullClient.delete(DeviceId);
107
108
  }
108
109
  }
109
- };
110
- // 处理事件
111
- const handleEvent = (message, ID) => {
110
+ }
111
+ else if (parsedMessage?.name) {
112
112
  // 全量客户端
113
113
  fullClient.forEach((clientWs, clientId) => {
114
114
  // 检查状态 并检查状态
@@ -122,6 +122,7 @@ const cbpServer = (port, listeningListener) => {
122
122
  });
123
123
  // 根据所在群进行分流。
124
124
  // 确保同一个频道的消息。都流向同一个客户端。
125
+ const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
125
126
  if (!ID) {
126
127
  logger.error({
127
128
  code: ResultCode.Fail,
@@ -198,237 +199,151 @@ const cbpServer = (port, listeningListener) => {
198
199
  return;
199
200
  }
200
201
  clientWs.send(message);
201
- };
202
- // 得到平台客户端的消息
203
- ws.on('message', (message) => {
204
- try {
205
- // 解析消息
206
- const parsedMessage = flattedJSON.parse(message.toString());
207
- // 1. 解析得到 actionId ,说明是消费行为请求。要广播告诉所有客户端。
208
- // 2. 解析得到 name ,说明是一个事件请求。
209
- // 3. 解析得到 apiId ,说明是一个接口请求。
210
- // 4. 解析得到 testID ,说明是一个测试请求。
211
- logger.debug({
212
- code: ResultCode.Ok,
213
- message: '服务端接收到消息',
214
- data: parsedMessage
215
- });
216
- if (parsedMessage.apiId) {
217
- // 指定的设备 处理消费。终端有记录每个客户端是谁
218
- const DeviceId = parsedMessage.DeviceId;
219
- handleApi(DeviceId, message);
220
- }
221
- else if (parsedMessage?.actionId) {
222
- // 指定的设备 处理消费。终端有记录每个客户端是谁
223
- const DeviceId = parsedMessage.DeviceId;
224
- handleAction(DeviceId, message);
225
- }
226
- else if (parsedMessage?.name) {
227
- const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
228
- handleEvent(message, ID);
229
- }
230
- else if (parsedMessage?.testID) {
231
- // 继续解析数据。测试请求。
232
- }
233
- }
234
- catch (error) {
235
- logger.error({
236
- code: ResultCode.Fail,
237
- message: '服务端解析平台消息失败',
238
- data: error
239
- });
240
- return;
241
- }
242
- });
243
- // 处理关闭事件
244
- ws.on('close', () => {
245
- platformClient.delete(originId);
246
- logger.debug({
247
- code: ResultCode.Fail,
248
- message: `Client ${originId} disconnected`,
249
- data: null
250
- });
251
- });
252
- ws.on('error', err => {
253
- logger.error({
254
- code: ResultCode.Fail,
255
- message: `Client ${originId} error`,
256
- data: err
257
- });
202
+ }
203
+ }
204
+ catch (error) {
205
+ logger.error({
206
+ code: ResultCode.Fail,
207
+ message: '服务端解析平台消息失败',
208
+ data: error
258
209
  });
259
- };
260
- // 设置子客户端
261
- const setChildrenClient = (originId, ws) => {
262
- childrenClient.set(originId, ws);
263
- // 得到子客户端的消息。只会是actions请求。
264
- ws.on('message', (message) => {
265
- // tudo
266
- // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
267
- // 导致无法进行多个平台连接。
268
- if (platformClient.size > 0) {
269
- platformClient.forEach((platformWs, platformId) => {
270
- // 检查平台客户端状态
271
- if (platformWs.readyState === WebSocket.OPEN) {
272
- platformWs.send(message);
273
- }
274
- else {
275
- // 如果连接已关闭,删除该平台客户端
276
- platformClient.delete(platformId);
277
- }
278
- });
210
+ return;
211
+ }
212
+ });
213
+ // 处理关闭事件
214
+ ws.on('close', () => {
215
+ delete platformClient[originId];
216
+ logger.debug({
217
+ code: ResultCode.Fail,
218
+ message: `Client ${originId} disconnected`,
219
+ data: null
220
+ });
221
+ });
222
+ ws.on('error', err => {
223
+ logger.error({
224
+ code: ResultCode.Fail,
225
+ message: `Client ${originId} error`,
226
+ data: err
227
+ });
228
+ });
229
+ };
230
+ // 设置子客户端
231
+ const setChildrenClient = (originId, ws) => {
232
+ childrenClient.set(originId, ws);
233
+ // 得到子客户端的消息。只会是actions请求。
234
+ ws.on('message', (message) => {
235
+ // tudo
236
+ // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
237
+ // 导致无法进行多个平台连接。
238
+ if (platformClient.size > 0) {
239
+ platformClient.forEach(platformWs => {
240
+ // 检查平台客户端状态
241
+ if (platformWs.readyState === WebSocket.OPEN) {
242
+ platformWs.send(message);
279
243
  }
280
- });
281
- // 处理关闭事件
282
- ws.on('close', () => {
283
- childrenClient.delete(originId);
284
- logger.debug({
285
- code: ResultCode.Fail,
286
- message: `Client ${originId} disconnected`,
287
- data: null
288
- });
289
- });
290
- ws.on('error', err => {
291
- logger.error({
292
- code: ResultCode.Fail,
293
- message: `Client ${originId} error`,
294
- data: err
295
- });
296
- });
297
- };
298
- // 全量客户端
299
- const setFullClient = (originId, ws) => {
300
- fullClient.set(originId, ws);
301
- // 处理消息事件
302
- ws.on('message', (message) => {
303
- // tudo
304
- // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
305
- // 导致无法进行多个平台连接。
306
- if (platformClient.size > 0) {
307
- platformClient.forEach((platformWs, platformId) => {
308
- // 检查平台客户端状态
309
- if (platformWs.readyState === WebSocket.OPEN) {
310
- platformWs.send(message);
311
- }
312
- else {
313
- // 如果连接已关闭,删除该平台客户端
314
- platformClient.delete(platformId);
315
- }
316
- });
244
+ else {
245
+ // 如果连接已关闭,删除该平台客户端
246
+ platformClient.delete(originId);
317
247
  }
318
248
  });
319
- // 处理关闭事件
320
- ws.on('close', () => {
321
- fullClient.delete(originId);
322
- logger.debug({
323
- code: ResultCode.Fail,
324
- message: `Client ${originId} disconnected`,
325
- data: null
326
- });
327
- });
328
- };
329
- // 处理客户端连接
330
- global.chatbotServer.on('connection', (ws, request) => {
331
- // 测试平台的连接
332
- if (request.url === '/testone') {
333
- connectionTestOne(ws, request);
334
- return;
335
- }
336
- // 读取请求头中的 来源
337
- const headers = request.headers;
338
- const origin = headers[USER_AGENT_HEADER] || USER_AGENT_HEADER_VALUE_MAP.client;
339
- // 来源id
340
- const originId = headers[DEVICE_ID_HEADER];
341
- if (!originId) {
342
- // 如果没有来源 ID,拒绝连接
343
- ws.close(4000, 'Missing Device ID');
344
- return;
345
- }
346
- logger.debug({
347
- code: ResultCode.Ok,
348
- message: `Client ${originId} connected`,
349
- data: null
350
- });
351
- // 根据来源进行分类
352
- if (origin === USER_AGENT_HEADER_VALUE_MAP.platform) {
353
- setPlatformClient(originId, ws);
354
- return;
355
- }
356
- else if (origin === USER_AGENT_HEADER_VALUE_MAP.client) {
357
- // 连接时,需要给客户端发送主动消息
358
- ws.send(flattedJSON.stringify({
359
- active: 'sync',
360
- payload: {
361
- value: getConfig().value,
362
- args: getConfig().argv,
363
- package: {
364
- version: getConfig().package?.version
365
- },
366
- env: {
367
- login: process.env.login,
368
- platform: process.env.platform,
369
- port: process.env.port
370
- }
371
- },
372
- // 主动消息
373
- activeId: originId
374
- }));
375
- }
376
- const isFullReceive = headers[FULL_RECEIVE_HEADER] === '1';
377
- // 如果是全量接收
378
- if (isFullReceive) {
379
- setFullClient(originId, ws);
380
- return;
381
- }
382
- setChildrenClient(originId, ws);
249
+ }
250
+ });
251
+ // 处理关闭事件
252
+ ws.on('close', () => {
253
+ delete childrenClient[originId];
254
+ logger.debug({
255
+ code: ResultCode.Fail,
256
+ message: `Client ${originId} disconnected`,
257
+ data: null
383
258
  });
384
- chatbotServer.on('error', (err) => {
385
- // 清理所有客户端连接
386
- platformClient.clear();
387
- childrenClient.clear();
388
- fullClient.clear();
389
- // 发现是端口已经被占用
390
- if (err.code === 'EADDRINUSE') {
391
- logger.error({
392
- code: ResultCode.FailInternal,
393
- message: `端口 ${port} 已被占用,请检查是否有其他服务在运行`,
394
- data: err.message
395
- });
396
- const reCreateTime = getReConnectTime();
397
- // 清理所有客户端连接,开始重新创建服务器
398
- setTimeout(() => {
399
- createServer();
400
- }, reCreateTime);
401
- }
402
- else {
403
- logger.error({
404
- code: ResultCode.FailInternal,
405
- message: 'WebSocket server error',
406
- data: err.message || 'Unknown error'
407
- });
408
- }
259
+ });
260
+ ws.on('error', err => {
261
+ logger.error({
262
+ code: ResultCode.Fail,
263
+ message: `Client ${originId} error`,
264
+ data: err
409
265
  });
410
- chatbotServer.on('close', () => {
411
- logger.info({
412
- code: ResultCode.Ok,
413
- message: 'WebSocket server closed',
414
- data: null
266
+ });
267
+ };
268
+ // 全量客户端
269
+ const setFullClient = (originId, ws) => {
270
+ fullClient.set(originId, ws);
271
+ // 处理消息事件
272
+ ws.on('message', (message) => {
273
+ // tudo
274
+ // 为什么 子客户端的行为,不携带目标平台的 DeviceId?
275
+ // 导致无法进行多个平台连接。
276
+ if (platformClient.size > 0) {
277
+ platformClient.forEach(platformWs => {
278
+ // 检查平台客户端状态
279
+ if (platformWs.readyState === WebSocket.OPEN) {
280
+ platformWs.send(message);
281
+ }
282
+ else {
283
+ // 如果连接已关闭,删除该平台客户端
284
+ platformClient.delete(originId);
285
+ }
415
286
  });
416
- // 清理所有客户端连接
417
- platformClient.clear();
418
- childrenClient.clear();
419
- fullClient.clear();
287
+ }
288
+ });
289
+ // 处理关闭事件
290
+ ws.on('close', () => {
291
+ delete fullClient[originId];
292
+ logger.debug({
293
+ code: ResultCode.Fail,
294
+ message: `Client ${originId} disconnected`,
295
+ data: null
420
296
  });
297
+ });
298
+ };
299
+ // 处理客户端连接
300
+ global.chatbotServer.on('connection', (ws, request) => {
301
+ // 读取请求头中的 来源
302
+ const headers = request.headers;
303
+ const origin = headers[USER_AGENT_HEADER] || 'client';
304
+ // 来源id
305
+ const originId = headers[DEVICE_ID_HEADER];
306
+ if (!originId) {
307
+ // 如果没有来源 ID,拒绝连接
308
+ ws.close(4000, 'Missing Device ID');
309
+ return;
421
310
  }
422
- catch (error) {
423
- logger.error({
424
- code: ResultCode.FailInternal,
425
- message: '创建 CBP 服务器失败',
426
- data: error
427
- });
311
+ logger.debug({
312
+ code: ResultCode.Ok,
313
+ message: `Client ${originId} connected`,
314
+ data: null
315
+ });
316
+ // 根据来源进行分类
317
+ if (origin === 'platform') {
318
+ setPlatformClient(originId, ws);
428
319
  return;
429
320
  }
430
- };
431
- createServer();
321
+ // 连接时,需要给客户端发送主动消息
322
+ ws.send(flattedJSON.stringify({
323
+ active: 'sync',
324
+ payload: {
325
+ value: getConfig().value,
326
+ args: getConfig().argv,
327
+ package: {
328
+ version: getConfig().package?.version
329
+ },
330
+ env: {
331
+ login: process.env.login,
332
+ platform: process.env.platform,
333
+ port: process.env.port
334
+ }
335
+ },
336
+ // 主动消息
337
+ activeId: originId
338
+ }));
339
+ const isFullReceive = headers[FULL_RECEIVE_HEADER] === '1';
340
+ // 如果是全量接收
341
+ if (isFullReceive) {
342
+ setFullClient(originId, ws);
343
+ return;
344
+ }
345
+ setChildrenClient(originId, ws);
346
+ });
432
347
  };
433
348
 
434
349
  export { cbpServer };
package/lib/cbp/router.js CHANGED
@@ -1,10 +1,25 @@
1
1
  import KoaRouter from 'koa-router';
2
+ import fs, { existsSync } from 'fs';
3
+ import path, { join, dirname } from 'path';
4
+ import mime from 'mime-types';
5
+ import { createRequire } from 'module';
2
6
 
7
+ const require = createRequire(import.meta.url);
8
+ const mainDirMap = new Map();
9
+ const formatPath = (path) => {
10
+ const pates = path.split('/');
11
+ const lastPath = pates[pates.length - 1];
12
+ if (lastPath.includes('.')) {
13
+ return path;
14
+ }
15
+ path += '.html';
16
+ return path;
17
+ };
3
18
  const router = new KoaRouter({
4
- prefix: '/api'
19
+ prefix: '/'
5
20
  });
6
21
  // 响应服务在线
7
- router.get('/online', ctx => {
22
+ router.get('api/online', ctx => {
8
23
  ctx.status = 200;
9
24
  ctx.body = {
10
25
  code: 200,
@@ -12,5 +27,149 @@ router.get('/online', ctx => {
12
27
  data: null
13
28
  };
14
29
  });
30
+ router.get('app/{*path}', async (ctx) => {
31
+ if (!process.env.input) {
32
+ ctx.status = 400;
33
+ ctx.body = {
34
+ code: 400,
35
+ message: '没有主要入口文件',
36
+ data: null
37
+ };
38
+ return;
39
+ }
40
+ const rootPath = process.cwd();
41
+ if (ctx.path.startsWith(`/app/api`)) {
42
+ let mainPath = join(rootPath, process.env.input);
43
+ // 路径
44
+ if (!existsSync(mainPath)) {
45
+ ctx.status = 400;
46
+ ctx.body = {
47
+ code: 400,
48
+ message: '未找到主要入口文件',
49
+ data: null
50
+ };
51
+ return;
52
+ }
53
+ const mainDir = dirname(mainPath);
54
+ try {
55
+ const dir = join(mainDir, 'route', ctx.path);
56
+ if (!existsSync(dir)) {
57
+ ctx.status = 404;
58
+ ctx.body = {
59
+ code: 404,
60
+ message: `API 'route/${ctx.path}' 未找到。`,
61
+ data: null
62
+ };
63
+ return;
64
+ }
65
+ const apiModule = await import(dir);
66
+ await apiModule.default(ctx);
67
+ }
68
+ catch (err) {
69
+ console.error(`Error handling API request ${ctx.path}:`, err);
70
+ ctx.status = 500;
71
+ ctx.body = {
72
+ code: 500,
73
+ message: `处理 API 请求时发生错误。`,
74
+ error: err.message
75
+ };
76
+ }
77
+ return;
78
+ }
79
+ const resourcePath = formatPath(ctx.params?.path || 'index.html');
80
+ const fullPath = path.join(rootPath, resourcePath);
81
+ try {
82
+ // 返回文件
83
+ const file = await fs.promises.readFile(fullPath);
84
+ const mimeType = mime.lookup(fullPath) || 'application/octet-stream';
85
+ ctx.set('Content-Type', mimeType); // 自动设置响应头
86
+ ctx.body = file;
87
+ ctx.status = 200;
88
+ }
89
+ catch (err) {
90
+ if (err.status === 404) {
91
+ ctx.status = 404;
92
+ ctx.body = {
93
+ code: 404,
94
+ message: `资源中未找到。`,
95
+ data: null
96
+ };
97
+ }
98
+ else {
99
+ ctx.status = 500;
100
+ ctx.body = {
101
+ code: 500,
102
+ message: `加载资源时发生服务器错误。`,
103
+ error: err.message
104
+ };
105
+ }
106
+ }
107
+ });
108
+ router.get('apps/:app/{*path}', async (ctx) => {
109
+ const appName = ctx.params.app;
110
+ const rootPath = process.cwd();
111
+ const apiDir = `/apps/${appName}/api`;
112
+ if (ctx.path.startsWith(apiDir)) {
113
+ try {
114
+ if (!mainDirMap.has(appName)) {
115
+ const mainPath = require.resolve(appName);
116
+ // 不存在 main
117
+ if (!existsSync(mainPath)) {
118
+ ctx.status = 400;
119
+ ctx.body = {
120
+ code: 400,
121
+ message: '未找到主要入口文件',
122
+ data: null
123
+ };
124
+ return;
125
+ }
126
+ const mainDir = dirname(mainPath);
127
+ mainDirMap.set(appName, mainDir);
128
+ }
129
+ const dir = join(mainDirMap.get(appName), 'route', ctx.path?.replace(apiDir, '/api') || '');
130
+ const apiModule = await import(dir);
131
+ await apiModule.default(ctx);
132
+ }
133
+ catch (err) {
134
+ logger.warn(`Error handling API request ${ctx.path}:`, err?.message || '');
135
+ ctx.status = 500;
136
+ ctx.body = {
137
+ code: 500,
138
+ message: `处理 API 请求时发生错误。`,
139
+ error: err.message
140
+ };
141
+ }
142
+ return;
143
+ }
144
+ const resourcePath = formatPath(ctx.params?.path || 'index.html');
145
+ const fullPath = path.join(rootPath, 'packages', appName, resourcePath);
146
+ try {
147
+ // 返回文件
148
+ const file = await fs.promises.readFile(fullPath);
149
+ const mimeType = mime.lookup(fullPath) || 'application/octet-stream';
150
+ ctx.set('Content-Type', mimeType); // 自动设置响应头
151
+ ctx.body = file;
152
+ ctx.status = 200;
153
+ }
154
+ catch (err) {
155
+ if (err.status === 404) {
156
+ ctx.status = 404;
157
+ ctx.body = {
158
+ code: 404,
159
+ message: `资源 '${resourcePath}' 在子应用 '${appName}' 中未找到。`,
160
+ data: null
161
+ };
162
+ }
163
+ else {
164
+ ctx.status = 500;
165
+ ctx.body = {
166
+ code: 500,
167
+ message: `加载子应用 '${appName}' 资源时发生服务器错误。`,
168
+ error: err.message
169
+ };
170
+ logger.warn(`Error handling API request ${ctx.path}:`, err?.message || '');
171
+ }
172
+ }
173
+ });
15
174
 
16
175
  export { router as default };
@@ -185,7 +185,6 @@ const connectionTestOne = (ws, _request) => {
185
185
  try {
186
186
  const messages = JSON.parse(readFileSync(messagePath, 'utf-8'));
187
187
  const updatedMessages = messages.filter((msg) => msg.CreateAt !== CreateAt);
188
- console.log('updatedMessages', updatedMessages);
189
188
  writeFile(messagePath, JSON.stringify(updatedMessages, null, 2), error => {
190
189
  if (error) {
191
190
  logger.error(`写入 ${type} 消息失败:`, error);
package/lib/global.d.ts CHANGED
@@ -79,6 +79,7 @@ declare global {
79
79
  login?: string;
80
80
  platform?: string;
81
81
  port?: string;
82
+ input?: string;
82
83
  NODE_ENV?: 'development' | 'production';
83
84
  }
84
85
  }
package/lib/main.js CHANGED
@@ -80,8 +80,8 @@ const start = async (options = {}) => {
80
80
  // 设置环境变量
81
81
  process.env.port = port;
82
82
  cbpServer(port, async () => {
83
- console.log(`ws://127.0.0.1:${port}`);
84
83
  const url = `ws://127.0.0.1:${port}`;
84
+ logger.info(`[CBP server started at ${url}]`);
85
85
  const isFullReceive = options?.is_full_receive || cfg.argv?.is_full_receive || cfg.value?.is_full_receive || true;
86
86
  cbpClient(url, { isFullReceive });
87
87
  // 加载平台服务
@@ -121,6 +121,7 @@ const start = async (options = {}) => {
121
121
  }
122
122
  // 获取入口文件
123
123
  const input = options.input || cfg.argv?.input || cfg.value?.input || getInputExportPath();
124
+ process.env.input = input;
124
125
  // 运行本地模块
125
126
  run(input);
126
127
  // load module
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alemonjs",
3
- "version": "2.1.0-alpha.30",
3
+ "version": "2.1.0-alpha.32",
4
4
  "description": "bot script",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",
@@ -31,10 +31,11 @@
31
31
  "commander": "^13.1.0",
32
32
  "file-type": "21.0.0",
33
33
  "flatted": "^3.3.3",
34
- "koa": "^2.15.3",
35
- "koa-router": "^13.0.1",
34
+ "koa": "^3.0.1",
35
+ "koa-router": "^14.0.0",
36
36
  "koa-static": "^5.0.0",
37
37
  "log4js": "^6.9.1",
38
+ "mime-types": "^3.0.1",
38
39
  "public-ip": "^7.0.1",
39
40
  "qrcode": "^1.5.4",
40
41
  "uuid": "11.1.0",
@@ -48,6 +49,7 @@
48
49
  "@types/koa-router": "^7.4.8",
49
50
  "@types/koa-static": "^4.0.4",
50
51
  "@types/koa__cors": "^5.0.0",
52
+ "@types/mime-types": "^3.0.1",
51
53
  "@types/uuid": "^10.0.0"
52
54
  },
53
55
  "bin": {
@@ -1,20 +0,0 @@
1
- const EventsKeyEnum = [
2
- 'message.create',
3
- 'message.update',
4
- 'message.delete',
5
- 'message.reaction.add',
6
- 'message.reaction.remove',
7
- 'private.message.create',
8
- 'private.message.update',
9
- 'private.message.delete',
10
- 'private.friend.add',
11
- 'private.guild.add',
12
- 'channal.create',
13
- 'channal.delete',
14
- 'guild.join',
15
- 'guild.exit',
16
- 'member.add',
17
- 'member.remove'
18
- ];
19
-
20
- export { EventsKeyEnum };