@kevisual/router 0.1.1 → 0.1.2

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/ws.d.ts CHANGED
@@ -194,14 +194,6 @@ type RouteOpts<U = {}, T = SimpleObject> = {
194
194
  metadata?: T;
195
195
  middleware?: RouteMiddleware[];
196
196
  type?: 'route' | 'middleware' | 'compound';
197
- /**
198
- * $#$ will be used to split path and key
199
- */
200
- idUsePath?: boolean;
201
- /**
202
- * id 合并的分隔符,默认为 $#$
203
- */
204
- delimiter?: string;
205
197
  isDebug?: boolean;
206
198
  };
207
199
  type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'nextRoute'>;
package/dist/ws.js CHANGED
@@ -4,21 +4,35 @@ var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
7
12
  var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
8
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
22
  for (let key of __getOwnPropNames(mod))
11
23
  if (!__hasOwnProp.call(to, key))
12
24
  __defProp(to, key, {
13
- get: () => mod[key],
25
+ get: __accessProp.bind(mod, key),
14
26
  enumerable: true
15
27
  });
28
+ if (canCache)
29
+ cache.set(mod, to);
16
30
  return to;
17
31
  };
18
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
19
33
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
34
 
21
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/constants.js
35
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/constants.js
22
36
  var require_constants = __commonJS((exports, module) => {
23
37
  var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"];
24
38
  var hasBlob = typeof Blob !== "undefined";
@@ -26,6 +40,7 @@ var require_constants = __commonJS((exports, module) => {
26
40
  BINARY_TYPES.push("blob");
27
41
  module.exports = {
28
42
  BINARY_TYPES,
43
+ CLOSE_TIMEOUT: 30000,
29
44
  EMPTY_BUFFER: Buffer.alloc(0),
30
45
  GUID: "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
31
46
  hasBlob,
@@ -37,7 +52,7 @@ var require_constants = __commonJS((exports, module) => {
37
52
  };
38
53
  });
39
54
 
40
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/buffer-util.js
55
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/buffer-util.js
41
56
  var require_buffer_util = __commonJS((exports, module) => {
42
57
  var { EMPTY_BUFFER } = require_constants();
43
58
  var FastBuffer = Buffer[Symbol.species];
@@ -98,7 +113,7 @@ var require_buffer_util = __commonJS((exports, module) => {
98
113
  };
99
114
  });
100
115
 
101
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/limiter.js
116
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/limiter.js
102
117
  var require_limiter = __commonJS((exports, module) => {
103
118
  var kDone = Symbol("kDone");
104
119
  var kRun = Symbol("kRun");
@@ -130,7 +145,7 @@ var require_limiter = __commonJS((exports, module) => {
130
145
  module.exports = Limiter;
131
146
  });
132
147
 
133
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/permessage-deflate.js
148
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/permessage-deflate.js
134
149
  var require_permessage_deflate = __commonJS((exports, module) => {
135
150
  var zlib = __require("zlib");
136
151
  var bufferUtil = require_buffer_util();
@@ -385,12 +400,16 @@ var require_permessage_deflate = __commonJS((exports, module) => {
385
400
  }
386
401
  function inflateOnError(err) {
387
402
  this[kPerMessageDeflate]._inflate = null;
403
+ if (this[kError]) {
404
+ this[kCallback](this[kError]);
405
+ return;
406
+ }
388
407
  err[kStatusCode] = 1007;
389
408
  this[kCallback](err);
390
409
  }
391
410
  });
392
411
 
393
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/validation.js
412
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/validation.js
394
413
  var require_validation = __commonJS((exports, module) => {
395
414
  var { isUtf8 } = __require("buffer");
396
415
  var { hasBlob } = require_constants();
@@ -570,7 +589,7 @@ var require_validation = __commonJS((exports, module) => {
570
589
  }
571
590
  });
572
591
 
573
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/receiver.js
592
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/receiver.js
574
593
  var require_receiver = __commonJS((exports, module) => {
575
594
  var { Writable } = __require("stream");
576
595
  var PerMessageDeflate = require_permessage_deflate();
@@ -951,7 +970,7 @@ var require_receiver = __commonJS((exports, module) => {
951
970
  module.exports = Receiver;
952
971
  });
953
972
 
954
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/sender.js
973
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/sender.js
955
974
  var require_sender = __commonJS((exports, module) => {
956
975
  var { Duplex } = __require("stream");
957
976
  var { randomFillSync } = __require("crypto");
@@ -1305,7 +1324,7 @@ var require_sender = __commonJS((exports, module) => {
1305
1324
  }
1306
1325
  });
1307
1326
 
1308
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/event-target.js
1327
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/event-target.js
1309
1328
  var require_event_target = __commonJS((exports, module) => {
1310
1329
  var { kForOnEventAttribute, kListener } = require_constants();
1311
1330
  var kCode = Symbol("kCode");
@@ -1456,7 +1475,7 @@ var require_event_target = __commonJS((exports, module) => {
1456
1475
  }
1457
1476
  });
1458
1477
 
1459
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/extension.js
1478
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/extension.js
1460
1479
  var require_extension = __commonJS((exports, module) => {
1461
1480
  var { tokenChars } = require_validation();
1462
1481
  function push(dest, name, elem) {
@@ -1621,7 +1640,7 @@ var require_extension = __commonJS((exports, module) => {
1621
1640
  module.exports = { format, parse };
1622
1641
  });
1623
1642
 
1624
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/websocket.js
1643
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/websocket.js
1625
1644
  var require_websocket = __commonJS((exports, module) => {
1626
1645
  var EventEmitter = __require("events");
1627
1646
  var https = __require("https");
@@ -1637,6 +1656,7 @@ var require_websocket = __commonJS((exports, module) => {
1637
1656
  var { isBlob } = require_validation();
1638
1657
  var {
1639
1658
  BINARY_TYPES,
1659
+ CLOSE_TIMEOUT,
1640
1660
  EMPTY_BUFFER,
1641
1661
  GUID,
1642
1662
  kForOnEventAttribute,
@@ -1650,7 +1670,6 @@ var require_websocket = __commonJS((exports, module) => {
1650
1670
  } = require_event_target();
1651
1671
  var { format, parse } = require_extension();
1652
1672
  var { toBuffer } = require_buffer_util();
1653
- var closeTimeout = 30 * 1000;
1654
1673
  var kAborted = Symbol("kAborted");
1655
1674
  var protocolVersions = [8, 13];
1656
1675
  var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
@@ -1690,6 +1709,7 @@ var require_websocket = __commonJS((exports, module) => {
1690
1709
  initAsClient(this, address, protocols, options);
1691
1710
  } else {
1692
1711
  this._autoPong = options.autoPong;
1712
+ this._closeTimeout = options.closeTimeout;
1693
1713
  this._isServer = true;
1694
1714
  }
1695
1715
  }
@@ -1981,6 +2001,7 @@ var require_websocket = __commonJS((exports, module) => {
1981
2001
  const opts = {
1982
2002
  allowSynchronousEvents: true,
1983
2003
  autoPong: true,
2004
+ closeTimeout: CLOSE_TIMEOUT,
1984
2005
  protocolVersion: protocolVersions[1],
1985
2006
  maxPayload: 100 * 1024 * 1024,
1986
2007
  skipUTF8Validation: false,
@@ -1998,6 +2019,7 @@ var require_websocket = __commonJS((exports, module) => {
1998
2019
  port: undefined
1999
2020
  };
2000
2021
  websocket._autoPong = opts.autoPong;
2022
+ websocket._closeTimeout = opts.closeTimeout;
2001
2023
  if (!protocolVersions.includes(opts.protocolVersion)) {
2002
2024
  throw new RangeError(`Unsupported protocol version: ${opts.protocolVersion} ` + `(supported versions: ${protocolVersions.join(", ")})`);
2003
2025
  }
@@ -2336,7 +2358,7 @@ var require_websocket = __commonJS((exports, module) => {
2336
2358
  }
2337
2359
  }
2338
2360
  function setCloseTimer(websocket) {
2339
- websocket._closeTimer = setTimeout(websocket._socket.destroy.bind(websocket._socket), closeTimeout);
2361
+ websocket._closeTimer = setTimeout(websocket._socket.destroy.bind(websocket._socket), websocket._closeTimeout);
2340
2362
  }
2341
2363
  function socketOnClose() {
2342
2364
  const websocket = this[kWebSocket];
@@ -2344,8 +2366,8 @@ var require_websocket = __commonJS((exports, module) => {
2344
2366
  this.removeListener("data", socketOnData);
2345
2367
  this.removeListener("end", socketOnEnd);
2346
2368
  websocket._readyState = WebSocket.CLOSING;
2347
- let chunk;
2348
- if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && (chunk = websocket._socket.read()) !== null) {
2369
+ if (!this._readableState.endEmitted && !websocket._closeFrameReceived && !websocket._receiver._writableState.errorEmitted && this._readableState.length !== 0) {
2370
+ const chunk = this.read(this._readableState.length);
2349
2371
  websocket._receiver.write(chunk);
2350
2372
  }
2351
2373
  websocket._receiver.end();
@@ -2380,7 +2402,7 @@ var require_websocket = __commonJS((exports, module) => {
2380
2402
  }
2381
2403
  });
2382
2404
 
2383
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/stream.js
2405
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/stream.js
2384
2406
  var require_stream = __commonJS((exports, module) => {
2385
2407
  var WebSocket = require_websocket();
2386
2408
  var { Duplex } = __require("stream");
@@ -2483,7 +2505,7 @@ var require_stream = __commonJS((exports, module) => {
2483
2505
  module.exports = createWebSocketStream;
2484
2506
  });
2485
2507
 
2486
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/subprotocol.js
2508
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/subprotocol.js
2487
2509
  var require_subprotocol = __commonJS((exports, module) => {
2488
2510
  var { tokenChars } = require_validation();
2489
2511
  function parse(header) {
@@ -2528,7 +2550,7 @@ var require_subprotocol = __commonJS((exports, module) => {
2528
2550
  module.exports = { parse };
2529
2551
  });
2530
2552
 
2531
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/lib/websocket-server.js
2553
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/lib/websocket-server.js
2532
2554
  var require_websocket_server = __commonJS((exports, module) => {
2533
2555
  var EventEmitter = __require("events");
2534
2556
  var http = __require("http");
@@ -2538,7 +2560,7 @@ var require_websocket_server = __commonJS((exports, module) => {
2538
2560
  var PerMessageDeflate = require_permessage_deflate();
2539
2561
  var subprotocol = require_subprotocol();
2540
2562
  var WebSocket = require_websocket();
2541
- var { GUID, kWebSocket } = require_constants();
2563
+ var { CLOSE_TIMEOUT, GUID, kWebSocket } = require_constants();
2542
2564
  var keyRegex = /^[+/0-9A-Za-z]{22}==$/;
2543
2565
  var RUNNING = 0;
2544
2566
  var CLOSING = 1;
@@ -2555,6 +2577,7 @@ var require_websocket_server = __commonJS((exports, module) => {
2555
2577
  perMessageDeflate: false,
2556
2578
  handleProtocols: null,
2557
2579
  clientTracking: true,
2580
+ closeTimeout: CLOSE_TIMEOUT,
2558
2581
  verifyClient: null,
2559
2582
  noServer: false,
2560
2583
  backlog: null,
@@ -2675,9 +2698,11 @@ var require_websocket_server = __commonJS((exports, module) => {
2675
2698
  abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
2676
2699
  return;
2677
2700
  }
2678
- if (version !== 8 && version !== 13) {
2701
+ if (version !== 13 && version !== 8) {
2679
2702
  const message = "Missing or invalid Sec-WebSocket-Version header";
2680
- abortHandshakeOrEmitwsClientError(this, req, socket, 400, message);
2703
+ abortHandshakeOrEmitwsClientError(this, req, socket, 400, message, {
2704
+ "Sec-WebSocket-Version": "13, 8"
2705
+ });
2681
2706
  return;
2682
2707
  }
2683
2708
  if (!this.shouldHandle(req)) {
@@ -2816,18 +2841,18 @@ var require_websocket_server = __commonJS((exports, module) => {
2816
2841
  \r
2817
2842
  ` + message);
2818
2843
  }
2819
- function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {
2844
+ function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
2820
2845
  if (server.listenerCount("wsClientError")) {
2821
2846
  const err = new Error(message);
2822
2847
  Error.captureStackTrace(err, abortHandshakeOrEmitwsClientError);
2823
2848
  server.emit("wsClientError", err, socket, req);
2824
2849
  } else {
2825
- abortHandshake(socket, code, message);
2850
+ abortHandshake(socket, code, message, headers);
2826
2851
  }
2827
2852
  }
2828
2853
  });
2829
2854
 
2830
- // node_modules/.pnpm/@kevisual+ws@8.0.0/node_modules/@kevisual/ws/wrapper.mjs
2855
+ // ../../node_modules/.pnpm/@kevisual+ws@8.19.0/node_modules/@kevisual/ws/wrapper.mjs
2831
2856
  var import_stream = __toESM(require_stream(), 1);
2832
2857
  var import_receiver = __toESM(require_receiver(), 1);
2833
2858
  var import_sender = __toESM(require_sender(), 1);
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.1.1",
4
+ "version": "0.1.2",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "main": "./dist/router.js",
@@ -25,34 +25,39 @@
25
25
  "@kevisual/code-builder": "^0.0.6",
26
26
  "@kevisual/context": "^0.0.8",
27
27
  "@kevisual/dts": "^0.0.4",
28
- "@kevisual/js-filter": "^0.0.5",
28
+ "@kevisual/js-filter": "^0.0.6",
29
29
  "@kevisual/local-proxy": "^0.0.8",
30
30
  "@kevisual/query": "^0.0.53",
31
+ "@kevisual/remote-app": "^0.0.7",
31
32
  "@kevisual/use-config": "^1.0.30",
32
- "@opencode-ai/plugin": "^1.2.24",
33
+ "@opencode-ai/plugin": "^1.2.26",
33
34
  "@types/bun": "^1.3.10",
34
- "@types/node": "^25.4.0",
35
+ "@types/crypto-js": "^4.2.2",
36
+ "@types/node": "^25.5.0",
35
37
  "@types/send": "^1.2.1",
36
38
  "@types/ws": "^8.18.1",
37
39
  "@types/xml2js": "^0.4.14",
38
40
  "commander": "^14.0.3",
41
+ "crypto-js": "^4.2.0",
42
+ "es-toolkit": "^1.45.1",
39
43
  "eventemitter3": "^5.0.4",
40
44
  "fast-glob": "^3.3.3",
41
- "hono": "^4.12.7",
45
+ "hono": "^4.12.8",
42
46
  "nanoid": "^5.1.6",
43
47
  "path-to-regexp": "^8.3.0",
44
48
  "send": "^1.2.1",
45
49
  "typescript": "^5.9.3",
46
50
  "ws": "npm:@kevisual/ws",
47
- "xml2js": "^0.6.2",
48
- "zod": "^4.3.6"
51
+ "xml2js": "^0.6.2"
49
52
  },
50
53
  "repository": {
51
54
  "type": "git",
52
55
  "url": "git+https://github.com/abearxiong/kevisual-router.git"
53
56
  },
54
57
  "dependencies": {
55
- "es-toolkit": "^1.45.1"
58
+ "crypto-js": "^4.2.0",
59
+ "es-toolkit": "^1.45.1",
60
+ "zod": "^4.3.6"
56
61
  },
57
62
  "publishConfig": {
58
63
  "access": "public"
package/src/app.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AddOpts, QueryRouter, QueryRouterServer, Route, RouteContext, RouteOpts } from './route.ts';
1
+ import { QueryRouterServer, Route, RouteContext, RouteOpts } from './route.ts';
2
2
  import { ServerNode, ServerNodeOpts } from './server/server.ts';
3
3
  import { HandleCtx } from './server/server-base.ts';
4
4
  import { ServerType } from './server/server-type.ts';
package/src/commander.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Command, program } from 'commander';
2
2
  import { App, QueryRouterServer } from './app.ts';
3
-
3
+ import { RemoteApp } from '@kevisual/remote-app'
4
4
  export const groupByPath = (routes: App['routes']) => {
5
5
  return routes.reduce((acc, route) => {
6
6
  const path = route.path || 'default';
@@ -66,8 +66,9 @@ export const parseDescription = (route: App['routes'][number]) => {
66
66
  }
67
67
  return desc;
68
68
  }
69
- export const createCommand = (opts: { app: App, program: Command }) => {
70
- const { app, program } = opts;
69
+ export const createCommand = (opts: { app: any, program: Command }) => {
70
+ const { program } = opts;
71
+ const app = opts.app as App;
71
72
  const routes = app.routes;
72
73
 
73
74
 
@@ -113,11 +114,61 @@ export const createCommand = (opts: { app: App, program: Command }) => {
113
114
  }
114
115
  }
115
116
 
116
- export const parse = (opts: { app: QueryRouterServer, description?: string, parse?: boolean, program?: Command }) => {
117
- const { app, description, parse = true, } = opts;
117
+ export const parse = async (opts: {
118
+ app: any,
119
+ description?: string,
120
+ parse?: boolean,
121
+ version?: string,
122
+ program?: Command,
123
+ remote?: {
124
+ token?: string,
125
+ username?: string,
126
+ id?: string,
127
+ }
128
+ }) => {
129
+ const { description, parse = true, version } = opts;
130
+ const app = opts.app as App;
118
131
  const _program = opts.program || program;
119
132
  _program.description(description || 'Router 命令行工具');
133
+ if (version) {
134
+ _program.version(version);
135
+ }
136
+ app.createRouteList();
137
+ app.route({
138
+ path: 'cli',
139
+ key: 'list'
140
+ }).define(async () => {
141
+ const routes = app.routes.map(route => {
142
+ return {
143
+ path: route.path,
144
+ key: route.key,
145
+ description: route?.metadata?.summary || route.description || '',
146
+ };
147
+ });
148
+ // 输出为表格格式
149
+ const table = routes.map(route => {
150
+ return `${route.path} ${route.key} - ${route.description}`;
151
+ }).join('\n');
152
+
153
+ console.log(table);
154
+ }).addTo(app, { overwrite: false })
155
+
120
156
  createCommand({ app: app as App, program: _program });
157
+
158
+ if (opts.remote) {
159
+ const { token, username, id } = opts.remote;
160
+ const remoteApp = new RemoteApp({
161
+ token,
162
+ username,
163
+ id,
164
+ });
165
+ const isConnect = await remoteApp.isConnect();
166
+ if (isConnect) {
167
+ remoteApp.listenProxy();
168
+ console.log('已连接到远程应用,正在监听命令...');
169
+ }
170
+ return
171
+ }
121
172
  if (parse) {
122
173
  _program.parse(process.argv);
123
174
  }
package/src/route.ts CHANGED
@@ -2,7 +2,7 @@ import { CustomError, throwError, CustomErrorOptions } from './result/error.ts';
2
2
  import { pick } from './utils/pick.ts';
3
3
  import { listenProcess, MockProcess } from './utils/listen-process.ts';
4
4
  import { z } from 'zod';
5
- import { randomId } from './utils/random.ts';
5
+ import { hashIdMd5Sync, randomId } from './utils/random.ts';
6
6
  import * as schema from './validator/schema.ts';
7
7
 
8
8
  export type RouterContextT = { code?: number;[key: string]: any };
@@ -96,14 +96,6 @@ export type RouteOpts<U = {}, T = SimpleObject> = {
96
96
  metadata?: T;
97
97
  middleware?: RouteMiddleware[]; // middleware
98
98
  type?: 'route' | 'middleware' | 'compound'; // compound表示这个 route 作为一个聚合体,没有实际的 run,而是一个 router 的聚合列表
99
- /**
100
- * $#$ will be used to split path and key
101
- */
102
- idUsePath?: boolean;
103
- /**
104
- * id 合并的分隔符,默认为 $#$
105
- */
106
- delimiter?: string;
107
99
  isDebug?: boolean;
108
100
  };
109
101
  export type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'nextRoute'>;
@@ -170,12 +162,9 @@ export class Route<M extends SimpleObject = SimpleObject, U extends SimpleObject
170
162
  key = key.trim();
171
163
  this.path = path;
172
164
  this.key = key;
165
+ const pathKey = `${path}$$${key}`;
173
166
  if (opts) {
174
- this.id = opts.id || randomId(12, 'rand-');
175
- if (!opts.id && opts.idUsePath) {
176
- const delimiter = opts.delimiter ?? '$$';
177
- this.id = path + delimiter + key;
178
- }
167
+ this.id = opts.id || hashIdMd5Sync(pathKey);
179
168
  this.run = opts.run as Run<BuildRouteContext<M, U>>;
180
169
  this.nextRoute = opts.nextRoute;
181
170
  this.description = opts.description;
@@ -186,7 +175,9 @@ export class Route<M extends SimpleObject = SimpleObject, U extends SimpleObject
186
175
  this.path = opts.path || path;
187
176
  } else {
188
177
  this.middleware = [];
189
- this.id = randomId(12, 'rand-');
178
+ }
179
+ if (!this.id) {
180
+ this.id = hashIdMd5Sync(pathKey);
190
181
  }
191
182
  this.isDebug = opts?.isDebug ?? false;
192
183
  }
@@ -1,8 +1,17 @@
1
1
  import { customAlphabet } from 'nanoid';
2
-
2
+ import Md5 from 'crypto-js/md5.js';
3
3
  const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 16);
4
4
 
5
5
  export const randomId = (length: number = 8, affix: string = '') => {
6
6
  return affix + nanoid(length);
7
7
  }
8
- export { nanoid };
8
+ export { nanoid };
9
+
10
+ /**
11
+ * 基于 MD5 的确定性 ID 生成 (同步版本)
12
+ * 浏览器和 Node.js 都支持
13
+ * 相同的 pathKey 永远返回相同的 16 位 ID
14
+ */
15
+ export const hashIdMd5Sync = (pathKey: string): string => {
16
+ return Md5(pathKey).toString().substring(0, 16);
17
+ }