vafast 0.4.2 → 0.4.3
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/README.md +6 -10
- package/dist/auth/{token.d.ts → token.d.mts} +21 -19
- package/dist/auth/token.mjs +105 -0
- package/dist/auth/token.mjs.map +1 -0
- package/dist/base-server-Bq4_lJWK.mjs +113 -0
- package/dist/base-server-Bq4_lJWK.mjs.map +1 -0
- package/dist/base-server-Gakrozqk.d.mts +40 -0
- package/dist/base64url-BY-HBSpL.d.mts +6 -0
- package/dist/base64url-DLDOeXsk.mjs +13 -0
- package/dist/base64url-DLDOeXsk.mjs.map +1 -0
- package/dist/chunk-67U6L5Jh.mjs +37 -0
- package/dist/component-route-BYV_X1rA.d.mts +31 -0
- package/dist/component-route-Do2yyYTi.mjs +1 -0
- package/dist/component-router-DXUXLp1R.mjs +33 -0
- package/dist/component-router-DXUXLp1R.mjs.map +1 -0
- package/dist/component-server-ARXvZJUQ.mjs +124 -0
- package/dist/component-server-ARXvZJUQ.mjs.map +1 -0
- package/dist/component-server-BOz4Q-Qt.d.mts +38 -0
- package/dist/create-handler-CbSoroA1.mjs +166 -0
- package/dist/create-handler-CbSoroA1.mjs.map +1 -0
- package/dist/{utils/create-handler.d.ts → create-handler-Dtt0xv6g.d.mts} +24 -24
- package/dist/{defineRoute.d.ts → defineRoute.d.mts} +20 -17
- package/dist/defineRoute.mjs +93 -0
- package/dist/defineRoute.mjs.map +1 -0
- package/dist/dependency-manager-CPkwMI7J.mjs +61 -0
- package/dist/dependency-manager-CPkwMI7J.mjs.map +1 -0
- package/dist/dependency-manager-Dbug5INp.d.mts +27 -0
- package/dist/formats-BSqJWCsG.d.mts +42 -0
- package/dist/go-await-B-KP-K8x.mjs +33 -0
- package/dist/go-await-B-KP-K8x.mjs.map +1 -0
- package/dist/{utils/go-await.d.ts → go-await-CqPx9dVQ.d.mts} +4 -2
- package/dist/handle-BhpqNgGf.mjs +30 -0
- package/dist/handle-BhpqNgGf.mjs.map +1 -0
- package/dist/{utils/handle.d.ts → handle-DOidKTI-.d.mts} +8 -6
- package/dist/html-renderer-C3LKTLme.d.mts +22 -0
- package/dist/{utils/html-renderer.js → html-renderer-CJ3B2Hft.mjs} +34 -29
- package/dist/html-renderer-CJ3B2Hft.mjs.map +1 -0
- package/dist/index-DFsQyT61.d.mts +48 -0
- package/dist/index-DXJd7-2Z.d.mts +1 -0
- package/dist/index.d.mts +35 -0
- package/dist/index.mjs +42 -0
- package/dist/index.mjs.map +1 -0
- package/dist/middleware/{auth.d.ts → auth.d.mts} +12 -8
- package/dist/middleware/auth.mjs +98 -0
- package/dist/middleware/auth.mjs.map +1 -0
- package/dist/middleware/authMiddleware.d.mts +9 -0
- package/dist/middleware/authMiddleware.mjs +19 -0
- package/dist/middleware/authMiddleware.mjs.map +1 -0
- package/dist/middleware/{component-renderer.d.ts → component-renderer.d.mts} +3 -1
- package/dist/middleware/component-renderer.mjs +119 -0
- package/dist/middleware/component-renderer.mjs.map +1 -0
- package/dist/middleware/{component-router.d.ts → component-router.d.mts} +5 -4
- package/dist/middleware/component-router.mjs +4 -0
- package/dist/middleware/cors.d.mts +16 -0
- package/dist/middleware/cors.mjs +38 -0
- package/dist/middleware/cors.mjs.map +1 -0
- package/dist/middleware/rateLimit.d.mts +14 -0
- package/dist/middleware/rateLimit.mjs +34 -0
- package/dist/middleware/rateLimit.mjs.map +1 -0
- package/dist/middleware-3ShRJyd1.mjs +59 -0
- package/dist/middleware-3ShRJyd1.mjs.map +1 -0
- package/dist/middleware.d.mts +25 -0
- package/dist/middleware.mjs +4 -0
- package/dist/monitoring/index.d.mts +33 -0
- package/dist/monitoring/index.mjs +27 -0
- package/dist/monitoring/index.mjs.map +1 -0
- package/dist/monitoring/native-monitor.d.mts +48 -0
- package/dist/monitoring/native-monitor.mjs +154 -0
- package/dist/monitoring/native-monitor.mjs.map +1 -0
- package/dist/monitoring/types.d.mts +150 -0
- package/dist/monitoring/types.mjs +1 -0
- package/dist/node-server/index.d.mts +4 -0
- package/dist/node-server/index.mjs +5 -0
- package/dist/node-server/{request.d.ts → request.d.mts} +4 -6
- package/dist/node-server/request.mjs +3 -0
- package/dist/node-server/{response.d.ts → response.d.mts} +4 -6
- package/dist/node-server/response.mjs +3 -0
- package/dist/node-server/serve.d.mts +2 -0
- package/dist/node-server/serve.mjs +4 -0
- package/dist/{utils/parsers.d.ts → parsers-CodQFP1Z.d.mts} +10 -8
- package/dist/parsers-ROIZWSGI.mjs +168 -0
- package/dist/parsers-ROIZWSGI.mjs.map +1 -0
- package/dist/path-matcher-CXMJ-IrG.mjs +62 -0
- package/dist/path-matcher-CXMJ-IrG.mjs.map +1 -0
- package/dist/radix-tree-BWmhTLhT.mjs +157 -0
- package/dist/radix-tree-BWmhTLhT.mjs.map +1 -0
- package/dist/request-B2BkUecT.mjs +133 -0
- package/dist/request-B2BkUecT.mjs.map +1 -0
- package/dist/request-validator-Dyqng-H_.mjs +77 -0
- package/dist/request-validator-Dyqng-H_.mjs.map +1 -0
- package/dist/request-validator-u2Ccj3_x.d.mts +67 -0
- package/dist/response-BhFKEphr.mjs +72 -0
- package/dist/response-BhFKEphr.mjs.map +1 -0
- package/dist/response-CSKW5hsS.mjs +97 -0
- package/dist/response-CSKW5hsS.mjs.map +1 -0
- package/dist/{utils/response.d.ts → response-CUyV5FIm.d.mts} +4 -2
- package/dist/route-BRR15b-p.mjs +11 -0
- package/dist/route-BRR15b-p.mjs.map +1 -0
- package/dist/route-BqmWCG4e.d.mts +44 -0
- package/dist/route-registry-AlkDgbcE.mjs +225 -0
- package/dist/route-registry-AlkDgbcE.mjs.map +1 -0
- package/dist/route-registry-ykzRmaHB.d.mts +176 -0
- package/dist/router/index.d.mts +5 -0
- package/dist/router/index.mjs +10 -0
- package/dist/router/index.mjs.map +1 -0
- package/dist/router/radix-tree.d.mts +60 -0
- package/dist/router/radix-tree.mjs +4 -0
- package/dist/router-BOeVQrjz.mjs +71 -0
- package/dist/router-BOeVQrjz.mjs.map +1 -0
- package/dist/{router.d.ts → router.d.mts} +6 -7
- package/dist/router.mjs +4 -0
- package/dist/schema-CVuttFSw.d.mts +81 -0
- package/dist/schema-CbAaktsZ.mjs +1 -0
- package/dist/serve-BQQ2JzIH.d.mts +69 -0
- package/dist/serve-MRGGK7-q.mjs +107 -0
- package/dist/serve-MRGGK7-q.mjs.map +1 -0
- package/dist/serve.d.mts +2 -0
- package/dist/serve.mjs +4 -0
- package/dist/server/base-server.d.mts +4 -0
- package/dist/server/base-server.mjs +4 -0
- package/dist/server/component-server.d.mts +5 -0
- package/dist/server/component-server.mjs +5 -0
- package/dist/server/index.d.mts +7 -0
- package/dist/server/index.mjs +8 -0
- package/dist/server/server-factory.d.mts +7 -0
- package/dist/server/server-factory.mjs +6 -0
- package/dist/server/server.d.mts +5 -0
- package/dist/server/server.mjs +4 -0
- package/dist/server-B0nzGCG5.mjs +88 -0
- package/dist/server-B0nzGCG5.mjs.map +1 -0
- package/dist/server-C8WCshmG.mjs +137 -0
- package/dist/server-C8WCshmG.mjs.map +1 -0
- package/dist/server-Drc2kSxp.d.mts +60 -0
- package/dist/sse-BOd2pvUK.d.mts +65 -0
- package/dist/sse-US5D9mgE.mjs +87 -0
- package/dist/sse-US5D9mgE.mjs.map +1 -0
- package/dist/types/component-route.d.mts +2 -0
- package/dist/types/component-route.mjs +1 -0
- package/dist/types/index.d.mts +6 -0
- package/dist/types/index.mjs +3 -0
- package/dist/types/route.d.mts +2 -0
- package/dist/types/route.mjs +3 -0
- package/dist/types/schema.d.mts +2 -0
- package/dist/types/schema.mjs +1 -0
- package/dist/types/types.d.mts +2 -0
- package/dist/types/types.mjs +1 -0
- package/dist/{types/types.d.ts → types-Cb7_2VSt.d.mts} +27 -25
- package/dist/utils/base64url.d.mts +2 -0
- package/dist/utils/base64url.mjs +3 -0
- package/dist/utils/create-handler.d.mts +3 -0
- package/dist/utils/create-handler.mjs +5 -0
- package/dist/utils/dependency-manager.d.mts +2 -0
- package/dist/utils/dependency-manager.mjs +4 -0
- package/dist/utils/formats.d.mts +2 -0
- package/dist/utils/formats.mjs +129 -0
- package/dist/utils/formats.mjs.map +1 -0
- package/dist/utils/go-await.d.mts +2 -0
- package/dist/utils/go-await.mjs +3 -0
- package/dist/utils/handle.d.mts +2 -0
- package/dist/utils/handle.mjs +4 -0
- package/dist/utils/html-renderer.d.mts +2 -0
- package/dist/utils/html-renderer.mjs +4 -0
- package/dist/utils/index.d.mts +16 -0
- package/dist/utils/index.mjs +23 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/parsers.d.mts +2 -0
- package/dist/utils/parsers.mjs +3 -0
- package/dist/utils/path-matcher.d.mts +27 -0
- package/dist/utils/path-matcher.mjs +4 -0
- package/dist/utils/request-validator.d.mts +3 -0
- package/dist/utils/request-validator.mjs +5 -0
- package/dist/utils/response.d.mts +2 -0
- package/dist/utils/response.mjs +4 -0
- package/dist/utils/route-registry.d.mts +4 -0
- package/dist/utils/route-registry.mjs +4 -0
- package/dist/utils/sse.d.mts +3 -0
- package/dist/utils/sse.mjs +5 -0
- package/dist/utils/validators/validators.d.mts +2 -0
- package/dist/utils/validators/validators.mjs +3 -0
- package/dist/validators-C0eZyxPh.d.mts +67 -0
- package/dist/validators-CbCLj0Rc.mjs +112 -0
- package/dist/validators-CbCLj0Rc.mjs.map +1 -0
- package/package.json +16 -18
- package/dist/auth/token.js +0 -131
- package/dist/auth/token.js.map +0 -1
- package/dist/defineRoute.js +0 -37
- package/dist/defineRoute.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.js +0 -2578
- package/dist/index.js.map +0 -1
- package/dist/middleware/auth.js +0 -205
- package/dist/middleware/auth.js.map +0 -1
- package/dist/middleware/authMiddleware.d.ts +0 -5
- package/dist/middleware/authMiddleware.js +0 -57
- package/dist/middleware/authMiddleware.js.map +0 -1
- package/dist/middleware/component-renderer.js +0 -139
- package/dist/middleware/component-renderer.js.map +0 -1
- package/dist/middleware/component-router.js +0 -36
- package/dist/middleware/component-router.js.map +0 -1
- package/dist/middleware/cors.d.ts +0 -12
- package/dist/middleware/cors.js +0 -43
- package/dist/middleware/cors.js.map +0 -1
- package/dist/middleware/rateLimit.d.ts +0 -10
- package/dist/middleware/rateLimit.js +0 -49
- package/dist/middleware/rateLimit.js.map +0 -1
- package/dist/middleware.d.ts +0 -21
- package/dist/middleware.js +0 -102
- package/dist/middleware.js.map +0 -1
- package/dist/monitoring/index.d.ts +0 -36
- package/dist/monitoring/index.js +0 -1487
- package/dist/monitoring/index.js.map +0 -1
- package/dist/monitoring/native-monitor.d.ts +0 -44
- package/dist/monitoring/native-monitor.js +0 -1454
- package/dist/monitoring/native-monitor.js.map +0 -1
- package/dist/monitoring/types.d.ts +0 -148
- package/dist/monitoring/types.js +0 -8
- package/dist/monitoring/types.js.map +0 -1
- package/dist/node-server/index.d.ts +0 -4
- package/dist/node-server/index.js +0 -298
- package/dist/node-server/index.js.map +0 -1
- package/dist/node-server/request.js +0 -125
- package/dist/node-server/request.js.map +0 -1
- package/dist/node-server/response.js +0 -76
- package/dist/node-server/response.js.map +0 -1
- package/dist/node-server/serve.d.ts +0 -71
- package/dist/node-server/serve.js +0 -281
- package/dist/node-server/serve.js.map +0 -1
- package/dist/router/index.d.ts +0 -3
- package/dist/router/index.js +0 -232
- package/dist/router/index.js.map +0 -1
- package/dist/router/radix-tree.d.ts +0 -66
- package/dist/router/radix-tree.js +0 -190
- package/dist/router/radix-tree.js.map +0 -1
- package/dist/router.js +0 -44
- package/dist/router.js.map +0 -1
- package/dist/serve.d.ts +0 -2
- package/dist/serve.js +0 -281
- package/dist/serve.js.map +0 -1
- package/dist/server/base-server.d.ts +0 -37
- package/dist/server/base-server.js +0 -134
- package/dist/server/base-server.js.map +0 -1
- package/dist/server/component-server.d.ts +0 -37
- package/dist/server/component-server.js +0 -488
- package/dist/server/component-server.js.map +0 -1
- package/dist/server/index.d.ts +0 -8
- package/dist/server/index.js +0 -1159
- package/dist/server/index.js.map +0 -1
- package/dist/server/server-factory.d.ts +0 -48
- package/dist/server/server-factory.js +0 -1156
- package/dist/server/server-factory.js.map +0 -1
- package/dist/server/server.d.ts +0 -64
- package/dist/server/server.js +0 -737
- package/dist/server/server.js.map +0 -1
- package/dist/types/component-route.d.ts +0 -29
- package/dist/types/component-route.js +0 -1
- package/dist/types/component-route.js.map +0 -1
- package/dist/types/index.d.ts +0 -5
- package/dist/types/index.js +0 -21
- package/dist/types/index.js.map +0 -1
- package/dist/types/route.d.ts +0 -42
- package/dist/types/route.js +0 -12
- package/dist/types/route.js.map +0 -1
- package/dist/types/schema.d.ts +0 -79
- package/dist/types/schema.js +0 -10
- package/dist/types/schema.js.map +0 -1
- package/dist/types/types.js +0 -1
- package/dist/types/types.js.map +0 -1
- package/dist/utils/base64url.d.ts +0 -4
- package/dist/utils/base64url.js +0 -14
- package/dist/utils/base64url.js.map +0 -1
- package/dist/utils/create-handler.js +0 -299
- package/dist/utils/create-handler.js.map +0 -1
- package/dist/utils/dependency-manager.d.ts +0 -25
- package/dist/utils/dependency-manager.js +0 -71
- package/dist/utils/dependency-manager.js.map +0 -1
- package/dist/utils/formats.d.ts +0 -40
- package/dist/utils/formats.js +0 -116
- package/dist/utils/formats.js.map +0 -1
- package/dist/utils/go-await.js +0 -16
- package/dist/utils/go-await.js.map +0 -1
- package/dist/utils/handle.js +0 -48
- package/dist/utils/handle.js.map +0 -1
- package/dist/utils/html-renderer.d.ts +0 -20
- package/dist/utils/html-renderer.js.map +0 -1
- package/dist/utils/index.d.ts +0 -16
- package/dist/utils/index.js +0 -1038
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/parsers.js +0 -160
- package/dist/utils/parsers.js.map +0 -1
- package/dist/utils/path-matcher.d.ts +0 -25
- package/dist/utils/path-matcher.js +0 -73
- package/dist/utils/path-matcher.js.map +0 -1
- package/dist/utils/request-validator.d.ts +0 -66
- package/dist/utils/request-validator.js +0 -158
- package/dist/utils/request-validator.js.map +0 -1
- package/dist/utils/response.js +0 -102
- package/dist/utils/response.js.map +0 -1
- package/dist/utils/route-registry.d.ts +0 -195
- package/dist/utils/route-registry.js +0 -152
- package/dist/utils/route-registry.js.map +0 -1
- package/dist/utils/sse.d.ts +0 -87
- package/dist/utils/sse.js +0 -181
- package/dist/utils/sse.js.map +0 -1
- package/dist/utils/validators/validators.d.ts +0 -76
- package/dist/utils/validators/validators.js +0 -97
- package/dist/utils/validators/validators.js.map +0 -1
package/dist/server/server.js
DELETED
|
@@ -1,737 +0,0 @@
|
|
|
1
|
-
// src/router.ts
|
|
2
|
-
function flattenNestedRoutes(routes) {
|
|
3
|
-
const flattened = [];
|
|
4
|
-
function processRoute(route, parentPath = "", parentMiddleware = [], parentName) {
|
|
5
|
-
const currentPath = normalizePath(parentPath + route.path);
|
|
6
|
-
const currentMiddleware = [
|
|
7
|
-
...parentMiddleware,
|
|
8
|
-
...route.middleware || []
|
|
9
|
-
];
|
|
10
|
-
const currentName = route.name || parentName;
|
|
11
|
-
if ("method" in route && "handler" in route) {
|
|
12
|
-
const leafRoute = route;
|
|
13
|
-
flattened.push({
|
|
14
|
-
...leafRoute,
|
|
15
|
-
fullPath: currentPath,
|
|
16
|
-
middlewareChain: currentMiddleware,
|
|
17
|
-
parentName
|
|
18
|
-
// 保存父级名称
|
|
19
|
-
});
|
|
20
|
-
} else if ("children" in route && route.children) {
|
|
21
|
-
for (const child of route.children) {
|
|
22
|
-
processRoute(child, currentPath, currentMiddleware, currentName);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
for (const route of routes) {
|
|
27
|
-
processRoute(route);
|
|
28
|
-
}
|
|
29
|
-
return flattened;
|
|
30
|
-
}
|
|
31
|
-
function normalizePath(path) {
|
|
32
|
-
let normalized = decodeURIComponent(path);
|
|
33
|
-
normalized = normalized.replace(/\/+/g, "/");
|
|
34
|
-
if (normalized === "") return "/";
|
|
35
|
-
if (normalized !== "/" && normalized.endsWith("/")) {
|
|
36
|
-
normalized = normalized.slice(0, -1);
|
|
37
|
-
}
|
|
38
|
-
return normalized;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// src/utils/response.ts
|
|
42
|
-
function json(data, status = 200, headers = {}) {
|
|
43
|
-
const body = JSON.stringify(data);
|
|
44
|
-
if (Object.keys(headers).length === 0) {
|
|
45
|
-
return new Response(body, {
|
|
46
|
-
status,
|
|
47
|
-
headers: { "Content-Type": "application/json" }
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
const h = new Headers({
|
|
51
|
-
"Content-Type": "application/json",
|
|
52
|
-
...headers
|
|
53
|
-
});
|
|
54
|
-
return new Response(body, {
|
|
55
|
-
status,
|
|
56
|
-
headers: h
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
var JSON_HEADERS = { "Content-Type": "application/json" };
|
|
60
|
-
var TEXT_HEADERS = { "Content-Type": "text/plain" };
|
|
61
|
-
function mapResponse(response) {
|
|
62
|
-
if (response instanceof Response) return response;
|
|
63
|
-
switch (response?.constructor?.name) {
|
|
64
|
-
case "String":
|
|
65
|
-
return new Response(response, { headers: TEXT_HEADERS });
|
|
66
|
-
case "Object":
|
|
67
|
-
case "Array":
|
|
68
|
-
return new Response(JSON.stringify(response), { headers: JSON_HEADERS });
|
|
69
|
-
case "Number":
|
|
70
|
-
case "Boolean":
|
|
71
|
-
return new Response(String(response), { headers: TEXT_HEADERS });
|
|
72
|
-
case void 0:
|
|
73
|
-
return new Response(null, { status: 204 });
|
|
74
|
-
case "ReadableStream":
|
|
75
|
-
return new Response(response);
|
|
76
|
-
case "Blob":
|
|
77
|
-
return new Response(response);
|
|
78
|
-
case "ArrayBuffer":
|
|
79
|
-
return new Response(response);
|
|
80
|
-
case "Uint8Array":
|
|
81
|
-
return new Response(response);
|
|
82
|
-
default:
|
|
83
|
-
if (response instanceof Promise) {
|
|
84
|
-
return response.then(mapResponse);
|
|
85
|
-
}
|
|
86
|
-
return new Response(JSON.stringify(response), { headers: JSON_HEADERS });
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// src/middleware.ts
|
|
91
|
-
var VafastError = class extends Error {
|
|
92
|
-
status;
|
|
93
|
-
type;
|
|
94
|
-
expose;
|
|
95
|
-
constructor(message, options = {}) {
|
|
96
|
-
super(message);
|
|
97
|
-
this.name = "VafastError";
|
|
98
|
-
this.status = options.status ?? 500;
|
|
99
|
-
this.type = options.type ?? "internal_error";
|
|
100
|
-
this.expose = options.expose ?? false;
|
|
101
|
-
if (options.cause) this.cause = options.cause;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
function composeMiddleware(middleware, finalHandler) {
|
|
105
|
-
const all = [errorHandler, ...middleware];
|
|
106
|
-
return function composedHandler(req) {
|
|
107
|
-
let i = -1;
|
|
108
|
-
const dispatch = (index) => {
|
|
109
|
-
if (index <= i)
|
|
110
|
-
return Promise.reject(new Error("next() called multiple times"));
|
|
111
|
-
i = index;
|
|
112
|
-
if (index < all.length) {
|
|
113
|
-
const mw = all[index];
|
|
114
|
-
return Promise.resolve(mw(req, () => dispatch(index + 1)));
|
|
115
|
-
}
|
|
116
|
-
return Promise.resolve(finalHandler(req)).then(mapResponse);
|
|
117
|
-
};
|
|
118
|
-
return dispatch(0);
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
var errorHandler = async (req, next) => {
|
|
122
|
-
try {
|
|
123
|
-
return await next();
|
|
124
|
-
} catch (err) {
|
|
125
|
-
console.error("\u672A\u5904\u7406\u7684\u9519\u8BEF:", err);
|
|
126
|
-
if (err instanceof VafastError) {
|
|
127
|
-
return json(
|
|
128
|
-
{
|
|
129
|
-
error: err.type,
|
|
130
|
-
message: err.expose ? err.message : "\u53D1\u751F\u4E86\u4E00\u4E2A\u9519\u8BEF"
|
|
131
|
-
},
|
|
132
|
-
err.status
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
return json({ error: "internal_error", message: "\u51FA\u73B0\u4E86\u4E00\u4E9B\u95EE\u9898" }, 500);
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// src/server/base-server.ts
|
|
140
|
-
var BaseServer = class {
|
|
141
|
-
globalMiddleware = [];
|
|
142
|
-
use(mw) {
|
|
143
|
-
this.globalMiddleware.push(mw);
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* 打印扁平化后的路由信息,用于调试
|
|
147
|
-
*/
|
|
148
|
-
logFlattenedRoutes(routes, type = "\u8DEF\u7531") {
|
|
149
|
-
console.log(`\u{1F680} \u6241\u5E73\u5316\u540E\u7684${type}:`);
|
|
150
|
-
for (const route of routes) {
|
|
151
|
-
const method = route.method || "GET";
|
|
152
|
-
const path = route.fullPath || route.path;
|
|
153
|
-
console.log(` ${method} ${path}`);
|
|
154
|
-
if (route.middlewareChain && route.middlewareChain.length > 0) {
|
|
155
|
-
console.log(` \u4E2D\u95F4\u4EF6\u94FE: ${route.middlewareChain.length} \u4E2A`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
console.log("");
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* 检测路由冲突
|
|
162
|
-
* 检查是否有路径相同但方法不同的路由,以及潜在的路径冲突
|
|
163
|
-
*/
|
|
164
|
-
detectRouteConflicts(routes) {
|
|
165
|
-
const pathGroups = /* @__PURE__ */ new Map();
|
|
166
|
-
for (const route of routes) {
|
|
167
|
-
const path = route.fullPath || route.path;
|
|
168
|
-
const method = route.method || "GET";
|
|
169
|
-
if (!pathGroups.has(path)) {
|
|
170
|
-
pathGroups.set(path, []);
|
|
171
|
-
}
|
|
172
|
-
pathGroups.get(path).push({ ...route, method });
|
|
173
|
-
}
|
|
174
|
-
for (const [path, routeList] of pathGroups) {
|
|
175
|
-
if (routeList.length > 1) {
|
|
176
|
-
const methods = routeList.map((r) => r.method);
|
|
177
|
-
const uniqueMethods = [...new Set(methods)];
|
|
178
|
-
if (uniqueMethods.length === 1) {
|
|
179
|
-
console.warn(
|
|
180
|
-
`\u26A0\uFE0F \u8DEF\u7531\u51B2\u7A81: ${uniqueMethods[0]} ${path} \u5B9A\u4E49\u4E86 ${routeList.length} \u6B21`
|
|
181
|
-
);
|
|
182
|
-
routeList.forEach((route, index) => {
|
|
183
|
-
console.warn(` ${index + 1}. ${route.method} ${path}`);
|
|
184
|
-
});
|
|
185
|
-
} else {
|
|
186
|
-
console.log(`\u2139\uFE0F \u8DEF\u5F84 ${path} \u652F\u6301\u65B9\u6CD5: ${uniqueMethods.join(", ")}`);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
this.detectDynamicRouteConflicts(routes);
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* 检测动态路由的潜在冲突
|
|
194
|
-
*/
|
|
195
|
-
detectDynamicRouteConflicts(routes) {
|
|
196
|
-
const dynamicRoutes = routes.filter((r) => {
|
|
197
|
-
const path = r.fullPath || r.path;
|
|
198
|
-
return path.includes(":") || path.includes("*");
|
|
199
|
-
});
|
|
200
|
-
for (let i = 0; i < dynamicRoutes.length; i++) {
|
|
201
|
-
for (let j = i + 1; j < dynamicRoutes.length; j++) {
|
|
202
|
-
const route1 = dynamicRoutes[i];
|
|
203
|
-
const route2 = dynamicRoutes[j];
|
|
204
|
-
const method1 = route1.method || "GET";
|
|
205
|
-
const method2 = route2.method || "GET";
|
|
206
|
-
if (method1 === method2) {
|
|
207
|
-
const path1 = route1.fullPath || route1.path;
|
|
208
|
-
const path2 = route2.fullPath || route2.path;
|
|
209
|
-
if (this.pathsMayConflict(path1, path2)) {
|
|
210
|
-
console.warn(
|
|
211
|
-
`\u26A0\uFE0F \u6F5C\u5728\u8DEF\u7531\u51B2\u7A81: ${method1} ${path1} \u53EF\u80FD\u4E0E ${path2} \u51B2\u7A81`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* 判断两个路径是否可能冲突
|
|
220
|
-
*/
|
|
221
|
-
pathsMayConflict(path1, path2) {
|
|
222
|
-
const parts1 = path1.split("/").filter(Boolean);
|
|
223
|
-
const parts2 = path2.split("/").filter(Boolean);
|
|
224
|
-
if (parts1.length !== parts2.length) return false;
|
|
225
|
-
for (let i = 0; i < parts1.length; i++) {
|
|
226
|
-
const p1 = parts1[i];
|
|
227
|
-
const p2 = parts2[i];
|
|
228
|
-
if (!p1.startsWith(":") && !p1.startsWith("*") && !p2.startsWith(":") && !p2.startsWith("*") && p1 !== p2) {
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
if (p1 === "*" && p2.startsWith(":") || p2 === "*" && p1.startsWith(":")) {
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return false;
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* 路径匹配
|
|
239
|
-
*/
|
|
240
|
-
matchPath(pattern, path) {
|
|
241
|
-
const patternParts = pattern.split("/").filter(Boolean);
|
|
242
|
-
const pathParts = path.split("/").filter(Boolean);
|
|
243
|
-
if (patternParts.length !== pathParts.length) {
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
for (let i = 0; i < patternParts.length; i++) {
|
|
247
|
-
if (patternParts[i] !== pathParts[i] && !patternParts[i].startsWith(":")) {
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* 提取路径参数
|
|
255
|
-
*/
|
|
256
|
-
extractParams(pattern, path) {
|
|
257
|
-
const params = {};
|
|
258
|
-
const patternParts = pattern.split("/").filter(Boolean);
|
|
259
|
-
const pathParts = path.split("/").filter(Boolean);
|
|
260
|
-
for (let i = 0; i < patternParts.length; i++) {
|
|
261
|
-
if (patternParts[i].startsWith(":")) {
|
|
262
|
-
const paramName = patternParts[i].slice(1);
|
|
263
|
-
params[paramName] = pathParts[i];
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return params;
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
// src/router/radix-tree.ts
|
|
271
|
-
var RadixRouter = class {
|
|
272
|
-
root;
|
|
273
|
-
constructor() {
|
|
274
|
-
this.root = this.createNode("");
|
|
275
|
-
}
|
|
276
|
-
createNode(path) {
|
|
277
|
-
return {
|
|
278
|
-
path,
|
|
279
|
-
children: /* @__PURE__ */ Object.create(null),
|
|
280
|
-
handlers: /* @__PURE__ */ Object.create(null)
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
/** 分割路径 */
|
|
284
|
-
splitPath(path) {
|
|
285
|
-
return path.split("/").filter(Boolean);
|
|
286
|
-
}
|
|
287
|
-
/** 编译器函数 - 用于预编译中间件链 */
|
|
288
|
-
compiler;
|
|
289
|
-
/** 设置中间件编译器 */
|
|
290
|
-
setCompiler(compiler) {
|
|
291
|
-
this.compiler = compiler;
|
|
292
|
-
}
|
|
293
|
-
/** 注册路由 */
|
|
294
|
-
register(method, pattern, handler, middleware = []) {
|
|
295
|
-
const segments = this.splitPath(pattern);
|
|
296
|
-
let node = this.root;
|
|
297
|
-
for (const segment of segments) {
|
|
298
|
-
const firstChar = segment[0];
|
|
299
|
-
if (firstChar === ":") {
|
|
300
|
-
if (!node.paramChild) {
|
|
301
|
-
node.paramChild = this.createNode(segment);
|
|
302
|
-
node.paramChild.paramName = segment.substring(1);
|
|
303
|
-
}
|
|
304
|
-
node = node.paramChild;
|
|
305
|
-
} else if (firstChar === "*") {
|
|
306
|
-
if (!node.wildcardChild) {
|
|
307
|
-
node.wildcardChild = this.createNode(segment);
|
|
308
|
-
node.wildcardChild.paramName = segment.length > 1 ? segment.substring(1) : "*";
|
|
309
|
-
}
|
|
310
|
-
node = node.wildcardChild;
|
|
311
|
-
break;
|
|
312
|
-
} else {
|
|
313
|
-
if (!node.children[segment]) {
|
|
314
|
-
node.children[segment] = this.createNode(segment);
|
|
315
|
-
}
|
|
316
|
-
node = node.children[segment];
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
const routeHandler = { handler, middleware };
|
|
320
|
-
if (this.compiler && middleware.length === 0) {
|
|
321
|
-
routeHandler.compiled = this.compiler([], handler);
|
|
322
|
-
}
|
|
323
|
-
node.handlers[method] = routeHandler;
|
|
324
|
-
}
|
|
325
|
-
/** 预编译所有路由(在添加全局中间件后调用) */
|
|
326
|
-
precompileAll(globalMiddleware) {
|
|
327
|
-
if (!this.compiler) return;
|
|
328
|
-
this.precompileNode(this.root, globalMiddleware);
|
|
329
|
-
}
|
|
330
|
-
precompileNode(node, globalMiddleware) {
|
|
331
|
-
for (const method in node.handlers) {
|
|
332
|
-
const routeHandler = node.handlers[method];
|
|
333
|
-
if (routeHandler) {
|
|
334
|
-
const allMiddleware = [...globalMiddleware, ...routeHandler.middleware];
|
|
335
|
-
routeHandler.compiled = this.compiler(
|
|
336
|
-
allMiddleware,
|
|
337
|
-
routeHandler.handler
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
for (const key in node.children) {
|
|
342
|
-
this.precompileNode(node.children[key], globalMiddleware);
|
|
343
|
-
}
|
|
344
|
-
if (node.paramChild) {
|
|
345
|
-
this.precompileNode(node.paramChild, globalMiddleware);
|
|
346
|
-
}
|
|
347
|
-
if (node.wildcardChild) {
|
|
348
|
-
this.precompileNode(node.wildcardChild, globalMiddleware);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
/** 匹配路由 */
|
|
352
|
-
match(method, path) {
|
|
353
|
-
const segments = this.splitPath(path);
|
|
354
|
-
const params = /* @__PURE__ */ Object.create(null);
|
|
355
|
-
const node = this.matchNode(this.root, segments, 0, params);
|
|
356
|
-
if (!node) return null;
|
|
357
|
-
const routeHandler = node.handlers[method];
|
|
358
|
-
if (!routeHandler) return null;
|
|
359
|
-
return {
|
|
360
|
-
handler: routeHandler.handler,
|
|
361
|
-
middleware: routeHandler.middleware,
|
|
362
|
-
params,
|
|
363
|
-
compiled: routeHandler.compiled
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
/** 递归匹配节点 (优先级: 静态 > 动态参数 > 通配符) */
|
|
367
|
-
matchNode(node, segments, index, params) {
|
|
368
|
-
if (index === segments.length) {
|
|
369
|
-
for (const method in node.handlers) {
|
|
370
|
-
if (node.handlers[method]) return node;
|
|
371
|
-
}
|
|
372
|
-
return null;
|
|
373
|
-
}
|
|
374
|
-
const segment = segments[index];
|
|
375
|
-
const staticChild = node.children[segment];
|
|
376
|
-
if (staticChild) {
|
|
377
|
-
const result = this.matchNode(staticChild, segments, index + 1, params);
|
|
378
|
-
if (result) return result;
|
|
379
|
-
}
|
|
380
|
-
if (node.paramChild) {
|
|
381
|
-
const paramName = node.paramChild.paramName;
|
|
382
|
-
const oldValue = params[paramName];
|
|
383
|
-
params[paramName] = segment;
|
|
384
|
-
const result = this.matchNode(
|
|
385
|
-
node.paramChild,
|
|
386
|
-
segments,
|
|
387
|
-
index + 1,
|
|
388
|
-
params
|
|
389
|
-
);
|
|
390
|
-
if (result) return result;
|
|
391
|
-
if (oldValue === void 0) {
|
|
392
|
-
delete params[paramName];
|
|
393
|
-
} else {
|
|
394
|
-
params[paramName] = oldValue;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
if (node.wildcardChild) {
|
|
398
|
-
params[node.wildcardChild.paramName || "*"] = segments.slice(index).join("/");
|
|
399
|
-
return node.wildcardChild;
|
|
400
|
-
}
|
|
401
|
-
return null;
|
|
402
|
-
}
|
|
403
|
-
/** 获取路径允许的 HTTP 方法 */
|
|
404
|
-
getAllowedMethods(path) {
|
|
405
|
-
const segments = this.splitPath(path);
|
|
406
|
-
const node = this.findNode(segments);
|
|
407
|
-
if (!node) return [];
|
|
408
|
-
const methods = [];
|
|
409
|
-
for (const method in node.handlers) {
|
|
410
|
-
if (node.handlers[method]) {
|
|
411
|
-
methods.push(method);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return methods;
|
|
415
|
-
}
|
|
416
|
-
/** 查找节点(不提取参数) */
|
|
417
|
-
findNode(segments) {
|
|
418
|
-
let node = this.root;
|
|
419
|
-
for (const segment of segments) {
|
|
420
|
-
if (node.children[segment]) {
|
|
421
|
-
node = node.children[segment];
|
|
422
|
-
} else if (node.paramChild) {
|
|
423
|
-
node = node.paramChild;
|
|
424
|
-
} else if (node.wildcardChild) {
|
|
425
|
-
return node.wildcardChild;
|
|
426
|
-
} else {
|
|
427
|
-
return null;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
return node;
|
|
431
|
-
}
|
|
432
|
-
/** 获取所有已注册的路由 */
|
|
433
|
-
getRoutes() {
|
|
434
|
-
const routes = [];
|
|
435
|
-
this.collectRoutes(this.root, "", routes);
|
|
436
|
-
return routes;
|
|
437
|
-
}
|
|
438
|
-
collectRoutes(node, prefix, routes) {
|
|
439
|
-
const currentPath = prefix + (node.path ? "/" + node.path : "");
|
|
440
|
-
for (const method in node.handlers) {
|
|
441
|
-
if (node.handlers[method]) {
|
|
442
|
-
routes.push({ method, path: currentPath || "/" });
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
for (const key in node.children) {
|
|
446
|
-
this.collectRoutes(node.children[key], currentPath, routes);
|
|
447
|
-
}
|
|
448
|
-
if (node.paramChild) {
|
|
449
|
-
this.collectRoutes(node.paramChild, currentPath, routes);
|
|
450
|
-
}
|
|
451
|
-
if (node.wildcardChild) {
|
|
452
|
-
this.collectRoutes(node.wildcardChild, currentPath, routes);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
// src/utils/route-registry.ts
|
|
458
|
-
var RouteRegistry = class {
|
|
459
|
-
/** 所有路由元信息 */
|
|
460
|
-
routes = [];
|
|
461
|
-
/** 路由映射表:METHOD:fullPath -> RouteMeta */
|
|
462
|
-
routeMap = /* @__PURE__ */ new Map();
|
|
463
|
-
/** 分类映射表:category -> RouteMeta[] */
|
|
464
|
-
categoryMap = /* @__PURE__ */ new Map();
|
|
465
|
-
constructor(routes) {
|
|
466
|
-
this.buildRegistry(routes);
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* 构建注册表
|
|
470
|
-
*/
|
|
471
|
-
buildRegistry(routes) {
|
|
472
|
-
for (const route of routes) {
|
|
473
|
-
const meta = {
|
|
474
|
-
method: route.method,
|
|
475
|
-
path: route.path,
|
|
476
|
-
fullPath: route.fullPath,
|
|
477
|
-
name: route.name,
|
|
478
|
-
description: route.description
|
|
479
|
-
};
|
|
480
|
-
for (const key of Object.keys(route)) {
|
|
481
|
-
if (!["method", "path", "fullPath", "name", "description", "handler", "middleware", "middlewareChain"].includes(key)) {
|
|
482
|
-
meta[key] = route[key];
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
this.routes.push(meta);
|
|
486
|
-
this.routeMap.set(`${route.method}:${route.fullPath}`, meta);
|
|
487
|
-
const category = this.extractCategory(route.fullPath);
|
|
488
|
-
if (!this.categoryMap.has(category)) {
|
|
489
|
-
this.categoryMap.set(category, []);
|
|
490
|
-
}
|
|
491
|
-
this.categoryMap.get(category).push(meta);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* 提取分类(第一段路径)
|
|
496
|
-
*/
|
|
497
|
-
extractCategory(path) {
|
|
498
|
-
const segments = path.split("/").filter(Boolean);
|
|
499
|
-
return segments[0] || "root";
|
|
500
|
-
}
|
|
501
|
-
// ============================================
|
|
502
|
-
// 查询接口
|
|
503
|
-
// ============================================
|
|
504
|
-
/**
|
|
505
|
-
* 获取所有路由元信息
|
|
506
|
-
*/
|
|
507
|
-
getAll() {
|
|
508
|
-
return [...this.routes];
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* 按 method + path 查询路由
|
|
512
|
-
*/
|
|
513
|
-
get(method, path) {
|
|
514
|
-
return this.routeMap.get(`${method}:${path}`);
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* 检查路由是否存在
|
|
518
|
-
*/
|
|
519
|
-
has(method, path) {
|
|
520
|
-
return this.routeMap.has(`${method}:${path}`);
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* 按分类获取路由
|
|
524
|
-
*/
|
|
525
|
-
getByCategory(category) {
|
|
526
|
-
return this.categoryMap.get(category) || [];
|
|
527
|
-
}
|
|
528
|
-
/**
|
|
529
|
-
* 获取所有分类
|
|
530
|
-
*/
|
|
531
|
-
getCategories() {
|
|
532
|
-
return Array.from(this.categoryMap.keys()).sort();
|
|
533
|
-
}
|
|
534
|
-
/**
|
|
535
|
-
* 筛选有特定字段的路由
|
|
536
|
-
*
|
|
537
|
-
* @example
|
|
538
|
-
* ```typescript
|
|
539
|
-
* // 获取所有配置了 webhook 的路由
|
|
540
|
-
* const webhookRoutes = registry.filter('webhook')
|
|
541
|
-
* ```
|
|
542
|
-
*/
|
|
543
|
-
filter(field) {
|
|
544
|
-
return this.routes.filter((r) => field in r && r[field] !== void 0);
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* 按条件筛选路由
|
|
548
|
-
*
|
|
549
|
-
* @example
|
|
550
|
-
* ```typescript
|
|
551
|
-
* // 获取所有 POST 请求
|
|
552
|
-
* const postRoutes = registry.filterBy(r => r.method === 'POST')
|
|
553
|
-
* ```
|
|
554
|
-
*/
|
|
555
|
-
filterBy(predicate) {
|
|
556
|
-
return this.routes.filter(predicate);
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* 获取路由数量
|
|
560
|
-
*/
|
|
561
|
-
get size() {
|
|
562
|
-
return this.routes.length;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* 遍历所有路由
|
|
566
|
-
*/
|
|
567
|
-
forEach(callback) {
|
|
568
|
-
this.routes.forEach(callback);
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* 映射所有路由
|
|
572
|
-
*/
|
|
573
|
-
map(callback) {
|
|
574
|
-
return this.routes.map(callback);
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
var globalRegistry = null;
|
|
578
|
-
function setGlobalRegistry(registry) {
|
|
579
|
-
globalRegistry = registry;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// src/server/server.ts
|
|
583
|
-
var Server = class extends BaseServer {
|
|
584
|
-
router;
|
|
585
|
-
routes;
|
|
586
|
-
/** 是否已预编译 */
|
|
587
|
-
isCompiled = false;
|
|
588
|
-
/** 预编译时的全局中间件数量 */
|
|
589
|
-
compiledWithMiddlewareCount = 0;
|
|
590
|
-
constructor(routes = []) {
|
|
591
|
-
super();
|
|
592
|
-
this.router = new RadixRouter();
|
|
593
|
-
this.routes = [];
|
|
594
|
-
this.router.setCompiler(
|
|
595
|
-
(middleware, handler) => composeMiddleware(middleware, handler)
|
|
596
|
-
);
|
|
597
|
-
if (routes.length > 0) {
|
|
598
|
-
this.registerRoutes(routes);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* 预编译所有路由处理链
|
|
603
|
-
* 在添加所有路由和全局中间件后调用,可提升运行时性能
|
|
604
|
-
*/
|
|
605
|
-
compile() {
|
|
606
|
-
this.router.precompileAll(this.globalMiddleware);
|
|
607
|
-
this.isCompiled = true;
|
|
608
|
-
this.compiledWithMiddlewareCount = this.globalMiddleware.length;
|
|
609
|
-
return this;
|
|
610
|
-
}
|
|
611
|
-
registerRoutes(routes) {
|
|
612
|
-
const flattened = flattenNestedRoutes(routes);
|
|
613
|
-
this.routes.push(...flattened);
|
|
614
|
-
for (const route of flattened) {
|
|
615
|
-
this.router.register(
|
|
616
|
-
route.method,
|
|
617
|
-
route.fullPath,
|
|
618
|
-
route.handler,
|
|
619
|
-
route.middlewareChain || []
|
|
620
|
-
);
|
|
621
|
-
}
|
|
622
|
-
this.detectRouteConflicts(flattened);
|
|
623
|
-
this.logFlattenedRoutes(flattened);
|
|
624
|
-
if (this.globalMiddleware.length === 0 && !this.isCompiled) {
|
|
625
|
-
this.compile();
|
|
626
|
-
}
|
|
627
|
-
setGlobalRegistry(new RouteRegistry(this.routes));
|
|
628
|
-
}
|
|
629
|
-
/** 快速提取 pathname */
|
|
630
|
-
extractPathname(url) {
|
|
631
|
-
let start = url.indexOf("://");
|
|
632
|
-
start = start === -1 ? 0 : start + 3;
|
|
633
|
-
const pathStart = url.indexOf("/", start);
|
|
634
|
-
if (pathStart === -1) return "/";
|
|
635
|
-
let end = url.indexOf("?", pathStart);
|
|
636
|
-
if (end === -1) end = url.indexOf("#", pathStart);
|
|
637
|
-
if (end === -1) end = url.length;
|
|
638
|
-
return url.substring(pathStart, end) || "/";
|
|
639
|
-
}
|
|
640
|
-
/** 生成 404/405 响应 */
|
|
641
|
-
createErrorResponse(method, pathname) {
|
|
642
|
-
const allowedMethods = this.router.getAllowedMethods(pathname);
|
|
643
|
-
if (allowedMethods.length > 0) {
|
|
644
|
-
return json(
|
|
645
|
-
{
|
|
646
|
-
success: false,
|
|
647
|
-
error: "Method Not Allowed",
|
|
648
|
-
message: `Method ${method} not allowed for this endpoint`,
|
|
649
|
-
allowedMethods
|
|
650
|
-
},
|
|
651
|
-
405,
|
|
652
|
-
{ Allow: allowedMethods.join(", ") }
|
|
653
|
-
);
|
|
654
|
-
}
|
|
655
|
-
return json({ success: false, error: "Not Found" }, 404);
|
|
656
|
-
}
|
|
657
|
-
/** 处理请求 */
|
|
658
|
-
fetch = async (req) => {
|
|
659
|
-
const pathname = this.extractPathname(req.url);
|
|
660
|
-
const method = req.method;
|
|
661
|
-
const match = this.router.match(method, pathname);
|
|
662
|
-
if (match) {
|
|
663
|
-
req.params = match.params;
|
|
664
|
-
if (match.compiled && this.globalMiddleware.length === this.compiledWithMiddlewareCount) {
|
|
665
|
-
return match.compiled(req);
|
|
666
|
-
}
|
|
667
|
-
const allMiddleware = [...this.globalMiddleware, ...match.middleware];
|
|
668
|
-
const handler = composeMiddleware(allMiddleware, match.handler);
|
|
669
|
-
return handler(req);
|
|
670
|
-
}
|
|
671
|
-
if (method === "OPTIONS") {
|
|
672
|
-
const allowedMethods = this.router.getAllowedMethods(pathname);
|
|
673
|
-
if (allowedMethods.length > 0) {
|
|
674
|
-
const anyMatch = this.router.match(
|
|
675
|
-
allowedMethods[0],
|
|
676
|
-
pathname
|
|
677
|
-
);
|
|
678
|
-
const routeMiddleware = anyMatch?.middleware || [];
|
|
679
|
-
const allMiddleware = [...this.globalMiddleware, ...routeMiddleware];
|
|
680
|
-
const optionsHandler = () => new Response(null, {
|
|
681
|
-
status: 204,
|
|
682
|
-
headers: { Allow: allowedMethods.join(", ") }
|
|
683
|
-
});
|
|
684
|
-
const handler = composeMiddleware(allMiddleware, optionsHandler);
|
|
685
|
-
return handler(req);
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
if (this.globalMiddleware.length > 0) {
|
|
689
|
-
const handler = composeMiddleware(
|
|
690
|
-
this.globalMiddleware,
|
|
691
|
-
() => this.createErrorResponse(method, pathname)
|
|
692
|
-
);
|
|
693
|
-
return handler(req);
|
|
694
|
-
}
|
|
695
|
-
return this.createErrorResponse(method, pathname);
|
|
696
|
-
};
|
|
697
|
-
addRoute(route) {
|
|
698
|
-
const flattenedRoute = {
|
|
699
|
-
...route,
|
|
700
|
-
fullPath: route.path,
|
|
701
|
-
middlewareChain: route.middleware || []
|
|
702
|
-
};
|
|
703
|
-
this.routes.push(flattenedRoute);
|
|
704
|
-
this.router.register(
|
|
705
|
-
route.method,
|
|
706
|
-
route.path,
|
|
707
|
-
route.handler,
|
|
708
|
-
route.middleware || []
|
|
709
|
-
);
|
|
710
|
-
}
|
|
711
|
-
addRoutes(routes) {
|
|
712
|
-
this.registerRoutes(routes);
|
|
713
|
-
}
|
|
714
|
-
getRoutes() {
|
|
715
|
-
return this.router.getRoutes();
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
* 获取完整的路由元信息(不含 handler 和 middleware)
|
|
719
|
-
*
|
|
720
|
-
* 用于 API 文档生成、Webhook 事件注册、权限检查等场景
|
|
721
|
-
*
|
|
722
|
-
* @example
|
|
723
|
-
* ```typescript
|
|
724
|
-
* const routes = server.getRoutesWithMeta()
|
|
725
|
-
* for (const route of routes) {
|
|
726
|
-
* console.log(route.fullPath, route.name, route.description)
|
|
727
|
-
* }
|
|
728
|
-
* ```
|
|
729
|
-
*/
|
|
730
|
-
getRoutesWithMeta() {
|
|
731
|
-
return this.routes;
|
|
732
|
-
}
|
|
733
|
-
};
|
|
734
|
-
export {
|
|
735
|
-
Server
|
|
736
|
-
};
|
|
737
|
-
//# sourceMappingURL=server.js.map
|