@kevisual/router 0.0.47 → 0.0.49

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/dist/router.d.ts CHANGED
@@ -405,6 +405,7 @@ type ServerOpts<T = {}> = {
405
405
  }) => any;
406
406
  cors?: Cors$2;
407
407
  io?: boolean;
408
+ showConnected?: boolean;
408
409
  } & T;
409
410
  interface ServerType {
410
411
  path?: string;
@@ -427,17 +428,18 @@ interface ServerType {
427
428
  */
428
429
  on(listener: OnListener): void;
429
430
  onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
430
- onWsClose(ws: WS): void;
431
+ onWsClose<T = {}>(ws: WS<T>): void;
432
+ sendConnected<T = {}>(ws: WS<T>): void;
431
433
  }
432
- type OnWebSocketOptions = {
433
- ws: WS;
434
+ type OnWebSocketOptions<T = {}> = {
435
+ ws: WS<T>;
434
436
  message: string | Buffer;
435
437
  pathname: string;
436
438
  token?: string;
437
439
  id?: string;
438
440
  };
439
441
  type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
440
- type WS = {
442
+ type WS<T = {}> = {
441
443
  send: (data: any) => void;
442
444
  close: (code?: number, reason?: string) => void;
443
445
  data?: {
@@ -449,20 +451,25 @@ type WS = {
449
451
  * 鉴权后的获取的信息
450
452
  */
451
453
  userApp?: string;
452
- };
454
+ } & T;
453
455
  };
454
456
  type Listener = {
455
457
  id?: string;
456
458
  io?: boolean;
457
459
  path?: string;
458
460
  func: WebSocketListenerFun | HttpListenerFun;
461
+ /**
462
+ * @description 是否默认解析为 JSON,如果为 true,则 message 会被 JSON.parse 处理,默认是 true
463
+ */
464
+ json?: boolean;
459
465
  };
460
466
  type WebSocketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
461
467
  type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
462
- type WebSocketReq = {
468
+ type WebSocketReq<T = {}, U = Record<string, any>> = {
463
469
  emitter?: EventEmitter;
464
- ws: WS;
465
- data: any;
470
+ ws: WS<T>;
471
+ data?: U;
472
+ message?: string | Buffer;
466
473
  pathname?: string;
467
474
  token?: string;
468
475
  id?: string;
@@ -480,6 +487,7 @@ type RouterReq<T = {}> = {
480
487
  remoteAddress?: string;
481
488
  remotePort?: number;
482
489
  };
490
+ body?: string;
483
491
  cookies?: Record<string, string>;
484
492
  } & T;
485
493
  type RouterRes<T = {}> = {
@@ -617,6 +625,7 @@ declare class ServerBase implements ServerType {
617
625
  cors: Cors$1;
618
626
  listeners: Listener[];
619
627
  emitter: EventEmitter$1<any>;
628
+ showConnected: boolean;
620
629
  constructor(opts?: ServerOpts);
621
630
  listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
622
631
  listen(port: number, hostname?: string, listeningListener?: () => void): void;
@@ -644,6 +653,7 @@ declare class ServerBase implements ServerType {
644
653
  on(listener: OnListener): void;
645
654
  onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): Promise<void>;
646
655
  onWsClose(ws: WS): Promise<void>;
656
+ sendConnected(ws: WS): Promise<void>;
647
657
  }
648
658
 
649
659
  type WsServerBaseOpts = {
package/dist/router.js CHANGED
@@ -1215,10 +1215,12 @@ class ServerBase {
1215
1215
  cors;
1216
1216
  listeners = [];
1217
1217
  emitter = new EventEmitter();
1218
+ showConnected = true;
1218
1219
  constructor(opts) {
1219
1220
  this.path = opts?.path || '/api/router';
1220
1221
  this.handle = opts?.handle;
1221
1222
  this.cors = opts?.cors;
1223
+ this.showConnected = opts?.showConnected !== false;
1222
1224
  }
1223
1225
  listen(...args) {
1224
1226
  this.customListen(...args);
@@ -1323,14 +1325,15 @@ class ServerBase {
1323
1325
  }
1324
1326
  on(listener) {
1325
1327
  this.listeners = [];
1328
+ const randomId = Math.random().toString(36).substring(2, 15);
1326
1329
  if (typeof listener === 'function') {
1327
- this.listeners.push({ func: listener });
1330
+ this.listeners.push({ func: listener, id: 'all-' + randomId });
1328
1331
  return;
1329
1332
  }
1330
1333
  if (Array.isArray(listener)) {
1331
1334
  for (const item of listener) {
1332
1335
  if (typeof item === 'function') {
1333
- this.listeners.push({ func: item });
1336
+ this.listeners.push({ func: item, id: 'all-' + randomId });
1334
1337
  }
1335
1338
  else {
1336
1339
  this.listeners.push(item);
@@ -1343,20 +1346,28 @@ class ServerBase {
1343
1346
  }
1344
1347
  async onWebSocket({ ws, message, pathname, token, id }) {
1345
1348
  const listener = this.listeners.find((item) => item.path === pathname && item.io);
1346
- const data = parseIfJson(message);
1347
1349
  if (listener) {
1348
1350
  const end = (data) => {
1349
1351
  ws.send(JSON.stringify(data));
1350
1352
  };
1353
+ let data = {};
1354
+ const isJson = listener.json !== false;
1355
+ if (isJson) {
1356
+ data = parseIfJson(message);
1357
+ }
1351
1358
  listener.func({
1352
1359
  emitter: this.emitter,
1353
1360
  data,
1354
1361
  token,
1362
+ message,
1363
+ pathname,
1355
1364
  id,
1356
1365
  ws,
1357
1366
  }, { end });
1358
1367
  return;
1359
1368
  }
1369
+ // 默认处理方案,直接调用 handle 方法
1370
+ const data = parseIfJson(message);
1360
1371
  if (typeof data === 'string') {
1361
1372
  const cleanMessage = data.trim().replace(/^["']|["']$/g, '');
1362
1373
  if (cleanMessage === 'close') {
@@ -1419,6 +1430,10 @@ class ServerBase {
1419
1430
  }, 5000);
1420
1431
  }
1421
1432
  }
1433
+ async sendConnected(ws) {
1434
+ if (this.showConnected)
1435
+ ws.send(JSON.stringify({ type: 'connected' }));
1436
+ }
1422
1437
  }
1423
1438
 
1424
1439
  function getDefaultExportFromCjs (x) {
@@ -6373,7 +6388,7 @@ class WsServerBase {
6373
6388
  ws.on('message', async (message) => {
6374
6389
  await this.server.onWebSocket({ ws, message, pathname, token, id });
6375
6390
  });
6376
- ws.send(JSON.stringify({ type: 'connected' }));
6391
+ this.server.sendConnected(ws);
6377
6392
  this.wss.on('close', () => {
6378
6393
  this.server.onWsClose(ws);
6379
6394
  });
@@ -6538,7 +6553,7 @@ class BunServer extends ServerBase {
6538
6553
  return new Response('WebSocket upgrade failed', { status: 400 });
6539
6554
  }
6540
6555
  // 将 Bun 的 Request 转换为 Node.js 风格的 req/res
6541
- return new Promise((resolve) => {
6556
+ return new Promise(async (resolve) => {
6542
6557
  const req = {
6543
6558
  url: url.pathname + url.search,
6544
6559
  method: request.method,
@@ -6547,6 +6562,11 @@ class BunServer extends ServerBase {
6547
6562
  // @ts-ignore
6548
6563
  remoteAddress: request?.remoteAddress || request?.ip || clientInfo?.address || '',
6549
6564
  remotePort: clientInfo?.port || 0,
6565
+ },
6566
+ // @ts-ignore
6567
+ bun: {
6568
+ request, // 原始请求对象
6569
+ server, // 原始服务器对象
6550
6570
  }
6551
6571
  };
6552
6572
  const res = {
@@ -6672,10 +6692,27 @@ class BunServer extends ServerBase {
6672
6692
  };
6673
6693
  // 处理请求体
6674
6694
  if (request.method !== 'GET' && request.method !== 'HEAD') {
6675
- request.text().then((body) => {
6676
- req.body = body;
6695
+ const contentType = request.headers.get('content-type') || '';
6696
+ if (contentType.includes('application/json')) {
6697
+ const text = await request.text();
6698
+ req.body = text;
6677
6699
  requestCallback(req, res);
6678
- });
6700
+ return;
6701
+ }
6702
+ else if (contentType.includes('application/x-www-form-urlencoded')) {
6703
+ const formData = await request.formData();
6704
+ const body = {};
6705
+ for (const [key, value] of formData.entries()) {
6706
+ body[key] = value;
6707
+ }
6708
+ req.body = JSON.stringify(body);
6709
+ requestCallback(req, res);
6710
+ return;
6711
+ }
6712
+ else {
6713
+ requestCallback(req, res);
6714
+ return;
6715
+ }
6679
6716
  }
6680
6717
  else {
6681
6718
  requestCallback(req, res);
@@ -6684,7 +6721,7 @@ class BunServer extends ServerBase {
6684
6721
  },
6685
6722
  websocket: {
6686
6723
  open: (ws) => {
6687
- ws.send(JSON.stringify({ type: 'connected' }));
6724
+ this.sendConnected(ws);
6688
6725
  },
6689
6726
  message: async (ws, message) => {
6690
6727
  const pathname = ws.data.pathname || '';
@@ -11181,7 +11218,7 @@ class App {
11181
11218
  }
11182
11219
  this.server.on({
11183
11220
  id: 'app-request-listener',
11184
- fun: fn,
11221
+ func: fn,
11185
11222
  });
11186
11223
  }
11187
11224
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@kevisual/router",
4
- "version": "0.0.47",
4
+ "version": "0.0.49",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
@@ -84,11 +84,6 @@
84
84
  "require": "./dist/router-define.js",
85
85
  "types": "./dist/router-define.d.ts"
86
86
  },
87
- "./simple-lib": {
88
- "import": "./dist/router-simple-lib.js",
89
- "require": "./dist/router-simple-lib.js",
90
- "types": "./dist/router-simple-lib.d.ts"
91
- },
92
87
  "./mod.ts": {
93
88
  "import": "./mod.ts",
94
89
  "require": "./mod.ts",
package/src/app.ts CHANGED
@@ -134,7 +134,7 @@ export class App<U = {}> {
134
134
  }
135
135
  this.server.on({
136
136
  id: 'app-request-listener',
137
- fun: fn as any,
137
+ func: fn as any,
138
138
  });
139
139
  }
140
140
  }
@@ -1,7 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  import { handleServer } from './handle-server.ts';
3
3
  import * as cookie from './cookie.ts';
4
- import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebScoketListenerFun, ListenerFun, HttpListenerFun, WS } from './server-type.ts';
4
+ import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebSocketListenerFun, ListenerFun, HttpListenerFun, WS } from './server-type.ts';
5
5
  import { parseIfJson } from '../utils/parse.ts';
6
6
  import { EventEmitter } from 'events';
7
7
  type CookieFn = (name: string, value: string, options?: cookie.SerializeOptions, end?: boolean) => void;
@@ -64,11 +64,12 @@ export class ServerBase implements ServerType {
64
64
  cors: Cors;
65
65
  listeners: Listener[] = [];
66
66
  emitter = new EventEmitter();
67
+ showConnected = true;
67
68
  constructor(opts?: ServerOpts) {
68
69
  this.path = opts?.path || '/api/router';
69
70
  this.handle = opts?.handle;
70
71
  this.cors = opts?.cors;
71
-
72
+ this.showConnected = opts?.showConnected !== false;
72
73
  }
73
74
  listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
74
75
  listen(port: number, hostname?: string, listeningListener?: () => void): void;
@@ -178,14 +179,15 @@ export class ServerBase implements ServerType {
178
179
  }
179
180
  on(listener: OnListener) {
180
181
  this.listeners = [];
182
+ const randomId = Math.random().toString(36).substring(2, 15);
181
183
  if (typeof listener === 'function') {
182
- this.listeners.push({ func: listener });
184
+ this.listeners.push({ func: listener, id: 'all-' + randomId });
183
185
  return;
184
186
  }
185
187
  if (Array.isArray(listener)) {
186
188
  for (const item of listener) {
187
189
  if (typeof item === 'function') {
188
- this.listeners.push({ func: item });
190
+ this.listeners.push({ func: item, id: 'all-' + randomId });
189
191
  } else {
190
192
  this.listeners.push(item);
191
193
  }
@@ -196,22 +198,29 @@ export class ServerBase implements ServerType {
196
198
  }
197
199
  async onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions) {
198
200
  const listener = this.listeners.find((item) => item.path === pathname && item.io);
199
- const data: any = parseIfJson(message);
200
201
 
201
202
  if (listener) {
202
203
  const end = (data: any) => {
203
204
  ws.send(JSON.stringify(data));
204
205
  }
205
- (listener.func as WebScoketListenerFun)({
206
+ let data: any = {};
207
+ const isJson = listener.json !== false;
208
+ if (isJson) {
209
+ data = parseIfJson(message);
210
+ }
211
+ (listener.func as WebSocketListenerFun)({
206
212
  emitter: this.emitter,
207
213
  data,
208
214
  token,
215
+ message,
216
+ pathname,
209
217
  id,
210
218
  ws,
211
219
  }, { end });
212
220
  return;
213
221
  }
214
-
222
+ // 默认处理方案,直接调用 handle 方法
223
+ const data: any = parseIfJson(message);
215
224
  if (typeof data === 'string') {
216
225
  const cleanMessage = data.trim().replace(/^["']|["']$/g, '');
217
226
  if (cleanMessage === 'close') {
@@ -275,4 +284,8 @@ export class ServerBase implements ServerType {
275
284
  }, 5000);
276
285
  }
277
286
  }
287
+ async sendConnected(ws: WS) {
288
+ if (this.showConnected)
289
+ ws.send(JSON.stringify({ type: 'connected' }));
290
+ }
278
291
  }
@@ -71,7 +71,7 @@ export class BunServer extends ServerBase implements ServerType {
71
71
  }
72
72
 
73
73
  // 将 Bun 的 Request 转换为 Node.js 风格的 req/res
74
- return new Promise((resolve) => {
74
+ return new Promise(async (resolve) => {
75
75
  const req: RouterReq = {
76
76
  url: url.pathname + url.search,
77
77
  method: request.method,
@@ -80,6 +80,11 @@ export class BunServer extends ServerBase implements ServerType {
80
80
  // @ts-ignore
81
81
  remoteAddress: request?.remoteAddress || request?.ip || clientInfo?.address || '',
82
82
  remotePort: clientInfo?.port || 0,
83
+ },
84
+ // @ts-ignore
85
+ bun: {
86
+ request, // 原始请求对象
87
+ server, // 原始服务器对象
83
88
  }
84
89
  };
85
90
 
@@ -212,10 +217,25 @@ export class BunServer extends ServerBase implements ServerType {
212
217
  };
213
218
  // 处理请求体
214
219
  if (request.method !== 'GET' && request.method !== 'HEAD') {
215
- request.text().then((body) => {
216
- (req as any).body = body;
220
+ const contentType = request.headers.get('content-type') || '';
221
+ if (contentType.includes('application/json')) {
222
+ const text = await request.text();
223
+ req.body = text;
217
224
  requestCallback(req, res);
218
- });
225
+ return;
226
+ } else if (contentType.includes('application/x-www-form-urlencoded')) {
227
+ const formData = await request.formData();
228
+ const body: Record<string, any> = {};
229
+ for (const [key, value] of formData.entries()) {
230
+ body[key] = value;
231
+ }
232
+ req.body = JSON.stringify(body);
233
+ requestCallback(req, res);
234
+ return;
235
+ } else {
236
+ requestCallback(req, res);
237
+ return;
238
+ }
219
239
  } else {
220
240
  requestCallback(req, res);
221
241
  }
@@ -223,7 +243,7 @@ export class BunServer extends ServerBase implements ServerType {
223
243
  },
224
244
  websocket: {
225
245
  open: (ws: any) => {
226
- ws.send(JSON.stringify({ type: 'connected' }));
246
+ this.sendConnected(ws);
227
247
  },
228
248
  message: async (ws: any, message: string | Buffer) => {
229
249
  const pathname = ws.data.pathname || '';
@@ -16,6 +16,7 @@ export type ServerOpts<T = {}> = {
16
16
  handle?: (msg?: { path: string; key?: string;[key: string]: any }, ctx?: { req: http.IncomingMessage; res: http.ServerResponse }) => any;
17
17
  cors?: Cors;
18
18
  io?: boolean;
19
+ showConnected?: boolean;
19
20
  } & T;
20
21
 
21
22
  export interface ServerType {
@@ -39,12 +40,19 @@ export interface ServerType {
39
40
  */
40
41
  on(listener: OnListener): void;
41
42
  onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
42
- onWsClose(ws: WS): void;
43
+ onWsClose<T = {}>(ws: WS<T>): void;
44
+ sendConnected<T = {}>(ws: WS<T>): void;
43
45
  }
44
46
 
45
- export type OnWebSocketOptions = { ws: WS; message: string | Buffer; pathname: string, token?: string, id?: string }
47
+ export type OnWebSocketOptions<T = {}> = {
48
+ ws: WS<T>;
49
+ message: string | Buffer;
50
+ pathname: string,
51
+ token?: string,
52
+ id?: string,
53
+ }
46
54
  export type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
47
- export type WS = {
55
+ export type WS<T = {}> = {
48
56
  send: (data: any) => void;
49
57
  close: (code?: number, reason?: string) => void;
50
58
  data?: {
@@ -56,22 +64,27 @@ export type WS = {
56
64
  * 鉴权后的获取的信息
57
65
  */
58
66
  userApp?: string;
59
- }
67
+ } & T;
60
68
  }
61
69
  export type Listener = {
62
70
  id?: string;
63
71
  io?: boolean;
64
72
  path?: string;
65
73
  func: WebSocketListenerFun | HttpListenerFun;
74
+ /**
75
+ * @description 是否默认解析为 JSON,如果为 true,则 message 会被 JSON.parse 处理,默认是 true
76
+ */
77
+ json?: boolean,
66
78
  }
67
79
 
68
80
  export type WebSocketListenerFun = (req: WebSocketReq, res: WebSocketRes) => Promise<void> | void;
69
81
  export type HttpListenerFun = (req: RouterReq, res: RouterRes) => Promise<void> | void;
70
82
 
71
- export type WebSocketReq = {
83
+ export type WebSocketReq<T = {}, U = Record<string, any>> = {
72
84
  emitter?: EventEmitter;
73
- ws: WS;
74
- data: any;
85
+ ws: WS<T>;
86
+ data?: U;
87
+ message?: string | Buffer;
75
88
  pathname?: string;
76
89
  token?: string;
77
90
  id?: string;
@@ -89,6 +102,7 @@ export type RouterReq<T = {}> = {
89
102
  remoteAddress?: string;
90
103
  remotePort?: number;
91
104
  };
105
+ body?: string;
92
106
  cookies?: Record<string, string>;
93
107
  } & T;
94
108
 
@@ -60,7 +60,7 @@ export class WsServerBase {
60
60
  ws.on('message', async (message: string | Buffer) => {
61
61
  await this.server.onWebSocket({ ws, message, pathname, token, id });
62
62
  });
63
- ws.send(JSON.stringify({ type: 'connected' }));
63
+ this.server.sendConnected(ws);
64
64
  this.wss.on('close', () => {
65
65
  this.server.onWsClose(ws);
66
66
  });
@@ -1,3 +0,0 @@
1
- declare const parseXml: (req: any) => Promise<any>;
2
-
3
- export { parseXml };
@@ -1,35 +0,0 @@
1
- import xml2js from 'xml2js';
2
-
3
- const parseXml = async (req) => {
4
- return await new Promise((resolve) => {
5
- // 读取请求数据
6
- let data = '';
7
- req.setEncoding('utf8');
8
- // 监听data事件,接收数据片段
9
- req.on('data', (chunk) => {
10
- data += chunk;
11
- });
12
- // 当请求结束时处理数据
13
- req.on('end', () => {
14
- try {
15
- // 使用xml2js解析XML
16
- xml2js.parseString(data, function (err, result) {
17
- if (err) {
18
- console.error('XML解析错误:', err);
19
- resolve(null);
20
- }
21
- else {
22
- const jsonString = JSON.stringify(result);
23
- resolve(jsonString);
24
- }
25
- });
26
- }
27
- catch (error) {
28
- console.error('处理请求时出错:', error);
29
- resolve(null);
30
- }
31
- });
32
- });
33
- };
34
-
35
- export { parseXml };