vafast 0.3.2 → 0.3.4
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/auth/token.d.ts +13 -11
- package/dist/auth/token.js +118 -111
- package/dist/auth/token.js.map +1 -0
- package/dist/defineRoute.d.ts +5 -2
- package/dist/defineRoute.js +7 -2
- package/dist/defineRoute.js.map +1 -0
- package/dist/index.d.ts +30 -14
- package/dist/index.js +2247 -15
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +8 -6
- package/dist/middleware/auth.js +198 -99
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/authMiddleware.d.ts +5 -2
- package/dist/middleware/authMiddleware.js +55 -11
- package/dist/middleware/authMiddleware.js.map +1 -0
- package/dist/middleware/component-renderer.d.ts +4 -2
- package/dist/middleware/component-renderer.js +87 -80
- package/dist/middleware/component-renderer.js.map +1 -0
- package/dist/middleware/component-router.d.ts +8 -3
- package/dist/middleware/component-router.js +33 -39
- package/dist/middleware/component-router.js.map +1 -0
- package/dist/middleware/cors.d.ts +6 -3
- package/dist/middleware/cors.js +42 -29
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/rateLimit.d.ts +5 -3
- package/dist/middleware/rateLimit.js +45 -29
- package/dist/middleware/rateLimit.js.map +1 -0
- package/dist/middleware.d.ts +6 -3
- package/dist/middleware.js +97 -51
- package/dist/middleware.js.map +1 -0
- package/dist/monitoring/index.d.ts +11 -4
- package/dist/monitoring/index.js +1299 -17
- package/dist/monitoring/index.js.map +1 -0
- package/dist/monitoring/native-monitor.d.ts +12 -6
- package/dist/monitoring/native-monitor.js +1258 -161
- package/dist/monitoring/native-monitor.js.map +1 -0
- package/dist/monitoring/types.d.ts +8 -6
- package/dist/monitoring/types.js +1 -1
- package/dist/monitoring/types.js.map +1 -0
- package/dist/node-server/index.d.ts +4 -22
- package/dist/node-server/index.js +254 -21
- package/dist/node-server/index.js.map +1 -0
- package/dist/node-server/request.d.ts +6 -2
- package/dist/node-server/request.js +102 -134
- package/dist/node-server/request.js.map +1 -0
- package/dist/node-server/response.d.ts +7 -3
- package/dist/node-server/response.js +67 -89
- package/dist/node-server/response.js.map +1 -0
- package/dist/node-server/serve.d.ts +11 -7
- package/dist/node-server/serve.js +231 -82
- package/dist/node-server/serve.js.map +1 -0
- package/dist/router/index.d.ts +3 -5
- package/dist/router/index.js +228 -7
- package/dist/router/index.js.map +1 -0
- package/dist/router/radix-tree.d.ts +7 -4
- package/dist/router/radix-tree.js +186 -218
- package/dist/router/radix-tree.js.map +1 -0
- package/dist/router.d.ts +7 -3
- package/dist/router.js +37 -83
- package/dist/router.js.map +1 -0
- package/dist/serve.d.ts +2 -12
- package/dist/serve.js +237 -11
- package/dist/serve.js.map +1 -0
- package/dist/server/base-server.d.ts +5 -2
- package/dist/server/base-server.js +124 -135
- package/dist/server/base-server.js.map +1 -0
- package/dist/server/component-server.d.ts +9 -4
- package/dist/server/component-server.js +481 -139
- package/dist/server/component-server.js.map +1 -0
- package/dist/server/index.d.ts +8 -7
- package/dist/server/index.js +985 -11
- package/dist/server/index.js.map +1 -0
- package/dist/server/server-factory.d.ts +11 -5
- package/dist/server/server-factory.js +979 -67
- package/dist/server/server-factory.js.map +1 -0
- package/dist/server/server.d.ts +7 -3
- package/dist/server/server.js +553 -112
- package/dist/server/server.js.map +1 -0
- package/dist/types/component-route.d.ts +8 -4
- package/dist/types/component-route.js +1 -1
- package/dist/types/component-route.js.map +1 -0
- package/dist/types/index.d.ts +5 -5
- package/dist/types/index.js +21 -4
- package/dist/types/index.js.map +1 -0
- package/dist/types/route.d.ts +13 -10
- package/dist/types/route.js +10 -9
- package/dist/types/route.js.map +1 -0
- package/dist/types/schema.d.ts +11 -7
- package/dist/types/schema.js +1 -1
- package/dist/types/schema.js.map +1 -0
- package/dist/types/types.d.ts +11 -9
- package/dist/types/types.js +1 -1
- package/dist/types/types.js.map +1 -0
- package/dist/utils/base64url.d.ts +4 -2
- package/dist/utils/base64url.js +12 -9
- package/dist/utils/base64url.js.map +1 -0
- package/dist/utils/create-handler.d.ts +11 -7
- package/dist/utils/create-handler.js +393 -217
- package/dist/utils/create-handler.js.map +1 -0
- package/dist/utils/dependency-manager.d.ts +3 -1
- package/dist/utils/dependency-manager.js +67 -69
- package/dist/utils/dependency-manager.js.map +1 -0
- package/dist/utils/go-await.d.ts +3 -1
- package/dist/utils/go-await.js +8 -22
- package/dist/utils/go-await.js.map +1 -0
- package/dist/utils/handle.d.ts +6 -4
- package/dist/utils/handle.js +44 -25
- package/dist/utils/handle.js.map +1 -0
- package/dist/utils/html-renderer.d.ts +3 -1
- package/dist/utils/html-renderer.js +25 -24
- package/dist/utils/html-renderer.js.map +1 -0
- package/dist/utils/index.d.ts +13 -13
- package/dist/utils/index.js +832 -21
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/parsers.d.ts +15 -13
- package/dist/utils/parsers.js +138 -188
- package/dist/utils/parsers.js.map +1 -0
- package/dist/utils/path-matcher.d.ts +3 -1
- package/dist/utils/path-matcher.js +68 -78
- package/dist/utils/path-matcher.js.map +1 -0
- package/dist/utils/request-validator.d.ts +13 -10
- package/dist/utils/request-validator.js +234 -84
- package/dist/utils/request-validator.js.map +1 -0
- package/dist/utils/response.d.ts +9 -7
- package/dist/utils/response.js +93 -102
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/validators/schema-validator.d.ts +13 -9
- package/dist/utils/validators/schema-validator.js +228 -209
- package/dist/utils/validators/schema-validator.js.map +1 -0
- package/dist/utils/validators/schema-validators-ultra.d.ts +15 -12
- package/dist/utils/validators/schema-validators-ultra.js +233 -256
- package/dist/utils/validators/schema-validators-ultra.js.map +1 -0
- package/dist/utils/validators/validators.d.ts +15 -12
- package/dist/utils/validators/validators.js +81 -122
- package/dist/utils/validators/validators.js.map +1 -0
- package/package.json +5 -4
|
@@ -1,222 +1,190 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const firstChar = segment[0];
|
|
50
|
-
if (firstChar === ":") {
|
|
51
|
-
// 动态参数节点
|
|
52
|
-
if (!node.paramChild) {
|
|
53
|
-
node.paramChild = this.createNode(segment);
|
|
54
|
-
node.paramChild.paramName = segment.substring(1);
|
|
55
|
-
}
|
|
56
|
-
node = node.paramChild;
|
|
57
|
-
}
|
|
58
|
-
else if (firstChar === "*") {
|
|
59
|
-
// 通配符节点
|
|
60
|
-
if (!node.wildcardChild) {
|
|
61
|
-
node.wildcardChild = this.createNode(segment);
|
|
62
|
-
node.wildcardChild.paramName =
|
|
63
|
-
segment.length > 1 ? segment.substring(1) : "*";
|
|
64
|
-
}
|
|
65
|
-
node = node.wildcardChild;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
// 静态路径节点
|
|
70
|
-
if (!node.children[segment]) {
|
|
71
|
-
node.children[segment] = this.createNode(segment);
|
|
72
|
-
}
|
|
73
|
-
node = node.children[segment];
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
const routeHandler = { handler, middleware };
|
|
77
|
-
// 如果没有全局中间件且设置了编译器,预编译处理链
|
|
78
|
-
if (this.compiler && middleware.length === 0) {
|
|
79
|
-
routeHandler.compiled = this.compiler([], handler);
|
|
80
|
-
}
|
|
81
|
-
node.handlers[method] = routeHandler;
|
|
82
|
-
}
|
|
83
|
-
/** 预编译所有路由(在添加全局中间件后调用) */
|
|
84
|
-
precompileAll(globalMiddleware) {
|
|
85
|
-
if (!this.compiler)
|
|
86
|
-
return;
|
|
87
|
-
this.precompileNode(this.root, globalMiddleware);
|
|
88
|
-
}
|
|
89
|
-
precompileNode(node, globalMiddleware) {
|
|
90
|
-
for (const method in node.handlers) {
|
|
91
|
-
const routeHandler = node.handlers[method];
|
|
92
|
-
if (routeHandler) {
|
|
93
|
-
const allMiddleware = [...globalMiddleware, ...routeHandler.middleware];
|
|
94
|
-
routeHandler.compiled = this.compiler(allMiddleware, routeHandler.handler);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
for (const key in node.children) {
|
|
98
|
-
this.precompileNode(node.children[key], globalMiddleware);
|
|
99
|
-
}
|
|
100
|
-
if (node.paramChild) {
|
|
101
|
-
this.precompileNode(node.paramChild, globalMiddleware);
|
|
102
|
-
}
|
|
103
|
-
if (node.wildcardChild) {
|
|
104
|
-
this.precompileNode(node.wildcardChild, globalMiddleware);
|
|
105
|
-
}
|
|
1
|
+
// src/router/radix-tree.ts
|
|
2
|
+
var RadixRouter = class {
|
|
3
|
+
root;
|
|
4
|
+
constructor() {
|
|
5
|
+
this.root = this.createNode("");
|
|
6
|
+
}
|
|
7
|
+
createNode(path) {
|
|
8
|
+
return {
|
|
9
|
+
path,
|
|
10
|
+
children: /* @__PURE__ */ Object.create(null),
|
|
11
|
+
handlers: /* @__PURE__ */ Object.create(null)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** 分割路径 */
|
|
15
|
+
splitPath(path) {
|
|
16
|
+
return path.split("/").filter(Boolean);
|
|
17
|
+
}
|
|
18
|
+
/** 编译器函数 - 用于预编译中间件链 */
|
|
19
|
+
compiler;
|
|
20
|
+
/** 设置中间件编译器 */
|
|
21
|
+
setCompiler(compiler) {
|
|
22
|
+
this.compiler = compiler;
|
|
23
|
+
}
|
|
24
|
+
/** 注册路由 */
|
|
25
|
+
register(method, pattern, handler, middleware = []) {
|
|
26
|
+
const segments = this.splitPath(pattern);
|
|
27
|
+
let node = this.root;
|
|
28
|
+
for (const segment of segments) {
|
|
29
|
+
const firstChar = segment[0];
|
|
30
|
+
if (firstChar === ":") {
|
|
31
|
+
if (!node.paramChild) {
|
|
32
|
+
node.paramChild = this.createNode(segment);
|
|
33
|
+
node.paramChild.paramName = segment.substring(1);
|
|
34
|
+
}
|
|
35
|
+
node = node.paramChild;
|
|
36
|
+
} else if (firstChar === "*") {
|
|
37
|
+
if (!node.wildcardChild) {
|
|
38
|
+
node.wildcardChild = this.createNode(segment);
|
|
39
|
+
node.wildcardChild.paramName = segment.length > 1 ? segment.substring(1) : "*";
|
|
40
|
+
}
|
|
41
|
+
node = node.wildcardChild;
|
|
42
|
+
break;
|
|
43
|
+
} else {
|
|
44
|
+
if (!node.children[segment]) {
|
|
45
|
+
node.children[segment] = this.createNode(segment);
|
|
46
|
+
}
|
|
47
|
+
node = node.children[segment];
|
|
48
|
+
}
|
|
106
49
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (node.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
50
|
+
const routeHandler = { handler, middleware };
|
|
51
|
+
if (this.compiler && middleware.length === 0) {
|
|
52
|
+
routeHandler.compiled = this.compiler([], handler);
|
|
53
|
+
}
|
|
54
|
+
node.handlers[method] = routeHandler;
|
|
55
|
+
}
|
|
56
|
+
/** 预编译所有路由(在添加全局中间件后调用) */
|
|
57
|
+
precompileAll(globalMiddleware) {
|
|
58
|
+
if (!this.compiler) return;
|
|
59
|
+
this.precompileNode(this.root, globalMiddleware);
|
|
60
|
+
}
|
|
61
|
+
precompileNode(node, globalMiddleware) {
|
|
62
|
+
for (const method in node.handlers) {
|
|
63
|
+
const routeHandler = node.handlers[method];
|
|
64
|
+
if (routeHandler) {
|
|
65
|
+
const allMiddleware = [...globalMiddleware, ...routeHandler.middleware];
|
|
66
|
+
routeHandler.compiled = this.compiler(
|
|
67
|
+
allMiddleware,
|
|
68
|
+
routeHandler.handler
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const key in node.children) {
|
|
73
|
+
this.precompileNode(node.children[key], globalMiddleware);
|
|
74
|
+
}
|
|
75
|
+
if (node.paramChild) {
|
|
76
|
+
this.precompileNode(node.paramChild, globalMiddleware);
|
|
77
|
+
}
|
|
78
|
+
if (node.wildcardChild) {
|
|
79
|
+
this.precompileNode(node.wildcardChild, globalMiddleware);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** 匹配路由 */
|
|
83
|
+
match(method, path) {
|
|
84
|
+
const segments = this.splitPath(path);
|
|
85
|
+
const params = /* @__PURE__ */ Object.create(null);
|
|
86
|
+
const node = this.matchNode(this.root, segments, 0, params);
|
|
87
|
+
if (!node) return null;
|
|
88
|
+
const routeHandler = node.handlers[method];
|
|
89
|
+
if (!routeHandler) return null;
|
|
90
|
+
return {
|
|
91
|
+
handler: routeHandler.handler,
|
|
92
|
+
middleware: routeHandler.middleware,
|
|
93
|
+
params,
|
|
94
|
+
compiled: routeHandler.compiled
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** 递归匹配节点 (优先级: 静态 > 动态参数 > 通配符) */
|
|
98
|
+
matchNode(node, segments, index, params) {
|
|
99
|
+
if (index === segments.length) {
|
|
100
|
+
for (const method in node.handlers) {
|
|
101
|
+
if (node.handlers[method]) return node;
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const segment = segments[index];
|
|
106
|
+
const staticChild = node.children[segment];
|
|
107
|
+
if (staticChild) {
|
|
108
|
+
const result = this.matchNode(staticChild, segments, index + 1, params);
|
|
109
|
+
if (result) return result;
|
|
110
|
+
}
|
|
111
|
+
if (node.paramChild) {
|
|
112
|
+
const paramName = node.paramChild.paramName;
|
|
113
|
+
const oldValue = params[paramName];
|
|
114
|
+
params[paramName] = segment;
|
|
115
|
+
const result = this.matchNode(
|
|
116
|
+
node.paramChild,
|
|
117
|
+
segments,
|
|
118
|
+
index + 1,
|
|
119
|
+
params
|
|
120
|
+
);
|
|
121
|
+
if (result) return result;
|
|
122
|
+
if (oldValue === void 0) {
|
|
123
|
+
delete params[paramName];
|
|
124
|
+
} else {
|
|
125
|
+
params[paramName] = oldValue;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (node.wildcardChild) {
|
|
129
|
+
params[node.wildcardChild.paramName || "*"] = segments.slice(index).join("/");
|
|
130
|
+
return node.wildcardChild;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
/** 获取路径允许的 HTTP 方法 */
|
|
135
|
+
getAllowedMethods(path) {
|
|
136
|
+
const segments = this.splitPath(path);
|
|
137
|
+
const node = this.findNode(segments);
|
|
138
|
+
if (!node) return [];
|
|
139
|
+
const methods = [];
|
|
140
|
+
for (const method in node.handlers) {
|
|
141
|
+
if (node.handlers[method]) {
|
|
142
|
+
methods.push(method);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return methods;
|
|
146
|
+
}
|
|
147
|
+
/** 查找节点(不提取参数) */
|
|
148
|
+
findNode(segments) {
|
|
149
|
+
let node = this.root;
|
|
150
|
+
for (const segment of segments) {
|
|
151
|
+
if (node.children[segment]) {
|
|
152
|
+
node = node.children[segment];
|
|
153
|
+
} else if (node.paramChild) {
|
|
154
|
+
node = node.paramChild;
|
|
155
|
+
} else if (node.wildcardChild) {
|
|
156
|
+
return node.wildcardChild;
|
|
157
|
+
} else {
|
|
164
158
|
return null;
|
|
159
|
+
}
|
|
165
160
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
else if (node.wildcardChild) {
|
|
191
|
-
return node.wildcardChild;
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
return null;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return node;
|
|
198
|
-
}
|
|
199
|
-
/** 获取所有已注册的路由 */
|
|
200
|
-
getRoutes() {
|
|
201
|
-
const routes = [];
|
|
202
|
-
this.collectRoutes(this.root, "", routes);
|
|
203
|
-
return routes;
|
|
204
|
-
}
|
|
205
|
-
collectRoutes(node, prefix, routes) {
|
|
206
|
-
const currentPath = prefix + (node.path ? "/" + node.path : "");
|
|
207
|
-
for (const method in node.handlers) {
|
|
208
|
-
if (node.handlers[method]) {
|
|
209
|
-
routes.push({ method: method, path: currentPath || "/" });
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
for (const key in node.children) {
|
|
213
|
-
this.collectRoutes(node.children[key], currentPath, routes);
|
|
214
|
-
}
|
|
215
|
-
if (node.paramChild) {
|
|
216
|
-
this.collectRoutes(node.paramChild, currentPath, routes);
|
|
217
|
-
}
|
|
218
|
-
if (node.wildcardChild) {
|
|
219
|
-
this.collectRoutes(node.wildcardChild, currentPath, routes);
|
|
220
|
-
}
|
|
161
|
+
return node;
|
|
162
|
+
}
|
|
163
|
+
/** 获取所有已注册的路由 */
|
|
164
|
+
getRoutes() {
|
|
165
|
+
const routes = [];
|
|
166
|
+
this.collectRoutes(this.root, "", routes);
|
|
167
|
+
return routes;
|
|
168
|
+
}
|
|
169
|
+
collectRoutes(node, prefix, routes) {
|
|
170
|
+
const currentPath = prefix + (node.path ? "/" + node.path : "");
|
|
171
|
+
for (const method in node.handlers) {
|
|
172
|
+
if (node.handlers[method]) {
|
|
173
|
+
routes.push({ method, path: currentPath || "/" });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
for (const key in node.children) {
|
|
177
|
+
this.collectRoutes(node.children[key], currentPath, routes);
|
|
178
|
+
}
|
|
179
|
+
if (node.paramChild) {
|
|
180
|
+
this.collectRoutes(node.paramChild, currentPath, routes);
|
|
181
|
+
}
|
|
182
|
+
if (node.wildcardChild) {
|
|
183
|
+
this.collectRoutes(node.wildcardChild, currentPath, routes);
|
|
221
184
|
}
|
|
222
|
-
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
export {
|
|
188
|
+
RadixRouter
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=radix-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/router/radix-tree.ts"],"sourcesContent":["/**\n * Radix Tree 路由匹配器\n *\n * 高性能路由匹配实现,时间复杂度 O(k),k 为路径段数\n *\n * 支持的路由模式:\n * - 静态路径: /users, /api/v1/health\n * - 动态参数: /users/:id, /posts/:postId/comments/:commentId\n * - 通配符: /files/*, /static/*filepath\n */\n\nimport type { Handler, Middleware, Method } from \"../types\";\n\n/** 预编译的处理器类型 */\ntype CompiledHandler = (req: Request) => Promise<Response>;\n\n/** 路由处理信息 */\ninterface RouteHandler {\n handler: Handler;\n middleware: Middleware[];\n /** 预编译后的完整处理链(包含中间件) */\n compiled?: CompiledHandler;\n}\n\n/** Radix Tree 节点 */\ninterface RadixNode {\n path: string;\n children: Record<string, RadixNode>;\n paramChild?: RadixNode;\n wildcardChild?: RadixNode;\n paramName?: string;\n handlers: Record<Method, RouteHandler | undefined>;\n}\n\n/** 路由匹配结果 */\nexport interface MatchResult {\n handler: Handler;\n middleware: Middleware[];\n params: Record<string, string>;\n /** 预编译后的完整处理链 */\n compiled?: CompiledHandler;\n}\n\n/**\n * Radix Tree 路由器\n *\n * @example\n * ```typescript\n * const router = new RadixRouter();\n * router.register(\"GET\", \"/users/:id\", handler);\n * const result = router.match(\"GET\", \"/users/123\");\n * // result.params = { id: \"123\" }\n * ```\n */\nexport class RadixRouter {\n private root: RadixNode;\n\n constructor() {\n this.root = this.createNode(\"\");\n }\n\n private createNode(path: string): RadixNode {\n return {\n path,\n children: Object.create(null),\n handlers: Object.create(null),\n };\n }\n\n /** 分割路径 */\n private splitPath(path: string): string[] {\n return path.split(\"/\").filter(Boolean);\n }\n\n /** 编译器函数 - 用于预编译中间件链 */\n private compiler?: (\n middleware: Middleware[],\n handler: Handler,\n ) => CompiledHandler;\n\n /** 设置中间件编译器 */\n setCompiler(\n compiler: (middleware: Middleware[], handler: Handler) => CompiledHandler,\n ): void {\n this.compiler = compiler;\n }\n\n /** 注册路由 */\n register(\n method: Method,\n pattern: string,\n handler: Handler,\n middleware: Middleware[] = [],\n ): void {\n const segments = this.splitPath(pattern);\n let node = this.root;\n\n for (const segment of segments) {\n const firstChar = segment[0];\n\n if (firstChar === \":\") {\n // 动态参数节点\n if (!node.paramChild) {\n node.paramChild = this.createNode(segment);\n node.paramChild.paramName = segment.substring(1);\n }\n node = node.paramChild;\n } else if (firstChar === \"*\") {\n // 通配符节点\n if (!node.wildcardChild) {\n node.wildcardChild = this.createNode(segment);\n node.wildcardChild.paramName =\n segment.length > 1 ? segment.substring(1) : \"*\";\n }\n node = node.wildcardChild;\n break;\n } else {\n // 静态路径节点\n if (!node.children[segment]) {\n node.children[segment] = this.createNode(segment);\n }\n node = node.children[segment];\n }\n }\n\n const routeHandler: RouteHandler = { handler, middleware };\n\n // 如果没有全局中间件且设置了编译器,预编译处理链\n if (this.compiler && middleware.length === 0) {\n routeHandler.compiled = this.compiler([], handler);\n }\n\n node.handlers[method] = routeHandler;\n }\n\n /** 预编译所有路由(在添加全局中间件后调用) */\n precompileAll(globalMiddleware: Middleware[]): void {\n if (!this.compiler) return;\n this.precompileNode(this.root, globalMiddleware);\n }\n\n private precompileNode(\n node: RadixNode,\n globalMiddleware: Middleware[],\n ): void {\n for (const method in node.handlers) {\n const routeHandler = node.handlers[method as Method];\n if (routeHandler) {\n const allMiddleware = [...globalMiddleware, ...routeHandler.middleware];\n routeHandler.compiled = this.compiler!(\n allMiddleware,\n routeHandler.handler,\n );\n }\n }\n\n for (const key in node.children) {\n this.precompileNode(node.children[key], globalMiddleware);\n }\n\n if (node.paramChild) {\n this.precompileNode(node.paramChild, globalMiddleware);\n }\n\n if (node.wildcardChild) {\n this.precompileNode(node.wildcardChild, globalMiddleware);\n }\n }\n\n /** 匹配路由 */\n match(method: Method, path: string): MatchResult | null {\n const segments = this.splitPath(path);\n const params: Record<string, string> = Object.create(null);\n\n const node = this.matchNode(this.root, segments, 0, params);\n if (!node) return null;\n\n const routeHandler = node.handlers[method];\n if (!routeHandler) return null;\n\n return {\n handler: routeHandler.handler,\n middleware: routeHandler.middleware,\n params,\n compiled: routeHandler.compiled,\n };\n }\n\n /** 递归匹配节点 (优先级: 静态 > 动态参数 > 通配符) */\n private matchNode(\n node: RadixNode,\n segments: string[],\n index: number,\n params: Record<string, string>,\n ): RadixNode | null {\n if (index === segments.length) {\n for (const method in node.handlers) {\n if (node.handlers[method as Method]) return node;\n }\n return null;\n }\n\n const segment = segments[index];\n\n // 1. 静态路径\n const staticChild = node.children[segment];\n if (staticChild) {\n const result = this.matchNode(staticChild, segments, index + 1, params);\n if (result) return result;\n }\n\n // 2. 动态参数\n if (node.paramChild) {\n const paramName = node.paramChild.paramName!;\n const oldValue = params[paramName];\n\n params[paramName] = segment;\n const result = this.matchNode(\n node.paramChild,\n segments,\n index + 1,\n params,\n );\n\n if (result) return result;\n\n // 回溯\n if (oldValue === undefined) {\n delete params[paramName];\n } else {\n params[paramName] = oldValue;\n }\n }\n\n // 3. 通配符\n if (node.wildcardChild) {\n params[node.wildcardChild.paramName || \"*\"] = segments\n .slice(index)\n .join(\"/\");\n return node.wildcardChild;\n }\n\n return null;\n }\n\n /** 获取路径允许的 HTTP 方法 */\n getAllowedMethods(path: string): Method[] {\n const segments = this.splitPath(path);\n const node = this.findNode(segments);\n if (!node) return [];\n\n const methods: Method[] = [];\n for (const method in node.handlers) {\n if (node.handlers[method as Method]) {\n methods.push(method as Method);\n }\n }\n return methods;\n }\n\n /** 查找节点(不提取参数) */\n private findNode(segments: string[]): RadixNode | null {\n let node = this.root;\n\n for (const segment of segments) {\n if (node.children[segment]) {\n node = node.children[segment];\n } else if (node.paramChild) {\n node = node.paramChild;\n } else if (node.wildcardChild) {\n return node.wildcardChild;\n } else {\n return null;\n }\n }\n\n return node;\n }\n\n /** 获取所有已注册的路由 */\n getRoutes(): Array<{ method: Method; path: string }> {\n const routes: Array<{ method: Method; path: string }> = [];\n this.collectRoutes(this.root, \"\", routes);\n return routes;\n }\n\n private collectRoutes(\n node: RadixNode,\n prefix: string,\n routes: Array<{ method: Method; path: string }>,\n ): void {\n const currentPath = prefix + (node.path ? \"/\" + node.path : \"\");\n\n for (const method in node.handlers) {\n if (node.handlers[method as Method]) {\n routes.push({ method: method as Method, path: currentPath || \"/\" });\n }\n }\n\n for (const key in node.children) {\n this.collectRoutes(node.children[key], currentPath, routes);\n }\n\n if (node.paramChild) {\n this.collectRoutes(node.paramChild, currentPath, routes);\n }\n\n if (node.wildcardChild) {\n this.collectRoutes(node.wildcardChild, currentPath, routes);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/router.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { Route, NestedRoute, FlattenedRoute } from './types/types.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* 路由工具函数
|
|
3
5
|
*
|
|
4
6
|
* 提供路由处理的基础工具
|
|
5
7
|
*/
|
|
6
|
-
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* 扁平化嵌套路由
|
|
9
11
|
*
|
|
@@ -28,7 +30,7 @@ import type { Route, NestedRoute, FlattenedRoute } from "./types";
|
|
|
28
30
|
* // ]
|
|
29
31
|
* ```
|
|
30
32
|
*/
|
|
31
|
-
|
|
33
|
+
declare function flattenNestedRoutes(routes: (Route | NestedRoute)[]): FlattenedRoute[];
|
|
32
34
|
/**
|
|
33
35
|
* 标准化路径
|
|
34
36
|
*
|
|
@@ -42,4 +44,6 @@ export declare function flattenNestedRoutes(routes: (Route | NestedRoute)[]): Fl
|
|
|
42
44
|
* normalizePath("/api/%20test") // "/api/ test"
|
|
43
45
|
* ```
|
|
44
46
|
*/
|
|
45
|
-
|
|
47
|
+
declare function normalizePath(path: string): string;
|
|
48
|
+
|
|
49
|
+
export { flattenNestedRoutes, normalizePath };
|
package/dist/router.js
CHANGED
|
@@ -1,86 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* ],
|
|
21
|
-
* },
|
|
22
|
-
* ]);
|
|
23
|
-
* // 结果:
|
|
24
|
-
* // [
|
|
25
|
-
* // { fullPath: "/api/users", method: "GET", ... },
|
|
26
|
-
* // { fullPath: "/api/users/:id", method: "GET", ... },
|
|
27
|
-
* // ]
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export function flattenNestedRoutes(routes) {
|
|
31
|
-
const flattened = [];
|
|
32
|
-
function processRoute(route, parentPath = "", parentMiddleware = []) {
|
|
33
|
-
// 计算当前完整路径
|
|
34
|
-
const currentPath = normalizePath(parentPath + route.path);
|
|
35
|
-
// 合并中间件链
|
|
36
|
-
const currentMiddleware = [
|
|
37
|
-
...parentMiddleware,
|
|
38
|
-
...(route.middleware || []),
|
|
39
|
-
];
|
|
40
|
-
if ("method" in route && "handler" in route) {
|
|
41
|
-
// 叶子路由(有处理函数)
|
|
42
|
-
flattened.push({
|
|
43
|
-
...route,
|
|
44
|
-
fullPath: currentPath,
|
|
45
|
-
middlewareChain: currentMiddleware,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
else if ("children" in route && route.children) {
|
|
49
|
-
// 分组路由,递归处理子路由
|
|
50
|
-
for (const child of route.children) {
|
|
51
|
-
processRoute(child, currentPath, currentMiddleware);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
1
|
+
// src/router.ts
|
|
2
|
+
function flattenNestedRoutes(routes) {
|
|
3
|
+
const flattened = [];
|
|
4
|
+
function processRoute(route, parentPath = "", parentMiddleware = []) {
|
|
5
|
+
const currentPath = normalizePath(parentPath + route.path);
|
|
6
|
+
const currentMiddleware = [
|
|
7
|
+
...parentMiddleware,
|
|
8
|
+
...route.middleware || []
|
|
9
|
+
];
|
|
10
|
+
if ("method" in route && "handler" in route) {
|
|
11
|
+
flattened.push({
|
|
12
|
+
...route,
|
|
13
|
+
fullPath: currentPath,
|
|
14
|
+
middlewareChain: currentMiddleware
|
|
15
|
+
});
|
|
16
|
+
} else if ("children" in route && route.children) {
|
|
17
|
+
for (const child of route.children) {
|
|
18
|
+
processRoute(child, currentPath, currentMiddleware);
|
|
19
|
+
}
|
|
54
20
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
21
|
+
}
|
|
22
|
+
for (const route of routes) {
|
|
23
|
+
processRoute(route);
|
|
24
|
+
}
|
|
25
|
+
return flattened;
|
|
59
26
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
* ```typescript
|
|
69
|
-
* normalizePath("//api//users/") // "/api/users"
|
|
70
|
-
* normalizePath("/api/%20test") // "/api/ test"
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
export function normalizePath(path) {
|
|
74
|
-
// 解码 URL 编码
|
|
75
|
-
let normalized = decodeURIComponent(path);
|
|
76
|
-
// 去除重复斜杠
|
|
77
|
-
normalized = normalized.replace(/\/+/g, "/");
|
|
78
|
-
// 空路径转为根路径
|
|
79
|
-
if (normalized === "")
|
|
80
|
-
return "/";
|
|
81
|
-
// 去除结尾斜杠(根路径除外)
|
|
82
|
-
if (normalized !== "/" && normalized.endsWith("/")) {
|
|
83
|
-
normalized = normalized.slice(0, -1);
|
|
84
|
-
}
|
|
85
|
-
return normalized;
|
|
27
|
+
function normalizePath(path) {
|
|
28
|
+
let normalized = decodeURIComponent(path);
|
|
29
|
+
normalized = normalized.replace(/\/+/g, "/");
|
|
30
|
+
if (normalized === "") return "/";
|
|
31
|
+
if (normalized !== "/" && normalized.endsWith("/")) {
|
|
32
|
+
normalized = normalized.slice(0, -1);
|
|
33
|
+
}
|
|
34
|
+
return normalized;
|
|
86
35
|
}
|
|
36
|
+
export {
|
|
37
|
+
flattenNestedRoutes,
|
|
38
|
+
normalizePath
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/router.ts"],"sourcesContent":["/**\n * 路由工具函数\n *\n * 提供路由处理的基础工具\n */\n\nimport type { Route, NestedRoute, FlattenedRoute, Middleware } from \"./types\";\n\n/**\n * 扁平化嵌套路由\n *\n * 将嵌套路由结构转换为扁平数组,计算完整路径和中间件链\n *\n * @example\n * ```typescript\n * const routes = flattenNestedRoutes([\n * {\n * path: \"/api\",\n * middleware: [authMiddleware],\n * children: [\n * { path: \"/users\", method: \"GET\", handler: getUsers },\n * { path: \"/users/:id\", method: \"GET\", handler: getUser },\n * ],\n * },\n * ]);\n * // 结果:\n * // [\n * // { fullPath: \"/api/users\", method: \"GET\", ... },\n * // { fullPath: \"/api/users/:id\", method: \"GET\", ... },\n * // ]\n * ```\n */\nexport function flattenNestedRoutes(\n routes: (Route | NestedRoute)[],\n): FlattenedRoute[] {\n const flattened: FlattenedRoute[] = [];\n\n function processRoute(\n route: Route | NestedRoute,\n parentPath = \"\",\n parentMiddleware: Middleware[] = [],\n ): void {\n // 计算当前完整路径\n const currentPath = normalizePath(parentPath + route.path);\n // 合并中间件链\n const currentMiddleware = [\n ...parentMiddleware,\n ...(route.middleware || []),\n ];\n\n if (\"method\" in route && \"handler\" in route) {\n // 叶子路由(有处理函数)\n flattened.push({\n ...route,\n fullPath: currentPath,\n middlewareChain: currentMiddleware,\n });\n } else if (\"children\" in route && route.children) {\n // 分组路由,递归处理子路由\n for (const child of route.children) {\n processRoute(child, currentPath, currentMiddleware);\n }\n }\n }\n\n for (const route of routes) {\n processRoute(route);\n }\n\n return flattened;\n}\n\n/**\n * 标准化路径\n *\n * - 解码 URL 编码字符\n * - 去除重复斜杠\n * - 处理结尾斜杠\n *\n * @example\n * ```typescript\n * normalizePath(\"//api//users/\") // \"/api/users\"\n * normalizePath(\"/api/%20test\") // \"/api/ test\"\n * ```\n */\nexport function normalizePath(path: string): string {\n // 解码 URL 编码\n let normalized = decodeURIComponent(path);\n\n // 去除重复斜杠\n normalized = normalized.replace(/\\/+/g, \"/\");\n\n // 空路径转为根路径\n if (normalized === \"\") return \"/\";\n\n // 去除结尾斜杠(根路径除外)\n if (normalized !== \"/\" && normalized.endsWith(\"/\")) {\n normalized = normalized.slice(0, -1);\n }\n\n return normalized;\n}\n"],"mappings":";AAgCO,SAAS,oBACd,QACkB;AAClB,QAAM,YAA8B,CAAC;AAErC,WAAS,aACP,OACA,aAAa,IACb,mBAAiC,CAAC,GAC5B;AAEN,UAAM,cAAc,cAAc,aAAa,MAAM,IAAI;AAEzD,UAAM,oBAAoB;AAAA,MACxB,GAAG;AAAA,MACH,GAAI,MAAM,cAAc,CAAC;AAAA,IAC3B;AAEA,QAAI,YAAY,SAAS,aAAa,OAAO;AAE3C,gBAAU,KAAK;AAAA,QACb,GAAG;AAAA,QACH,UAAU;AAAA,QACV,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH,WAAW,cAAc,SAAS,MAAM,UAAU;AAEhD,iBAAW,SAAS,MAAM,UAAU;AAClC,qBAAa,OAAO,aAAa,iBAAiB;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAEA,aAAW,SAAS,QAAQ;AAC1B,iBAAa,KAAK;AAAA,EACpB;AAEA,SAAO;AACT;AAeO,SAAS,cAAc,MAAsB;AAElD,MAAI,aAAa,mBAAmB,IAAI;AAGxC,eAAa,WAAW,QAAQ,QAAQ,GAAG;AAG3C,MAAI,eAAe,GAAI,QAAO;AAG9B,MAAI,eAAe,OAAO,WAAW,SAAS,GAAG,GAAG;AAClD,iBAAa,WAAW,MAAM,GAAG,EAAE;AAAA,EACrC;AAEA,SAAO;AACT;","names":[]}
|
package/dist/serve.d.ts
CHANGED
|
@@ -1,12 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* 使用 Node.js 原生 http 模块,兼容 Bun 和 Node.js
|
|
4
|
-
*
|
|
5
|
-
* 基准测试结果(Bun 环境):
|
|
6
|
-
* - Bun.serve: 35,422 req/s
|
|
7
|
-
* - node:http: 38,075 req/s
|
|
8
|
-
*
|
|
9
|
-
* node:http 在 Bun 下性能甚至更好,无需使用 Bun API
|
|
10
|
-
*/
|
|
11
|
-
export { serve, createAdaptorServer } from "./node-server/serve";
|
|
12
|
-
export type { ServeOptions, ServeResult, FetchHandler, } from "./node-server/serve";
|
|
1
|
+
export { FetchHandler, ServeOptions, ServeResult, createAdaptorServer, serve } from './node-server/serve.js';
|
|
2
|
+
import 'node:http';
|