vafast 0.4.1 → 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 -23
- 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 -2575
- 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 -1484
- package/dist/monitoring/index.js.map +0 -1
- package/dist/monitoring/native-monitor.d.ts +0 -44
- package/dist/monitoring/native-monitor.js +0 -1451
- 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 -229
- 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 -41
- 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 -1156
- package/dist/server/index.js.map +0 -1
- package/dist/server/server-factory.d.ts +0 -48
- package/dist/server/server-factory.js +0 -1153
- package/dist/server/server-factory.js.map +0 -1
- package/dist/server/server.d.ts +0 -64
- package/dist/server/server.js +0 -734
- 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
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
// src/utils/validators/validators.ts
|
|
2
|
-
import { Type } from "@sinclair/typebox";
|
|
3
|
-
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
4
|
-
var compilerCache = /* @__PURE__ */ new WeakMap();
|
|
5
|
-
function getCompiledValidator(schema) {
|
|
6
|
-
let compiler = compilerCache.get(schema);
|
|
7
|
-
if (!compiler) {
|
|
8
|
-
compiler = TypeCompiler.Compile(schema);
|
|
9
|
-
compilerCache.set(schema, compiler);
|
|
10
|
-
}
|
|
11
|
-
return compiler;
|
|
12
|
-
}
|
|
13
|
-
function validateSchemaOrThrow(schema, data, context) {
|
|
14
|
-
const compiler = getCompiledValidator(schema);
|
|
15
|
-
if (!compiler.Check(data)) {
|
|
16
|
-
throw new Error(`${context}\u9A8C\u8BC1\u5931\u8D25`);
|
|
17
|
-
}
|
|
18
|
-
return data;
|
|
19
|
-
}
|
|
20
|
-
function validateAllSchemas(config, data) {
|
|
21
|
-
if (config.body) {
|
|
22
|
-
validateSchemaOrThrow(config.body, data.body, "\u8BF7\u6C42\u4F53");
|
|
23
|
-
}
|
|
24
|
-
if (config.query) {
|
|
25
|
-
validateSchemaOrThrow(config.query, data.query, "Query\u53C2\u6570");
|
|
26
|
-
}
|
|
27
|
-
if (config.params) {
|
|
28
|
-
validateSchemaOrThrow(config.params, data.params, "\u8DEF\u5F84\u53C2\u6570");
|
|
29
|
-
}
|
|
30
|
-
if (config.headers) {
|
|
31
|
-
validateSchemaOrThrow(config.headers, data.headers, "\u8BF7\u6C42\u5934");
|
|
32
|
-
}
|
|
33
|
-
if (config.cookies) {
|
|
34
|
-
validateSchemaOrThrow(config.cookies, data.cookies, "Cookie");
|
|
35
|
-
}
|
|
36
|
-
return data;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// src/utils/parsers.ts
|
|
40
|
-
import qs from "qs";
|
|
41
|
-
import cookie from "cookie";
|
|
42
|
-
async function parseBody(req) {
|
|
43
|
-
const contentType = req.headers.get("content-type") || "";
|
|
44
|
-
if (contentType.includes("application/json")) {
|
|
45
|
-
return await req.json();
|
|
46
|
-
}
|
|
47
|
-
if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
48
|
-
const text = await req.text();
|
|
49
|
-
return Object.fromEntries(new URLSearchParams(text));
|
|
50
|
-
}
|
|
51
|
-
return await req.text();
|
|
52
|
-
}
|
|
53
|
-
function extractQueryString(url) {
|
|
54
|
-
const qIndex = url.indexOf("?");
|
|
55
|
-
if (qIndex === -1) return "";
|
|
56
|
-
const hashIndex = url.indexOf("#", qIndex);
|
|
57
|
-
return hashIndex === -1 ? url.substring(qIndex + 1) : url.substring(qIndex + 1, hashIndex);
|
|
58
|
-
}
|
|
59
|
-
function parseQuery(req) {
|
|
60
|
-
const queryString = extractQueryString(req.url);
|
|
61
|
-
if (!queryString) return {};
|
|
62
|
-
return qs.parse(queryString);
|
|
63
|
-
}
|
|
64
|
-
function parseHeaders(req) {
|
|
65
|
-
const headers = /* @__PURE__ */ Object.create(null);
|
|
66
|
-
req.headers.forEach((value, key) => {
|
|
67
|
-
headers[key] = value;
|
|
68
|
-
});
|
|
69
|
-
return headers;
|
|
70
|
-
}
|
|
71
|
-
function parseCookies(req) {
|
|
72
|
-
const cookieHeader = req.headers.get("cookie");
|
|
73
|
-
if (!cookieHeader) return {};
|
|
74
|
-
try {
|
|
75
|
-
const parsed = cookie.parse(cookieHeader);
|
|
76
|
-
const result = {};
|
|
77
|
-
for (const [key, value] of Object.entries(parsed)) {
|
|
78
|
-
if (value !== void 0 && value !== null) {
|
|
79
|
-
result[key] = value;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return result;
|
|
83
|
-
} catch {
|
|
84
|
-
return {};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// src/utils/request-validator.ts
|
|
89
|
-
async function parseRequest(request, params) {
|
|
90
|
-
const requestData = {
|
|
91
|
-
body: void 0,
|
|
92
|
-
query: parseQuery(request),
|
|
93
|
-
params: params || {},
|
|
94
|
-
headers: parseHeaders(request),
|
|
95
|
-
cookies: parseCookies(request)
|
|
96
|
-
};
|
|
97
|
-
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
98
|
-
requestData.body = await parseBody(request);
|
|
99
|
-
}
|
|
100
|
-
return requestData;
|
|
101
|
-
}
|
|
102
|
-
function validateRequest(config, requestData) {
|
|
103
|
-
try {
|
|
104
|
-
const validatedData = validateAllSchemas(config, requestData);
|
|
105
|
-
return {
|
|
106
|
-
success: true,
|
|
107
|
-
data: validatedData
|
|
108
|
-
};
|
|
109
|
-
} catch (error) {
|
|
110
|
-
return {
|
|
111
|
-
success: false,
|
|
112
|
-
errors: [
|
|
113
|
-
{
|
|
114
|
-
field: "unknown",
|
|
115
|
-
message: error instanceof Error ? error.message : "\u9A8C\u8BC1\u5931\u8D25"
|
|
116
|
-
}
|
|
117
|
-
]
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async function parseAndValidateRequest(request, config, params) {
|
|
122
|
-
try {
|
|
123
|
-
const requestData = await parseRequest(request, params);
|
|
124
|
-
return validateRequest(config, requestData);
|
|
125
|
-
} catch (error) {
|
|
126
|
-
return {
|
|
127
|
-
success: false,
|
|
128
|
-
errors: [
|
|
129
|
-
{
|
|
130
|
-
field: "unknown",
|
|
131
|
-
message: error instanceof Error ? error.message : "\u8BF7\u6C42\u89E3\u6790\u5931\u8D25"
|
|
132
|
-
}
|
|
133
|
-
]
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
function createRequestValidator(config) {
|
|
138
|
-
return async (request, params) => {
|
|
139
|
-
return parseAndValidateRequest(request, config, params);
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
export {
|
|
143
|
-
createRequestValidator,
|
|
144
|
-
parseAndValidateRequest,
|
|
145
|
-
parseRequest,
|
|
146
|
-
validateRequest
|
|
147
|
-
};
|
|
148
|
-
/**
|
|
149
|
-
* 请求解析和验证器
|
|
150
|
-
*
|
|
151
|
-
* 解析handler的req参数,使用Ultra验证器进行验证,
|
|
152
|
-
* 并类型安全地返回解析出来的值
|
|
153
|
-
*
|
|
154
|
-
* @author Framework Team
|
|
155
|
-
* @version 1.0.0
|
|
156
|
-
* @license MIT
|
|
157
|
-
*/
|
|
158
|
-
//# sourceMappingURL=request-validator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/validators/validators.ts","../../src/utils/parsers.ts","../../src/utils/request-validator.ts"],"sourcesContent":["/**\n * Schema 验证器 - 简洁版\n *\n * 特点:\n * - WeakMap 缓存避免内存泄漏\n * - TypeCompiler JIT 编译,性能最佳\n * - 支持 FormatRegistry(需确保同一实例)\n *\n * @version 7.0.0\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { Static, TSchema } from \"@sinclair/typebox\";\nimport { TypeCompiler, type TypeCheck } from \"@sinclair/typebox/compiler\";\nimport { Value } from \"@sinclair/typebox/value\";\n\n// ============== 类型定义 ==============\n\n/** Schema 配置接口 */\nexport interface SchemaConfig {\n body?: TSchema;\n query?: TSchema;\n params?: TSchema;\n headers?: TSchema;\n cookies?: TSchema;\n}\n\n/** 验证错误接口 */\nexport interface ValidationError {\n path: string;\n message: string;\n code: string;\n value?: unknown;\n}\n\n/** 验证结果 */\nexport type ValidationResult<T = unknown> =\n | { success: true; data: T }\n | { success: false; errors: ValidationError[] };\n\n// ============== 缓存 ==============\n\n/** 编译器缓存 - WeakMap 避免内存泄漏 */\nconst compilerCache = new WeakMap<TSchema, TypeCheck<TSchema>>();\n\n// ============== 核心函数 ==============\n\n/**\n * 获取或创建编译后的验证器\n */\nfunction getCompiledValidator<T extends TSchema>(schema: T): TypeCheck<T> {\n let compiler = compilerCache.get(schema);\n if (!compiler) {\n compiler = TypeCompiler.Compile(schema);\n compilerCache.set(schema, compiler);\n }\n return compiler as TypeCheck<T>;\n}\n\n/**\n * 验证单个 Schema(返回结果对象)\n */\nexport function validateSchema<T extends TSchema>(\n schema: T,\n data: unknown,\n): ValidationResult<Static<T>> {\n try {\n const compiler = getCompiledValidator(schema);\n\n if (compiler.Check(data)) {\n return { success: true, data: data as Static<T> };\n }\n\n // 收集错误\n const errors: ValidationError[] = [];\n for (const error of compiler.Errors(data)) {\n errors.push({\n path: error.path,\n message: error.message,\n code: \"VALIDATION_FAILED\",\n value: error.value,\n });\n }\n return { success: false, errors };\n } catch (error) {\n return {\n success: false,\n errors: [\n {\n path: \"\",\n message: error instanceof Error ? error.message : \"验证异常\",\n code: \"VALIDATION_EXCEPTION\",\n },\n ],\n };\n }\n}\n\n/**\n * 验证 Schema(抛出异常版本,用于框架内部)\n */\nexport function validateSchemaOrThrow<T extends TSchema>(\n schema: T,\n data: unknown,\n context: string,\n): Static<T> {\n const compiler = getCompiledValidator(schema);\n\n if (!compiler.Check(data)) {\n throw new Error(`${context}验证失败`);\n }\n\n return data as Static<T>;\n}\n\n/**\n * 快速验证(只返回布尔值)\n */\nexport function validateFast<T extends TSchema>(\n schema: T,\n data: unknown,\n): data is Static<T> {\n const compiler = getCompiledValidator(schema);\n return compiler.Check(data);\n}\n\n/**\n * 批量验证所有 Schema(用于请求验证)\n */\nexport function validateAllSchemas(\n config: SchemaConfig,\n data: {\n body: unknown;\n query: unknown;\n params: unknown;\n headers: unknown;\n cookies: unknown;\n },\n): typeof data {\n if (config.body) {\n validateSchemaOrThrow(config.body, data.body, \"请求体\");\n }\n if (config.query) {\n validateSchemaOrThrow(config.query, data.query, \"Query参数\");\n }\n if (config.params) {\n validateSchemaOrThrow(config.params, data.params, \"路径参数\");\n }\n if (config.headers) {\n validateSchemaOrThrow(config.headers, data.headers, \"请求头\");\n }\n if (config.cookies) {\n validateSchemaOrThrow(config.cookies, data.cookies, \"Cookie\");\n }\n return data;\n}\n\n/**\n * 预编译 Schema(启动时调用,避免首次请求开销)\n */\nexport function precompileSchemas(config: SchemaConfig): void {\n if (config.body) getCompiledValidator(config.body);\n if (config.query) getCompiledValidator(config.query);\n if (config.params) getCompiledValidator(config.params);\n if (config.headers) getCompiledValidator(config.headers);\n if (config.cookies) getCompiledValidator(config.cookies);\n}\n\n/**\n * 创建类型特化的验证器(高频使用场景)\n */\nexport function createValidator<T extends TSchema>(\n schema: T,\n): (data: unknown) => ValidationResult<Static<T>> {\n return (data: unknown) => validateSchema(schema, data);\n}\n\n/**\n * 获取缓存统计(调试用)\n */\nexport function getValidatorCacheStats(): { cacheType: string; note: string } {\n return {\n cacheType: \"WeakMap\",\n note: \"WeakMap 缓存会随 Schema 对象自动清理,无内存泄漏风险\",\n };\n}\n\n// 导出 TypeBox 类型\nexport { Type, Static, TSchema };\n","// src/parsers.ts\nimport qs from \"qs\";\nimport cookie from \"cookie\";\n\n// 文件信息接口\nexport interface FileInfo {\n name: string;\n type: string;\n size: number;\n data: ArrayBuffer;\n}\n\n// 表单数据接口\nexport interface FormData {\n fields: Record<string, string>;\n files: Record<string, FileInfo>;\n}\n\n/**\n * 简化的请求体解析函数\n * 优先简洁性,处理最常见的场景\n */\nexport async function parseBody(req: Request): Promise<unknown> {\n const contentType = req.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n return await req.json();\n }\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const text = await req.text();\n return Object.fromEntries(new URLSearchParams(text));\n }\n return await req.text(); // fallback\n}\n\n/**\n * 解析 multipart/form-data 格式\n * 支持文件上传和普通表单字段\n */\nasync function parseMultipartFormData(req: Request): Promise<FormData> {\n const formData = await req.formData();\n const result: FormData = {\n fields: {},\n files: {},\n };\n\n for (const [key, value] of formData.entries()) {\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"name\" in value &&\n \"type\" in value &&\n \"size\" in value\n ) {\n // 处理文件\n const file = value as any;\n const arrayBuffer = await file.arrayBuffer();\n result.files[key] = {\n name: file.name,\n type: file.type,\n size: file.size,\n data: arrayBuffer,\n };\n } else {\n // 处理普通字段\n result.fields[key] = value as string;\n }\n }\n\n return result;\n}\n\n/**\n * 解析请求体为特定类型\n * 提供类型安全的解析方法\n */\nexport async function parseBodyAs<T>(req: Request): Promise<T> {\n const body = await parseBody(req);\n return body as T;\n}\n\n/**\n * 解析请求体为表单数据\n * 专门用于处理 multipart/form-data\n */\nexport async function parseFormData(req: Request): Promise<FormData> {\n const contentType = req.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"multipart/form-data\")) {\n throw new Error(\"请求不是 multipart/form-data 格式\");\n }\n\n return await parseMultipartFormData(req);\n}\n\n/**\n * 解析请求体为文件\n * 专门用于处理文件上传\n */\nexport async function parseFile(req: Request): Promise<FileInfo> {\n const contentType = req.headers.get(\"content-type\") || \"\";\n\n if (!contentType.includes(\"multipart/form-data\")) {\n throw new Error(\"请求不是 multipart/form-data 格式\");\n }\n\n const formData = await parseMultipartFormData(req);\n const fileKeys = Object.keys(formData.files);\n\n if (fileKeys.length === 0) {\n throw new Error(\"请求中没有文件\");\n }\n\n if (fileKeys.length > 1) {\n throw new Error(\"请求中包含多个文件,请使用 parseFormData\");\n }\n\n return formData.files[fileKeys[0]];\n}\n\n/**\n * 快速提取 query string(避免创建 URL 对象)\n */\nfunction extractQueryString(url: string): string {\n const qIndex = url.indexOf(\"?\");\n if (qIndex === -1) return \"\";\n\n const hashIndex = url.indexOf(\"#\", qIndex);\n return hashIndex === -1\n ? url.substring(qIndex + 1)\n : url.substring(qIndex + 1, hashIndex);\n}\n\n/** 获取查询字符串,直接返回对象 */\nexport function parseQuery(req: Request): Record<string, unknown> {\n const queryString = extractQueryString(req.url);\n if (!queryString) return {};\n return qs.parse(queryString);\n}\n\n/**\n * 快速解析简单查询字符串(不支持嵌套,但更快)\n * 适用于简单的 key=value&key2=value2 场景\n */\nexport function parseQueryFast(req: Request): Record<string, string> {\n const queryString = extractQueryString(req.url);\n if (!queryString) return {};\n\n const result: Record<string, string> = Object.create(null);\n const pairs = queryString.split(\"&\");\n\n for (const pair of pairs) {\n const eqIndex = pair.indexOf(\"=\");\n if (eqIndex === -1) {\n result[decodeURIComponent(pair)] = \"\";\n } else {\n const key = decodeURIComponent(pair.substring(0, eqIndex));\n const value = decodeURIComponent(pair.substring(eqIndex + 1));\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/** 解析请求头,返回对象 */\nexport function parseHeaders(req: Request): Record<string, string> {\n const headers: Record<string, string> = Object.create(null);\n req.headers.forEach((value, key) => {\n headers[key] = value;\n });\n return headers;\n}\n\n/**\n * 获取单个请求头(避免解析全部)\n */\nexport function getHeader(req: Request, name: string): string | null {\n return req.headers.get(name);\n}\n\n/** 使用cookie库解析Cookie,保证可靠性 */\nexport function parseCookies(req: Request): Record<string, string> {\n const cookieHeader = req.headers.get(\"cookie\");\n if (!cookieHeader) return {};\n\n try {\n const parsed = cookie.parse(cookieHeader);\n // 过滤掉undefined和null值\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (value !== undefined && value !== null) {\n result[key] = value;\n }\n }\n return result;\n } catch {\n return {};\n }\n}\n\n/**\n * 快速解析 Cookie(简化版,不使用外部库)\n * 适用于简单的 cookie 场景\n */\nexport function parseCookiesFast(req: Request): Record<string, string> {\n const cookieHeader = req.headers.get(\"cookie\");\n if (!cookieHeader) return {};\n\n const result: Record<string, string> = Object.create(null);\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const trimmed = pair.trim();\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex > 0) {\n const key = trimmed.substring(0, eqIndex).trim();\n const value = trimmed.substring(eqIndex + 1).trim();\n // 移除引号\n result[key] =\n value.startsWith('\"') && value.endsWith('\"')\n ? value.slice(1, -1)\n : value;\n }\n }\n\n return result;\n}\n\n/**\n * 获取单个 Cookie 值(避免解析全部)\n */\nexport function getCookie(req: Request, name: string): string | null {\n const cookieHeader = req.headers.get(\"cookie\");\n if (!cookieHeader) return null;\n\n const prefix = `${name}=`;\n const pairs = cookieHeader.split(\";\");\n\n for (const pair of pairs) {\n const trimmed = pair.trim();\n if (trimmed.startsWith(prefix)) {\n const value = trimmed.substring(prefix.length).trim();\n return value.startsWith('\"') && value.endsWith('\"')\n ? value.slice(1, -1)\n : value;\n }\n }\n\n return null;\n}\n","/**\n * 请求解析和验证器\n *\n * 解析handler的req参数,使用Ultra验证器进行验证,\n * 并类型安全地返回解析出来的值\n *\n * @author Framework Team\n * @version 1.0.0\n * @license MIT\n */\n\nimport type { TSchema } from \"@sinclair/typebox\";\nimport type { Static } from \"@sinclair/typebox\";\nimport {\n validateAllSchemas,\n type SchemaConfig,\n} from \"./validators/validators\";\nimport { parseBody, parseQuery, parseHeaders, parseCookies } from \"./parsers\";\n\n// 请求数据结构\nexport interface RequestData {\n body: unknown;\n query: unknown;\n params: Record<string, string>;\n headers: Record<string, string>;\n cookies: Record<string, string>;\n}\n\n// 验证后的请求数据类型\nexport interface ValidatedRequestData<T extends SchemaConfig> {\n body: T[\"body\"] extends TSchema ? Static<T[\"body\"]> : unknown;\n query: T[\"query\"] extends TSchema ? Static<T[\"query\"]> : unknown;\n params: T[\"params\"] extends TSchema\n ? Static<T[\"params\"]>\n : Record<string, string>;\n headers: T[\"headers\"] extends TSchema\n ? Static<T[\"headers\"]>\n : Record<string, string>;\n cookies: T[\"cookies\"] extends TSchema\n ? Static<T[\"cookies\"]>\n : Record<string, string>;\n}\n\n// 验证结果\nexport interface ValidationResult<T extends SchemaConfig> {\n success: boolean;\n data?: ValidatedRequestData<T>;\n errors?: Array<{ field: keyof SchemaConfig; message: string }>;\n}\n\n/**\n * 解析Request对象,提取所有相关数据\n * @param request Request对象\n * @param params 路径参数(可选)\n * @returns 解析后的请求数据\n */\nexport async function parseRequest(\n request: Request,\n params?: Record<string, string>,\n): Promise<RequestData> {\n const requestData: RequestData = {\n body: undefined,\n query: parseQuery(request),\n params: params || {},\n headers: parseHeaders(request),\n cookies: parseCookies(request),\n };\n\n // 对于非GET请求,尝试解析请求体\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n requestData.body = await parseBody(request);\n }\n\n return requestData;\n}\n\n/**\n * 验证请求数据\n * @param config Schema配置\n * @param requestData 请求数据\n * @returns 验证结果\n */\nexport function validateRequest<T extends SchemaConfig>(\n config: T,\n requestData: RequestData,\n): ValidationResult<T> {\n try {\n const validatedData = validateAllSchemas(config, requestData);\n\n return {\n success: true,\n data: validatedData as ValidatedRequestData<T>,\n };\n } catch (error) {\n return {\n success: false,\n errors: [\n {\n field: \"unknown\" as keyof SchemaConfig,\n message: error instanceof Error ? error.message : \"验证失败\",\n },\n ],\n };\n }\n}\n\n/**\n * 完整的请求解析和验证流程\n * @param request Request对象\n * @param config Schema配置\n * @param params 路径参数(可选)\n * @returns 验证结果\n */\nexport async function parseAndValidateRequest<T extends SchemaConfig>(\n request: Request,\n config: T,\n params?: Record<string, string>,\n): Promise<ValidationResult<T>> {\n try {\n // 1. 解析请求\n const requestData = await parseRequest(request, params);\n\n // 2. 验证数据\n return validateRequest(config, requestData);\n } catch (error) {\n return {\n success: false,\n errors: [\n {\n field: \"unknown\" as keyof SchemaConfig,\n message: error instanceof Error ? error.message : \"请求解析失败\",\n },\n ],\n };\n }\n}\n\n/**\n * 创建类型安全的请求验证器工厂\n * @param config Schema配置\n * @returns 验证器函数\n */\nexport function createRequestValidator<T extends SchemaConfig>(config: T) {\n return async (request: Request, params?: Record<string, string>) => {\n return parseAndValidateRequest(request, config, params);\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/utils/response.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
// src/utils/response.ts
|
|
2
|
-
function json(data, status = 200, headers = {}) {
|
|
3
|
-
const body = JSON.stringify(data);
|
|
4
|
-
if (Object.keys(headers).length === 0) {
|
|
5
|
-
return new Response(body, {
|
|
6
|
-
status,
|
|
7
|
-
headers: { "Content-Type": "application/json" }
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
const h = new Headers({
|
|
11
|
-
"Content-Type": "application/json",
|
|
12
|
-
...headers
|
|
13
|
-
});
|
|
14
|
-
return new Response(body, {
|
|
15
|
-
status,
|
|
16
|
-
headers: h
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
var JSON_HEADERS = { "Content-Type": "application/json" };
|
|
20
|
-
var TEXT_HEADERS = { "Content-Type": "text/plain" };
|
|
21
|
-
function mapResponse(response) {
|
|
22
|
-
if (response instanceof Response) return response;
|
|
23
|
-
switch (response?.constructor?.name) {
|
|
24
|
-
case "String":
|
|
25
|
-
return new Response(response, { headers: TEXT_HEADERS });
|
|
26
|
-
case "Object":
|
|
27
|
-
case "Array":
|
|
28
|
-
return new Response(JSON.stringify(response), { headers: JSON_HEADERS });
|
|
29
|
-
case "Number":
|
|
30
|
-
case "Boolean":
|
|
31
|
-
return new Response(String(response), { headers: TEXT_HEADERS });
|
|
32
|
-
case void 0:
|
|
33
|
-
return new Response(null, { status: 204 });
|
|
34
|
-
case "ReadableStream":
|
|
35
|
-
return new Response(response);
|
|
36
|
-
case "Blob":
|
|
37
|
-
return new Response(response);
|
|
38
|
-
case "ArrayBuffer":
|
|
39
|
-
return new Response(response);
|
|
40
|
-
case "Uint8Array":
|
|
41
|
-
return new Response(response);
|
|
42
|
-
default:
|
|
43
|
-
if (response instanceof Promise) {
|
|
44
|
-
return response.then(mapResponse);
|
|
45
|
-
}
|
|
46
|
-
return new Response(JSON.stringify(response), { headers: JSON_HEADERS });
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function redirect(location, status = 302) {
|
|
50
|
-
return new Response(null, {
|
|
51
|
-
status,
|
|
52
|
-
headers: {
|
|
53
|
-
Location: location
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
function text(content, status = 200, headers = {}) {
|
|
58
|
-
const h = new Headers({
|
|
59
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
60
|
-
...headers
|
|
61
|
-
});
|
|
62
|
-
return new Response(content, {
|
|
63
|
-
status,
|
|
64
|
-
headers: h
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
function html(content, status = 200, headers = {}) {
|
|
68
|
-
const h = new Headers({
|
|
69
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
70
|
-
...headers
|
|
71
|
-
});
|
|
72
|
-
return new Response(content, {
|
|
73
|
-
status,
|
|
74
|
-
headers: h
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
function empty(status = 204, headers = {}) {
|
|
78
|
-
return new Response(null, {
|
|
79
|
-
status,
|
|
80
|
-
headers
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
function stream(stream2, status = 200, headers = {}) {
|
|
84
|
-
const h = new Headers({
|
|
85
|
-
"Content-Type": "application/octet-stream",
|
|
86
|
-
...headers
|
|
87
|
-
});
|
|
88
|
-
return new Response(stream2, {
|
|
89
|
-
status,
|
|
90
|
-
headers: h
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
export {
|
|
94
|
-
empty,
|
|
95
|
-
html,
|
|
96
|
-
json,
|
|
97
|
-
mapResponse,
|
|
98
|
-
redirect,
|
|
99
|
-
stream,
|
|
100
|
-
text
|
|
101
|
-
};
|
|
102
|
-
//# sourceMappingURL=response.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/response.ts"],"sourcesContent":["// src/response.ts\n\n/** 生成 JSON 响应 */\nexport function json(\n data: unknown,\n status = 200,\n headers: HeadersInit = {},\n): Response {\n const body = JSON.stringify(data);\n\n // 优化:只在有自定义 headers 时才创建 Headers 对象\n if (Object.keys(headers).length === 0) {\n return new Response(body, {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n // 有自定义 headers 时才创建 Headers 对象\n const h = new Headers({\n \"Content-Type\": \"application/json\",\n ...headers,\n });\n\n return new Response(body, {\n status,\n headers: h,\n });\n}\n\n// JSON 响应的预创建 headers(避免每次创建)\nconst JSON_HEADERS = { \"Content-Type\": \"application/json\" };\nconst TEXT_HEADERS = { \"Content-Type\": \"text/plain\" };\n\n/**\n * 类型特化的响应映射\n * 根据返回值类型直接生成 Response,避免不必要的检查\n */\nexport function mapResponse(response: unknown): Response {\n // 快速路径:已经是 Response\n if (response instanceof Response) return response;\n\n // 使用 constructor.name 进行类型判断(比 instanceof 更快)\n switch (response?.constructor?.name) {\n case \"String\":\n return new Response(response as string, { headers: TEXT_HEADERS });\n\n case \"Object\":\n case \"Array\":\n return new Response(JSON.stringify(response), { headers: JSON_HEADERS });\n\n case \"Number\":\n case \"Boolean\":\n return new Response(String(response), { headers: TEXT_HEADERS });\n\n case undefined:\n // null 或 undefined\n return new Response(null, { status: 204 });\n\n case \"ReadableStream\":\n return new Response(response as ReadableStream);\n\n case \"Blob\":\n return new Response(response as Blob);\n\n case \"ArrayBuffer\":\n return new Response(response as ArrayBuffer);\n\n case \"Uint8Array\":\n return new Response(response as unknown as BodyInit);\n\n default:\n // Promise 处理\n if (response instanceof Promise) {\n return response.then(mapResponse) as unknown as Response;\n }\n // 其他情况使用 JSON 序列化\n return new Response(JSON.stringify(response), { headers: JSON_HEADERS });\n }\n}\n\n/** 生成重定向响应 */\nexport function redirect(location: string, status: 301 | 302 = 302): Response {\n return new Response(null, {\n status,\n headers: {\n Location: location,\n },\n });\n}\n\n/** 生成纯文本响应 */\nexport function text(\n content: string,\n status = 200,\n headers: HeadersInit = {},\n): Response {\n const h = new Headers({\n \"Content-Type\": \"text/plain; charset=utf-8\",\n ...headers,\n });\n\n return new Response(content, {\n status,\n headers: h,\n });\n}\n\n/** 生成HTML响应 */\nexport function html(\n content: string,\n status = 200,\n headers: HeadersInit = {},\n): Response {\n const h = new Headers({\n \"Content-Type\": \"text/html; charset=utf-8\",\n ...headers,\n });\n\n return new Response(content, {\n status,\n headers: h,\n });\n}\n\n/** 生成空响应(204 No Content) */\nexport function empty(status = 204, headers: HeadersInit = {}): Response {\n return new Response(null, {\n status,\n headers,\n });\n}\n\n/** 生成流式响应 */\nexport function stream(\n stream: ReadableStream,\n status = 200,\n headers: HeadersInit = {},\n): Response {\n const h = new Headers({\n \"Content-Type\": \"application/octet-stream\",\n ...headers,\n });\n\n return new Response(stream, {\n status,\n headers: h,\n });\n}\n"],"mappings":";AAGO,SAAS,KACd,MACA,SAAS,KACT,UAAuB,CAAC,GACd;AACV,QAAM,OAAO,KAAK,UAAU,IAAI;AAGhC,MAAI,OAAO,KAAK,OAAO,EAAE,WAAW,GAAG;AACrC,WAAO,IAAI,SAAS,MAAM;AAAA,MACxB;AAAA,MACA,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAChD,CAAC;AAAA,EACH;AAGA,QAAM,IAAI,IAAI,QAAQ;AAAA,IACpB,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACL,CAAC;AAED,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;AAGA,IAAM,eAAe,EAAE,gBAAgB,mBAAmB;AAC1D,IAAM,eAAe,EAAE,gBAAgB,aAAa;AAM7C,SAAS,YAAY,UAA6B;AAEvD,MAAI,oBAAoB,SAAU,QAAO;AAGzC,UAAQ,UAAU,aAAa,MAAM;AAAA,IACnC,KAAK;AACH,aAAO,IAAI,SAAS,UAAoB,EAAE,SAAS,aAAa,CAAC;AAAA,IAEnE,KAAK;AAAA,IACL,KAAK;AACH,aAAO,IAAI,SAAS,KAAK,UAAU,QAAQ,GAAG,EAAE,SAAS,aAAa,CAAC;AAAA,IAEzE,KAAK;AAAA,IACL,KAAK;AACH,aAAO,IAAI,SAAS,OAAO,QAAQ,GAAG,EAAE,SAAS,aAAa,CAAC;AAAA,IAEjE,KAAK;AAEH,aAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IAE3C,KAAK;AACH,aAAO,IAAI,SAAS,QAA0B;AAAA,IAEhD,KAAK;AACH,aAAO,IAAI,SAAS,QAAgB;AAAA,IAEtC,KAAK;AACH,aAAO,IAAI,SAAS,QAAuB;AAAA,IAE7C,KAAK;AACH,aAAO,IAAI,SAAS,QAA+B;AAAA,IAErD;AAEE,UAAI,oBAAoB,SAAS;AAC/B,eAAO,SAAS,KAAK,WAAW;AAAA,MAClC;AAEA,aAAO,IAAI,SAAS,KAAK,UAAU,QAAQ,GAAG,EAAE,SAAS,aAAa,CAAC;AAAA,EAC3E;AACF;AAGO,SAAS,SAAS,UAAkB,SAAoB,KAAe;AAC5E,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB;AAAA,IACA,SAAS;AAAA,MACP,UAAU;AAAA,IACZ;AAAA,EACF,CAAC;AACH;AAGO,SAAS,KACd,SACA,SAAS,KACT,UAAuB,CAAC,GACd;AACV,QAAM,IAAI,IAAI,QAAQ;AAAA,IACpB,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACL,CAAC;AAED,SAAO,IAAI,SAAS,SAAS;AAAA,IAC3B;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;AAGO,SAAS,KACd,SACA,SAAS,KACT,UAAuB,CAAC,GACd;AACV,QAAM,IAAI,IAAI,QAAQ;AAAA,IACpB,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACL,CAAC;AAED,SAAO,IAAI,SAAS,SAAS;AAAA,IAC3B;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;AAGO,SAAS,MAAM,SAAS,KAAK,UAAuB,CAAC,GAAa;AACvE,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAGO,SAAS,OACdA,SACA,SAAS,KACT,UAAuB,CAAC,GACd;AACV,QAAM,IAAI,IAAI,QAAQ;AAAA,IACpB,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACL,CAAC;AAED,SAAO,IAAI,SAASA,SAAQ;AAAA,IAC1B;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;","names":["stream"]}
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { FlattenedRoute, Method } from '../types/types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 路由注册表
|
|
5
|
-
*
|
|
6
|
-
* 提供路由元信息的收集和查询能力
|
|
7
|
-
* 可用于:API 文档生成、Webhook 事件注册、权限检查、审计日志等
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* // 创建注册表
|
|
12
|
-
* const registry = createRouteRegistry(server.getRoutes())
|
|
13
|
-
*
|
|
14
|
-
* // 查询路由
|
|
15
|
-
* const route = registry.get('POST', '/auth/signIn')
|
|
16
|
-
*
|
|
17
|
-
* // 筛选有 webhook 配置的路由
|
|
18
|
-
* const webhookRoutes = registry.filter('webhook')
|
|
19
|
-
*
|
|
20
|
-
* // 按分类获取
|
|
21
|
-
* const authRoutes = registry.getByCategory('auth')
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 路由元信息(不含 handler 和 middleware)
|
|
27
|
-
*/
|
|
28
|
-
interface RouteMeta {
|
|
29
|
-
method: Method;
|
|
30
|
-
path: string;
|
|
31
|
-
fullPath: string;
|
|
32
|
-
name?: string;
|
|
33
|
-
description?: string;
|
|
34
|
-
/** 扩展字段 */
|
|
35
|
-
[key: string]: unknown;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 路由注册表
|
|
39
|
-
*
|
|
40
|
-
* 泛型 T 用于定义扩展字段的类型
|
|
41
|
-
*/
|
|
42
|
-
declare class RouteRegistry<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
43
|
-
/** 所有路由元信息 */
|
|
44
|
-
private routes;
|
|
45
|
-
/** 路由映射表:METHOD:fullPath -> RouteMeta */
|
|
46
|
-
private routeMap;
|
|
47
|
-
/** 分类映射表:category -> RouteMeta[] */
|
|
48
|
-
private categoryMap;
|
|
49
|
-
constructor(routes: FlattenedRoute[]);
|
|
50
|
-
/**
|
|
51
|
-
* 构建注册表
|
|
52
|
-
*/
|
|
53
|
-
private buildRegistry;
|
|
54
|
-
/**
|
|
55
|
-
* 提取分类(第一段路径)
|
|
56
|
-
*/
|
|
57
|
-
private extractCategory;
|
|
58
|
-
/**
|
|
59
|
-
* 获取所有路由元信息
|
|
60
|
-
*/
|
|
61
|
-
getAll(): RouteMeta[];
|
|
62
|
-
/**
|
|
63
|
-
* 按 method + path 查询路由
|
|
64
|
-
*/
|
|
65
|
-
get(method: string, path: string): (RouteMeta & T) | undefined;
|
|
66
|
-
/**
|
|
67
|
-
* 检查路由是否存在
|
|
68
|
-
*/
|
|
69
|
-
has(method: string, path: string): boolean;
|
|
70
|
-
/**
|
|
71
|
-
* 按分类获取路由
|
|
72
|
-
*/
|
|
73
|
-
getByCategory(category: string): RouteMeta[];
|
|
74
|
-
/**
|
|
75
|
-
* 获取所有分类
|
|
76
|
-
*/
|
|
77
|
-
getCategories(): string[];
|
|
78
|
-
/**
|
|
79
|
-
* 筛选有特定字段的路由
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```typescript
|
|
83
|
-
* // 获取所有配置了 webhook 的路由
|
|
84
|
-
* const webhookRoutes = registry.filter('webhook')
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
filter<K extends string>(field: K): (RouteMeta & Record<K, unknown>)[];
|
|
88
|
-
/**
|
|
89
|
-
* 按条件筛选路由
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```typescript
|
|
93
|
-
* // 获取所有 POST 请求
|
|
94
|
-
* const postRoutes = registry.filterBy(r => r.method === 'POST')
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
filterBy(predicate: (route: RouteMeta) => boolean): RouteMeta[];
|
|
98
|
-
/**
|
|
99
|
-
* 获取路由数量
|
|
100
|
-
*/
|
|
101
|
-
get size(): number;
|
|
102
|
-
/**
|
|
103
|
-
* 遍历所有路由
|
|
104
|
-
*/
|
|
105
|
-
forEach(callback: (route: RouteMeta, index: number) => void): void;
|
|
106
|
-
/**
|
|
107
|
-
* 映射所有路由
|
|
108
|
-
*/
|
|
109
|
-
map<R>(callback: (route: RouteMeta, index: number) => R): R[];
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* 创建路由注册表
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* ```typescript
|
|
116
|
-
* // 定义扩展字段类型
|
|
117
|
-
* interface MyRouteMeta {
|
|
118
|
-
* webhook?: { eventKey: string }
|
|
119
|
-
* permission?: string
|
|
120
|
-
* }
|
|
121
|
-
*
|
|
122
|
-
* // 创建带类型的注册表
|
|
123
|
-
* const registry = createRouteRegistry<MyRouteMeta>(server.getRoutes())
|
|
124
|
-
*
|
|
125
|
-
* // 类型安全的查询
|
|
126
|
-
* const route = registry.get('POST', '/auth/signIn')
|
|
127
|
-
* if (route?.webhook) {
|
|
128
|
-
* console.log(route.webhook.eventKey)
|
|
129
|
-
* }
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
declare function createRouteRegistry<T extends Record<string, unknown> = Record<string, unknown>>(routes: FlattenedRoute[]): RouteRegistry<T>;
|
|
133
|
-
/**
|
|
134
|
-
* 设置全局 registry(框架内部使用)
|
|
135
|
-
* @internal
|
|
136
|
-
*/
|
|
137
|
-
declare function setGlobalRegistry(registry: RouteRegistry): void;
|
|
138
|
-
/**
|
|
139
|
-
* 获取全局路由注册表
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* ```typescript
|
|
143
|
-
* // 在任意文件中
|
|
144
|
-
* import { getRouteRegistry } from 'vafast'
|
|
145
|
-
*
|
|
146
|
-
* const registry = getRouteRegistry()
|
|
147
|
-
* const webhookRoutes = registry.filter('webhook')
|
|
148
|
-
* ```
|
|
149
|
-
*
|
|
150
|
-
* @throws 如果 Server 尚未创建
|
|
151
|
-
*/
|
|
152
|
-
declare function getRouteRegistry<T extends Record<string, unknown> = Record<string, unknown>>(): RouteRegistry<T>;
|
|
153
|
-
/**
|
|
154
|
-
* 按 method + path 获取单个路由
|
|
155
|
-
*
|
|
156
|
-
* 便捷函数,无需先获取 registry
|
|
157
|
-
*
|
|
158
|
-
* @example
|
|
159
|
-
* ```typescript
|
|
160
|
-
* // 在中间件或接口中
|
|
161
|
-
* import { getRoute } from 'vafast'
|
|
162
|
-
*
|
|
163
|
-
* const route = getRoute('POST', '/auth/signIn')
|
|
164
|
-
* if (route?.webhook) {
|
|
165
|
-
* console.log('This route has webhook:', route.webhook)
|
|
166
|
-
* }
|
|
167
|
-
* ```
|
|
168
|
-
*/
|
|
169
|
-
declare function getRoute<T extends Record<string, unknown> = Record<string, unknown>>(method: string, path: string): (RouteMeta & T) | undefined;
|
|
170
|
-
/**
|
|
171
|
-
* 获取所有路由
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* ```typescript
|
|
175
|
-
* import { getAllRoutes } from 'vafast'
|
|
176
|
-
*
|
|
177
|
-
* const routes = getAllRoutes()
|
|
178
|
-
* console.log(`Total ${routes.length} routes`)
|
|
179
|
-
* ```
|
|
180
|
-
*/
|
|
181
|
-
declare function getAllRoutes(): RouteMeta[];
|
|
182
|
-
/**
|
|
183
|
-
* 筛选有特定字段的路由
|
|
184
|
-
*
|
|
185
|
-
* @example
|
|
186
|
-
* ```typescript
|
|
187
|
-
* import { filterRoutes } from 'vafast'
|
|
188
|
-
*
|
|
189
|
-
* // 获取所有配置了 webhook 的路由
|
|
190
|
-
* const webhookRoutes = filterRoutes('webhook')
|
|
191
|
-
* ```
|
|
192
|
-
*/
|
|
193
|
-
declare function filterRoutes<K extends string>(field: K): (RouteMeta & Record<K, unknown>)[];
|
|
194
|
-
|
|
195
|
-
export { type RouteMeta, RouteRegistry, createRouteRegistry, filterRoutes, getAllRoutes, getRoute, getRouteRegistry, setGlobalRegistry };
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
// src/utils/route-registry.ts
|
|
2
|
-
var RouteRegistry = class {
|
|
3
|
-
/** 所有路由元信息 */
|
|
4
|
-
routes = [];
|
|
5
|
-
/** 路由映射表:METHOD:fullPath -> RouteMeta */
|
|
6
|
-
routeMap = /* @__PURE__ */ new Map();
|
|
7
|
-
/** 分类映射表:category -> RouteMeta[] */
|
|
8
|
-
categoryMap = /* @__PURE__ */ new Map();
|
|
9
|
-
constructor(routes) {
|
|
10
|
-
this.buildRegistry(routes);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* 构建注册表
|
|
14
|
-
*/
|
|
15
|
-
buildRegistry(routes) {
|
|
16
|
-
for (const route of routes) {
|
|
17
|
-
const meta = {
|
|
18
|
-
method: route.method,
|
|
19
|
-
path: route.path,
|
|
20
|
-
fullPath: route.fullPath,
|
|
21
|
-
name: route.name,
|
|
22
|
-
description: route.description
|
|
23
|
-
};
|
|
24
|
-
for (const key of Object.keys(route)) {
|
|
25
|
-
if (!["method", "path", "fullPath", "name", "description", "handler", "middleware", "middlewareChain"].includes(key)) {
|
|
26
|
-
meta[key] = route[key];
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
this.routes.push(meta);
|
|
30
|
-
this.routeMap.set(`${route.method}:${route.fullPath}`, meta);
|
|
31
|
-
const category = this.extractCategory(route.fullPath);
|
|
32
|
-
if (!this.categoryMap.has(category)) {
|
|
33
|
-
this.categoryMap.set(category, []);
|
|
34
|
-
}
|
|
35
|
-
this.categoryMap.get(category).push(meta);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* 提取分类(第一段路径)
|
|
40
|
-
*/
|
|
41
|
-
extractCategory(path) {
|
|
42
|
-
const segments = path.split("/").filter(Boolean);
|
|
43
|
-
return segments[0] || "root";
|
|
44
|
-
}
|
|
45
|
-
// ============================================
|
|
46
|
-
// 查询接口
|
|
47
|
-
// ============================================
|
|
48
|
-
/**
|
|
49
|
-
* 获取所有路由元信息
|
|
50
|
-
*/
|
|
51
|
-
getAll() {
|
|
52
|
-
return [...this.routes];
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* 按 method + path 查询路由
|
|
56
|
-
*/
|
|
57
|
-
get(method, path) {
|
|
58
|
-
return this.routeMap.get(`${method}:${path}`);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* 检查路由是否存在
|
|
62
|
-
*/
|
|
63
|
-
has(method, path) {
|
|
64
|
-
return this.routeMap.has(`${method}:${path}`);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* 按分类获取路由
|
|
68
|
-
*/
|
|
69
|
-
getByCategory(category) {
|
|
70
|
-
return this.categoryMap.get(category) || [];
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* 获取所有分类
|
|
74
|
-
*/
|
|
75
|
-
getCategories() {
|
|
76
|
-
return Array.from(this.categoryMap.keys()).sort();
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* 筛选有特定字段的路由
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```typescript
|
|
83
|
-
* // 获取所有配置了 webhook 的路由
|
|
84
|
-
* const webhookRoutes = registry.filter('webhook')
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
filter(field) {
|
|
88
|
-
return this.routes.filter((r) => field in r && r[field] !== void 0);
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* 按条件筛选路由
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```typescript
|
|
95
|
-
* // 获取所有 POST 请求
|
|
96
|
-
* const postRoutes = registry.filterBy(r => r.method === 'POST')
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
filterBy(predicate) {
|
|
100
|
-
return this.routes.filter(predicate);
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* 获取路由数量
|
|
104
|
-
*/
|
|
105
|
-
get size() {
|
|
106
|
-
return this.routes.length;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* 遍历所有路由
|
|
110
|
-
*/
|
|
111
|
-
forEach(callback) {
|
|
112
|
-
this.routes.forEach(callback);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* 映射所有路由
|
|
116
|
-
*/
|
|
117
|
-
map(callback) {
|
|
118
|
-
return this.routes.map(callback);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
function createRouteRegistry(routes) {
|
|
122
|
-
return new RouteRegistry(routes);
|
|
123
|
-
}
|
|
124
|
-
var globalRegistry = null;
|
|
125
|
-
function setGlobalRegistry(registry) {
|
|
126
|
-
globalRegistry = registry;
|
|
127
|
-
}
|
|
128
|
-
function getRouteRegistry() {
|
|
129
|
-
if (!globalRegistry) {
|
|
130
|
-
throw new Error("RouteRegistry not initialized. Make sure Server is created first.");
|
|
131
|
-
}
|
|
132
|
-
return globalRegistry;
|
|
133
|
-
}
|
|
134
|
-
function getRoute(method, path) {
|
|
135
|
-
return getRouteRegistry().get(method, path);
|
|
136
|
-
}
|
|
137
|
-
function getAllRoutes() {
|
|
138
|
-
return getRouteRegistry().getAll();
|
|
139
|
-
}
|
|
140
|
-
function filterRoutes(field) {
|
|
141
|
-
return getRouteRegistry().filter(field);
|
|
142
|
-
}
|
|
143
|
-
export {
|
|
144
|
-
RouteRegistry,
|
|
145
|
-
createRouteRegistry,
|
|
146
|
-
filterRoutes,
|
|
147
|
-
getAllRoutes,
|
|
148
|
-
getRoute,
|
|
149
|
-
getRouteRegistry,
|
|
150
|
-
setGlobalRegistry
|
|
151
|
-
};
|
|
152
|
-
//# sourceMappingURL=route-registry.js.map
|