vafast 0.1.17 → 0.2.1
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 +167 -185
- package/dist/auth/token.d.ts +39 -2
- package/dist/auth/token.js +124 -0
- package/dist/defineRoute.js +3 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +13 -323
- package/dist/middleware/auth.d.ts +6 -0
- package/dist/middleware/auth.js +106 -0
- package/dist/middleware/authMiddleware.js +13 -0
- package/dist/middleware/component-renderer.d.ts +6 -0
- package/dist/middleware/component-renderer.js +132 -0
- package/dist/middleware/component-router.d.ts +10 -0
- package/dist/middleware/component-router.js +42 -0
- package/dist/middleware/cors.js +30 -0
- package/dist/middleware/rateLimit.js +33 -0
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +56 -0
- package/dist/monitoring/index.d.ts +29 -0
- package/dist/monitoring/index.js +24 -0
- package/dist/monitoring/native-monitor.d.ts +38 -0
- package/dist/monitoring/native-monitor.js +176 -0
- package/dist/monitoring/types.d.ts +146 -0
- package/dist/monitoring/types.js +8 -0
- package/dist/router/index.d.ts +5 -0
- package/dist/router/index.js +7 -0
- package/dist/router/radix-tree.d.ts +51 -0
- package/dist/router/radix-tree.js +186 -0
- package/dist/router.d.ts +43 -6
- package/dist/router.js +86 -0
- package/dist/server/base-server.d.ts +34 -0
- package/dist/server/base-server.js +145 -0
- package/dist/server/component-server.d.ts +32 -0
- package/dist/server/component-server.js +146 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +11 -0
- package/dist/server/server-factory.d.ts +42 -0
- package/dist/server/server-factory.js +70 -0
- package/dist/server/server.d.ts +35 -0
- package/dist/server/server.js +97 -0
- package/dist/types/component-route.d.ts +25 -0
- package/dist/types/component-route.js +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +4 -0
- package/dist/types/route.d.ts +39 -0
- package/dist/types/route.js +11 -0
- package/dist/types/schema.d.ts +75 -0
- package/dist/types/schema.js +10 -0
- package/dist/types/types.d.ts +22 -0
- package/dist/types/types.js +1 -0
- package/dist/utils/base64url.js +11 -0
- package/dist/utils/create-handler.d.ts +74 -0
- package/dist/utils/create-handler.js +234 -0
- package/dist/utils/dependency-manager.d.ts +23 -0
- package/dist/utils/dependency-manager.js +73 -0
- package/dist/utils/go-await.d.ts +26 -0
- package/dist/utils/go-await.js +30 -0
- package/dist/{cookie.d.ts → utils/handle.d.ts} +3 -0
- package/dist/utils/handle.js +29 -0
- package/dist/utils/html-renderer.d.ts +18 -0
- package/dist/utils/html-renderer.js +64 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/parsers.d.ts +36 -0
- package/dist/utils/parsers.js +126 -0
- package/dist/utils/path-matcher.d.ts +23 -0
- package/dist/utils/path-matcher.js +83 -0
- package/dist/utils/request-validator.d.ts +63 -0
- package/dist/utils/request-validator.js +94 -0
- package/dist/utils/response.d.ts +17 -0
- package/dist/utils/response.js +110 -0
- package/dist/utils/validators/schema-validator.d.ts +66 -0
- package/dist/utils/validators/schema-validator.js +222 -0
- package/dist/utils/validators/schema-validators-ultra.d.ts +51 -0
- package/dist/utils/validators/schema-validators-ultra.js +289 -0
- package/dist/utils/validators/validators.d.ts +30 -0
- package/dist/utils/validators/validators.js +54 -0
- package/package.json +50 -14
- package/dist/server.d.ts +0 -9
- package/dist/types.d.ts +0 -9
- package/dist/util.d.ts +0 -7
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 服务器模块导出
|
|
3
|
+
*/
|
|
4
|
+
// 主服务器类
|
|
5
|
+
export { Server } from "./server";
|
|
6
|
+
// 组件服务器 (SSR)
|
|
7
|
+
export { ComponentServer } from "./component-server";
|
|
8
|
+
// 服务器工厂
|
|
9
|
+
export { ServerFactory } from "./server-factory";
|
|
10
|
+
// 基类 (仅用于扩展)
|
|
11
|
+
export { BaseServer } from "./base-server";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Route, NestedRoute } from "../types";
|
|
2
|
+
import type { ComponentRoute, NestedComponentRoute } from "../types/component-route";
|
|
3
|
+
import { Server } from "../server";
|
|
4
|
+
import { ComponentServer } from "./component-server";
|
|
5
|
+
/**
|
|
6
|
+
* 服务器工厂类
|
|
7
|
+
* 用于创建和管理不同类型的服务器
|
|
8
|
+
*/
|
|
9
|
+
export declare class ServerFactory {
|
|
10
|
+
private servers;
|
|
11
|
+
/**
|
|
12
|
+
* 创建标准REST API服务器
|
|
13
|
+
*/
|
|
14
|
+
createRestServer(routes: (Route | NestedRoute)[]): Server;
|
|
15
|
+
/**
|
|
16
|
+
* 创建组件服务器
|
|
17
|
+
*/
|
|
18
|
+
createComponentServer(routes: (ComponentRoute | NestedComponentRoute)[]): ComponentServer;
|
|
19
|
+
/**
|
|
20
|
+
* 获取指定类型的服务器
|
|
21
|
+
*/
|
|
22
|
+
getServer(type: "rest" | "component"): Server | ComponentServer | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* 获取所有服务器
|
|
25
|
+
*/
|
|
26
|
+
getAllServers(): Map<string, Server | ComponentServer>;
|
|
27
|
+
/**
|
|
28
|
+
* 移除指定类型的服务器
|
|
29
|
+
*/
|
|
30
|
+
removeServer(type: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* 清除所有服务器
|
|
33
|
+
*/
|
|
34
|
+
clearServers(): void;
|
|
35
|
+
/**
|
|
36
|
+
* 获取服务器状态信息
|
|
37
|
+
*/
|
|
38
|
+
getServerStatus(): Record<string, {
|
|
39
|
+
type: string;
|
|
40
|
+
routes: number;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Server } from "../server";
|
|
2
|
+
import { ComponentServer } from "./component-server";
|
|
3
|
+
/**
|
|
4
|
+
* 服务器工厂类
|
|
5
|
+
* 用于创建和管理不同类型的服务器
|
|
6
|
+
*/
|
|
7
|
+
export class ServerFactory {
|
|
8
|
+
servers = new Map();
|
|
9
|
+
/**
|
|
10
|
+
* 创建标准REST API服务器
|
|
11
|
+
*/
|
|
12
|
+
createRestServer(routes) {
|
|
13
|
+
const server = new Server(routes);
|
|
14
|
+
this.servers.set("rest", server);
|
|
15
|
+
return server;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 创建组件服务器
|
|
19
|
+
*/
|
|
20
|
+
createComponentServer(routes) {
|
|
21
|
+
const server = new ComponentServer(routes);
|
|
22
|
+
this.servers.set("component", server);
|
|
23
|
+
return server;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 获取指定类型的服务器
|
|
27
|
+
*/
|
|
28
|
+
getServer(type) {
|
|
29
|
+
return this.servers.get(type);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 获取所有服务器
|
|
33
|
+
*/
|
|
34
|
+
getAllServers() {
|
|
35
|
+
return this.servers;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 移除指定类型的服务器
|
|
39
|
+
*/
|
|
40
|
+
removeServer(type) {
|
|
41
|
+
return this.servers.delete(type);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 清除所有服务器
|
|
45
|
+
*/
|
|
46
|
+
clearServers() {
|
|
47
|
+
this.servers.clear();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 获取服务器状态信息
|
|
51
|
+
*/
|
|
52
|
+
getServerStatus() {
|
|
53
|
+
const status = {};
|
|
54
|
+
for (const [name, server] of this.servers) {
|
|
55
|
+
if (server instanceof Server) {
|
|
56
|
+
status[name] = {
|
|
57
|
+
type: "REST API",
|
|
58
|
+
routes: server.routes?.length || 0,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
else if (server instanceof ComponentServer) {
|
|
62
|
+
status[name] = {
|
|
63
|
+
type: "Component",
|
|
64
|
+
routes: server.routes?.length || 0,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return status;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vafast 核心服务器
|
|
3
|
+
*
|
|
4
|
+
* 基于 Radix Tree 的高性能路由匹配
|
|
5
|
+
* 时间复杂度: O(k),k 为路径段数
|
|
6
|
+
*/
|
|
7
|
+
import type { Route, NestedRoute, Method } from "../types";
|
|
8
|
+
import { BaseServer } from "./base-server";
|
|
9
|
+
/**
|
|
10
|
+
* Vafast 服务器
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const server = new Server([
|
|
15
|
+
* { method: "GET", path: "/", handler: () => new Response("Hello") },
|
|
16
|
+
* ]);
|
|
17
|
+
* export default { fetch: server.fetch };
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class Server extends BaseServer {
|
|
21
|
+
private router;
|
|
22
|
+
private routes;
|
|
23
|
+
constructor(routes?: (Route | NestedRoute)[]);
|
|
24
|
+
private registerRoutes;
|
|
25
|
+
/** 快速提取 pathname */
|
|
26
|
+
private extractPathname;
|
|
27
|
+
/** 处理请求 */
|
|
28
|
+
fetch: (req: Request) => Promise<Response>;
|
|
29
|
+
addRoute(route: Route): void;
|
|
30
|
+
addRoutes(routes: (Route | NestedRoute)[]): void;
|
|
31
|
+
getRoutes(): Array<{
|
|
32
|
+
method: Method;
|
|
33
|
+
path: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vafast 核心服务器
|
|
3
|
+
*
|
|
4
|
+
* 基于 Radix Tree 的高性能路由匹配
|
|
5
|
+
* 时间复杂度: O(k),k 为路径段数
|
|
6
|
+
*/
|
|
7
|
+
import { flattenNestedRoutes } from "../router";
|
|
8
|
+
import { composeMiddleware } from "../middleware";
|
|
9
|
+
import { json } from "../utils/response";
|
|
10
|
+
import { BaseServer } from "./base-server";
|
|
11
|
+
import { RadixRouter } from "../router/radix-tree";
|
|
12
|
+
/**
|
|
13
|
+
* Vafast 服务器
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const server = new Server([
|
|
18
|
+
* { method: "GET", path: "/", handler: () => new Response("Hello") },
|
|
19
|
+
* ]);
|
|
20
|
+
* export default { fetch: server.fetch };
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class Server extends BaseServer {
|
|
24
|
+
router;
|
|
25
|
+
routes;
|
|
26
|
+
constructor(routes = []) {
|
|
27
|
+
super();
|
|
28
|
+
this.router = new RadixRouter();
|
|
29
|
+
this.routes = [];
|
|
30
|
+
if (routes.length > 0) {
|
|
31
|
+
this.registerRoutes(routes);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
registerRoutes(routes) {
|
|
35
|
+
const flattened = flattenNestedRoutes(routes);
|
|
36
|
+
this.routes.push(...flattened);
|
|
37
|
+
for (const route of flattened) {
|
|
38
|
+
this.router.register(route.method, route.fullPath, route.handler, route.middlewareChain || []);
|
|
39
|
+
}
|
|
40
|
+
this.detectRouteConflicts(flattened);
|
|
41
|
+
this.logFlattenedRoutes(flattened);
|
|
42
|
+
}
|
|
43
|
+
/** 快速提取 pathname */
|
|
44
|
+
extractPathname(url) {
|
|
45
|
+
let start = url.indexOf("://");
|
|
46
|
+
start = start === -1 ? 0 : start + 3;
|
|
47
|
+
const pathStart = url.indexOf("/", start);
|
|
48
|
+
if (pathStart === -1)
|
|
49
|
+
return "/";
|
|
50
|
+
let end = url.indexOf("?", pathStart);
|
|
51
|
+
if (end === -1)
|
|
52
|
+
end = url.indexOf("#", pathStart);
|
|
53
|
+
if (end === -1)
|
|
54
|
+
end = url.length;
|
|
55
|
+
return url.substring(pathStart, end) || "/";
|
|
56
|
+
}
|
|
57
|
+
/** 处理请求 */
|
|
58
|
+
fetch = async (req) => {
|
|
59
|
+
const pathname = this.extractPathname(req.url);
|
|
60
|
+
const method = req.method;
|
|
61
|
+
const match = this.router.match(method, pathname);
|
|
62
|
+
if (match) {
|
|
63
|
+
req.params = match.params;
|
|
64
|
+
// 组合全局中间件 + 路由中间件(mapResponse 在 composeMiddleware 内部处理)
|
|
65
|
+
const allMiddleware = [...this.globalMiddleware, ...match.middleware];
|
|
66
|
+
const handler = composeMiddleware(allMiddleware, match.handler);
|
|
67
|
+
return handler(req);
|
|
68
|
+
}
|
|
69
|
+
// 405 Method Not Allowed
|
|
70
|
+
const allowedMethods = this.router.getAllowedMethods(pathname);
|
|
71
|
+
if (allowedMethods.length > 0) {
|
|
72
|
+
return json({
|
|
73
|
+
success: false,
|
|
74
|
+
error: "Method Not Allowed",
|
|
75
|
+
message: `Method ${method} not allowed for this endpoint`,
|
|
76
|
+
allowedMethods,
|
|
77
|
+
}, 405, { Allow: allowedMethods.join(", ") });
|
|
78
|
+
}
|
|
79
|
+
// 404 Not Found
|
|
80
|
+
return json({ success: false, error: "Not Found" }, 404);
|
|
81
|
+
};
|
|
82
|
+
addRoute(route) {
|
|
83
|
+
const flattenedRoute = {
|
|
84
|
+
...route,
|
|
85
|
+
fullPath: route.path,
|
|
86
|
+
middlewareChain: route.middleware || [],
|
|
87
|
+
};
|
|
88
|
+
this.routes.push(flattenedRoute);
|
|
89
|
+
this.router.register(route.method, route.path, route.handler, route.middleware || []);
|
|
90
|
+
}
|
|
91
|
+
addRoutes(routes) {
|
|
92
|
+
this.registerRoutes(routes);
|
|
93
|
+
}
|
|
94
|
+
getRoutes() {
|
|
95
|
+
return this.router.getRoutes();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Middleware } from "./route";
|
|
2
|
+
/**
|
|
3
|
+
* 组件路由配置
|
|
4
|
+
* 支持声明式的组件关联
|
|
5
|
+
*/
|
|
6
|
+
export interface ComponentRoute {
|
|
7
|
+
path: string;
|
|
8
|
+
component: () => Promise<any>;
|
|
9
|
+
middleware?: Middleware[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 嵌套组件路由配置
|
|
13
|
+
*/
|
|
14
|
+
export interface NestedComponentRoute {
|
|
15
|
+
path: string;
|
|
16
|
+
middleware?: Middleware[];
|
|
17
|
+
children?: (ComponentRoute | NestedComponentRoute)[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 扁平化后的组件路由
|
|
21
|
+
*/
|
|
22
|
+
export interface FlattenedComponentRoute extends ComponentRoute {
|
|
23
|
+
fullPath: string;
|
|
24
|
+
middlewareChain: Middleware[];
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { Method, Handler, Route, NestedRoute, Middleware, FlattenedRoute, ResponseBody, } from "./types";
|
|
2
|
+
export type { BaseRouteConfig, ExtendedRouteConfig, NestedRouteConfig, TypedRoute, CompatibleRoute, } from "./route";
|
|
3
|
+
export { createTypedRoute, isTypedRoute } from "./route";
|
|
4
|
+
export * from "./component-route";
|
|
5
|
+
export * from "./schema";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Route, ResponseBody } from "./types";
|
|
2
|
+
export interface Middleware {
|
|
3
|
+
(req: Request, next: () => Promise<Response>): Promise<Response>;
|
|
4
|
+
}
|
|
5
|
+
export interface BaseRouteConfig {
|
|
6
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
7
|
+
path: string;
|
|
8
|
+
handler: (req: Request) => ResponseBody | Promise<ResponseBody>;
|
|
9
|
+
}
|
|
10
|
+
export interface ExtendedRouteConfig extends BaseRouteConfig {
|
|
11
|
+
middleware?: Middleware[];
|
|
12
|
+
body?: any;
|
|
13
|
+
query?: any;
|
|
14
|
+
params?: any;
|
|
15
|
+
headers?: any;
|
|
16
|
+
cookies?: any;
|
|
17
|
+
docs?: {
|
|
18
|
+
description?: string;
|
|
19
|
+
tags?: string[];
|
|
20
|
+
security?: any[];
|
|
21
|
+
responses?: Record<string, any>;
|
|
22
|
+
};
|
|
23
|
+
timeout?: number;
|
|
24
|
+
maxBodySize?: string;
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
}
|
|
27
|
+
export interface NestedRouteConfig {
|
|
28
|
+
path: string;
|
|
29
|
+
middleware?: Middleware[];
|
|
30
|
+
children?: (NestedRouteConfig | ExtendedRouteConfig)[];
|
|
31
|
+
}
|
|
32
|
+
export type TypedRoute = ExtendedRouteConfig;
|
|
33
|
+
export type CompatibleRoute = Route | TypedRoute;
|
|
34
|
+
export interface FlattenedRoute extends ExtendedRouteConfig {
|
|
35
|
+
fullPath: string;
|
|
36
|
+
middlewareChain: Middleware[];
|
|
37
|
+
}
|
|
38
|
+
export declare function createTypedRoute(config: ExtendedRouteConfig): ExtendedRouteConfig;
|
|
39
|
+
export declare function isTypedRoute(route: any): route is TypedRoute;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// 导出一些实际的函数,确保 JavaScript 代码生成
|
|
2
|
+
export function createTypedRoute(config) {
|
|
3
|
+
return config;
|
|
4
|
+
}
|
|
5
|
+
export function isTypedRoute(route) {
|
|
6
|
+
return (route &&
|
|
7
|
+
typeof route === "object" &&
|
|
8
|
+
"method" in route &&
|
|
9
|
+
"path" in route &&
|
|
10
|
+
"handler" in route);
|
|
11
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema 类型定义
|
|
3
|
+
*
|
|
4
|
+
* 使用 TSchema 约束替代 any,提供完整的类型安全
|
|
5
|
+
*
|
|
6
|
+
* @author Framework Team
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
import type { TSchema, Static } from "@sinclair/typebox";
|
|
11
|
+
/**
|
|
12
|
+
* 路由 Schema 配置
|
|
13
|
+
* 所有 schema 字段使用 TSchema 约束
|
|
14
|
+
*/
|
|
15
|
+
export interface RouteSchema {
|
|
16
|
+
body?: TSchema;
|
|
17
|
+
query?: TSchema;
|
|
18
|
+
params?: TSchema;
|
|
19
|
+
headers?: TSchema;
|
|
20
|
+
cookies?: TSchema;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 从 Schema 配置推导出具体类型
|
|
24
|
+
*/
|
|
25
|
+
export type InferSchema<T extends RouteSchema> = {
|
|
26
|
+
body: T["body"] extends TSchema ? Static<T["body"]> : unknown;
|
|
27
|
+
query: T["query"] extends TSchema ? Static<T["query"]> : Record<string, string>;
|
|
28
|
+
params: T["params"] extends TSchema ? Static<T["params"]> : Record<string, string>;
|
|
29
|
+
headers: T["headers"] extends TSchema ? Static<T["headers"]> : Record<string, string>;
|
|
30
|
+
cookies: T["cookies"] extends TSchema ? Static<T["cookies"]> : Record<string, string>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Handler 上下文类型
|
|
34
|
+
*/
|
|
35
|
+
export interface HandlerContext<T extends RouteSchema = RouteSchema> {
|
|
36
|
+
/** 原始请求对象 */
|
|
37
|
+
req: Request;
|
|
38
|
+
/** 请求体 (经过 schema 验证) */
|
|
39
|
+
body: InferSchema<T>["body"];
|
|
40
|
+
/** 查询参数 (经过 schema 验证) */
|
|
41
|
+
query: InferSchema<T>["query"];
|
|
42
|
+
/** 路径参数 (经过 schema 验证) */
|
|
43
|
+
params: InferSchema<T>["params"];
|
|
44
|
+
/** 请求头 (经过 schema 验证) */
|
|
45
|
+
headers: InferSchema<T>["headers"];
|
|
46
|
+
/** Cookie (经过 schema 验证) */
|
|
47
|
+
cookies: InferSchema<T>["cookies"];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 带额外上下文的 Handler 上下文类型
|
|
51
|
+
* 用于中间件注入额外数据
|
|
52
|
+
*/
|
|
53
|
+
export type HandlerContextWithExtra<T extends RouteSchema = RouteSchema, TExtra extends Record<string, unknown> = Record<string, never>> = HandlerContext<T> & TExtra;
|
|
54
|
+
/**
|
|
55
|
+
* Handler 函数类型
|
|
56
|
+
*/
|
|
57
|
+
export type TypedHandler<T extends RouteSchema = RouteSchema, TExtra extends Record<string, unknown> = Record<string, never>, TReturn = unknown> = (ctx: HandlerContextWithExtra<T, TExtra>) => TReturn | Promise<TReturn>;
|
|
58
|
+
/**
|
|
59
|
+
* 扩展的路由配置 (包含 schema)
|
|
60
|
+
*/
|
|
61
|
+
export interface TypedRouteConfig<T extends RouteSchema = RouteSchema> {
|
|
62
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
63
|
+
path: string;
|
|
64
|
+
schema?: T;
|
|
65
|
+
handler: (req: Request) => Response | Promise<Response>;
|
|
66
|
+
middleware?: Array<(req: Request, next: () => Promise<Response>) => Promise<Response>>;
|
|
67
|
+
docs?: {
|
|
68
|
+
description?: string;
|
|
69
|
+
tags?: string[];
|
|
70
|
+
security?: unknown[];
|
|
71
|
+
responses?: Record<string, unknown>;
|
|
72
|
+
};
|
|
73
|
+
timeout?: number;
|
|
74
|
+
maxBodySize?: string;
|
|
75
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
2
|
+
/** 支持的响应类型 - 由 mapResponse 自动转换 */
|
|
3
|
+
export type ResponseBody = Response | string | number | boolean | object | null | undefined | ReadableStream | Blob | ArrayBuffer;
|
|
4
|
+
/** Handler 返回值(支持同步/异步,任意类型) */
|
|
5
|
+
export type Handler = (req: Request, params?: Record<string, string>, user?: Record<string, any>) => ResponseBody | Promise<ResponseBody>;
|
|
6
|
+
/** 中间件(返回值必须是 Response 或 Promise<Response>) */
|
|
7
|
+
export type Middleware = (req: Request, next: () => Promise<Response>) => Response | Promise<Response>;
|
|
8
|
+
export interface Route {
|
|
9
|
+
method: Method;
|
|
10
|
+
path: string;
|
|
11
|
+
handler: Handler;
|
|
12
|
+
middleware?: Middleware[];
|
|
13
|
+
}
|
|
14
|
+
export interface NestedRoute {
|
|
15
|
+
path: string;
|
|
16
|
+
middleware?: Middleware[];
|
|
17
|
+
children?: (NestedRoute | Route)[];
|
|
18
|
+
}
|
|
19
|
+
export interface FlattenedRoute extends Route {
|
|
20
|
+
fullPath: string;
|
|
21
|
+
middlewareChain: Middleware[];
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function base64urlEncode(str) {
|
|
2
|
+
return btoa(str)
|
|
3
|
+
.replace(/=/g, "") // ✅ 删除填充
|
|
4
|
+
.replace(/\+/g, "-")
|
|
5
|
+
.replace(/\//g, "_");
|
|
6
|
+
}
|
|
7
|
+
export function base64urlDecode(str) {
|
|
8
|
+
const pad = str.length % 4 === 0 ? "" : "=".repeat(4 - (str.length % 4));
|
|
9
|
+
const base64 = str.replace(/-/g, "+").replace(/_/g, "/") + pad;
|
|
10
|
+
return atob(base64);
|
|
11
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 类型安全的路由处理器工厂
|
|
3
|
+
*
|
|
4
|
+
* 非柯里化设计,API 更简洁
|
|
5
|
+
*
|
|
6
|
+
* @author Framework Team
|
|
7
|
+
* @version 3.0.0
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
import type { RouteSchema, HandlerContext, HandlerContextWithExtra } from "../types/schema";
|
|
11
|
+
/** 空 schema 的上下文类型 */
|
|
12
|
+
type EmptySchemaContext = {
|
|
13
|
+
req: Request;
|
|
14
|
+
body: unknown;
|
|
15
|
+
query: Record<string, string>;
|
|
16
|
+
params: Record<string, string>;
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
cookies: Record<string, string>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* 创建类型安全的路由处理器
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // 无 schema - 直接传入 handler
|
|
26
|
+
* createHandler(({ params }) => `User: ${params.id}`)
|
|
27
|
+
*
|
|
28
|
+
* // 有 schema - 传入 schema 和 handler
|
|
29
|
+
* createHandler(
|
|
30
|
+
* { body: Type.Object({ name: Type.String() }) },
|
|
31
|
+
* ({ body }) => ({ hello: body.name })
|
|
32
|
+
* )
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function createHandler<R>(handler: (ctx: EmptySchemaContext) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
36
|
+
export declare function createHandler<const T extends RouteSchema, R>(schema: T, handler: (ctx: HandlerContext<T>) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
37
|
+
/**
|
|
38
|
+
* 创建带额外上下文的路由处理器
|
|
39
|
+
*
|
|
40
|
+
* 用于中间件注入额外数据的场景
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // 定义中间件注入的类型
|
|
45
|
+
* type AuthContext = { user: { id: string; role: string } };
|
|
46
|
+
*
|
|
47
|
+
* // 无 schema
|
|
48
|
+
* createHandlerWithExtra<AuthContext>(({ user }) => {
|
|
49
|
+
* return { userId: user.id };
|
|
50
|
+
* })
|
|
51
|
+
*
|
|
52
|
+
* // 有 schema
|
|
53
|
+
* createHandlerWithExtra<AuthContext>(
|
|
54
|
+
* { body: Type.Object({ action: Type.String() }) },
|
|
55
|
+
* ({ body, user }) => ({ success: true, userId: user.id })
|
|
56
|
+
* )
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function createHandlerWithExtra<TExtra extends Record<string, unknown> = Record<string, never>, R = unknown>(handler: (ctx: EmptySchemaContext & TExtra) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
60
|
+
export declare function createHandlerWithExtra<TExtra extends Record<string, unknown> = Record<string, never>, const T extends RouteSchema = RouteSchema, R = unknown>(schema: T, handler: (ctx: HandlerContextWithExtra<T, TExtra>) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
61
|
+
/**
|
|
62
|
+
* 简单的路由处理器 (无 schema 验证,只有 req)
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* simpleHandler(({ req }) => {
|
|
67
|
+
* return { message: "Hello World" };
|
|
68
|
+
* })
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function simpleHandler<R>(handler: (ctx: {
|
|
72
|
+
req: Request;
|
|
73
|
+
}) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
74
|
+
export {};
|