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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/router.ts","../../src/utils/response.ts","../../src/middleware.ts","../../src/server/base-server.ts","../../src/router/radix-tree.ts","../../src/server/server.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","// 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","// src/middleware.ts\n\nimport { json, mapResponse } from \"./utils/response\";\n\nimport type { Handler, Middleware } from \"./types\";\n/** 中间件类型:使用 next() 传递给下一个处理 */\n\n/** Vafast 自定义错误类型 */\nexport class VafastError extends Error {\n status: number;\n type: string;\n expose: boolean;\n\n constructor(\n message: string,\n options: {\n status?: number;\n type?: string;\n expose?: boolean;\n cause?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"VafastError\";\n this.status = options.status ?? 500;\n this.type = options.type ?? \"internal_error\";\n this.expose = options.expose ?? false;\n if (options.cause) (this as any).cause = options.cause;\n }\n}\n\n/**\n * 组合类型: 自动注入错误处理器进行中间件组合\n */\nexport function composeMiddleware(\n middleware: Middleware[],\n finalHandler: Handler,\n): (req: Request) => Promise<Response> {\n const all = [errorHandler, ...middleware];\n\n return function composedHandler(req: Request): Promise<Response> {\n let i = -1;\n\n const dispatch = (index: number): Promise<Response> => {\n if (index <= i)\n return Promise.reject(new Error(\"next() called multiple times\"));\n i = index;\n\n // 中间件阶段\n if (index < all.length) {\n const mw = all[index];\n return Promise.resolve(mw(req, () => dispatch(index + 1)));\n }\n\n // 最终 handler - 使用 mapResponse 转换返回值\n return Promise.resolve(finalHandler(req)).then(mapResponse);\n };\n\n return dispatch(0);\n };\n}\n\n/** 默认包含的全局错误处理器 */\nconst errorHandler: Middleware = async (req, next) => {\n try {\n return await next();\n } catch (err) {\n console.error(\"未处理的错误:\", err);\n\n if (err instanceof VafastError) {\n return json(\n {\n error: err.type,\n message: err.expose ? err.message : \"发生了一个错误\",\n },\n err.status,\n );\n }\n\n return json({ error: \"internal_error\", message: \"出现了一些问题\" }, 500);\n }\n};\n","import type { Middleware } from \"../types\";\n\n/**\n * 服务器基类\n * 包含所有服务器类型的公共逻辑\n */\nexport abstract class BaseServer {\n protected globalMiddleware: Middleware[] = [];\n\n use(mw: Middleware) {\n this.globalMiddleware.push(mw);\n }\n\n /**\n * 打印扁平化后的路由信息,用于调试\n */\n protected logFlattenedRoutes(routes: any[], type: string = \"路由\"): void {\n console.log(`🚀 扁平化后的${type}:`);\n for (const route of routes) {\n const method = route.method || \"GET\";\n const path = route.fullPath || route.path;\n console.log(` ${method} ${path}`);\n if (route.middlewareChain && route.middlewareChain.length > 0) {\n console.log(` 中间件链: ${route.middlewareChain.length} 个`);\n }\n }\n console.log(\"\");\n }\n\n /**\n * 检测路由冲突\n * 检查是否有路径相同但方法不同的路由,以及潜在的路径冲突\n */\n protected detectRouteConflicts(routes: any[]): void {\n const pathGroups = new Map<string, any[]>();\n\n // 按路径分组\n for (const route of routes) {\n const path = route.fullPath || route.path;\n const method = route.method || \"GET\";\n if (!pathGroups.has(path)) {\n pathGroups.set(path, []);\n }\n pathGroups.get(path)!.push({ ...route, method });\n }\n\n // 检查冲突\n for (const [path, routeList] of pathGroups) {\n if (routeList.length > 1) {\n const methods = routeList.map((r) => r.method);\n const uniqueMethods = [...new Set(methods)];\n\n if (uniqueMethods.length === 1) {\n // 相同路径、相同方法 - 这是冲突!\n console.warn(\n `⚠️ 路由冲突: ${uniqueMethods[0]} ${path} 定义了 ${routeList.length} 次`,\n );\n routeList.forEach((route, index) => {\n console.warn(` ${index + 1}. ${route.method} ${path}`);\n });\n } else {\n // 相同路径、不同方法 - 这是正常的\n console.log(`ℹ️ 路径 ${path} 支持方法: ${uniqueMethods.join(\", \")}`);\n }\n }\n }\n\n // 检查潜在的路径冲突(动态路由可能冲突)\n this.detectDynamicRouteConflicts(routes);\n }\n\n /**\n * 检测动态路由的潜在冲突\n */\n private detectDynamicRouteConflicts(routes: any[]): void {\n const dynamicRoutes = routes.filter((r) => {\n const path = r.fullPath || r.path;\n return path.includes(\":\") || path.includes(\"*\");\n });\n\n for (let i = 0; i < dynamicRoutes.length; i++) {\n for (let j = i + 1; j < dynamicRoutes.length; j++) {\n const route1 = dynamicRoutes[i];\n const route2 = dynamicRoutes[j];\n const method1 = route1.method || \"GET\";\n const method2 = route2.method || \"GET\";\n\n if (method1 === method2) {\n const path1 = route1.fullPath || route1.path;\n const path2 = route2.fullPath || route2.path;\n // 检查路径是否可能冲突\n if (this.pathsMayConflict(path1, path2)) {\n console.warn(\n `⚠️ 潜在路由冲突: ${method1} ${path1} 可能与 ${path2} 冲突`,\n );\n }\n }\n }\n }\n }\n\n /**\n * 判断两个路径是否可能冲突\n */\n private pathsMayConflict(path1: string, path2: string): boolean {\n const parts1 = path1.split(\"/\").filter(Boolean);\n const parts2 = path2.split(\"/\").filter(Boolean);\n\n if (parts1.length !== parts2.length) return false;\n\n for (let i = 0; i < parts1.length; i++) {\n const p1 = parts1[i];\n const p2 = parts2[i];\n\n // 如果两个部分都是静态的且不同,则不会冲突\n if (\n !p1.startsWith(\":\") &&\n !p1.startsWith(\"*\") &&\n !p2.startsWith(\":\") &&\n !p2.startsWith(\"*\") &&\n p1 !== p2\n ) {\n return false;\n }\n\n // 如果一个是通配符,另一个是动态参数,可能冲突\n if (\n (p1 === \"*\" && p2.startsWith(\":\")) ||\n (p2 === \"*\" && p1.startsWith(\":\"))\n ) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * 路径匹配\n */\n protected matchPath(pattern: string, path: string): boolean {\n const patternParts = pattern.split(\"/\").filter(Boolean);\n const pathParts = path.split(\"/\").filter(Boolean);\n\n if (patternParts.length !== pathParts.length) {\n return false;\n }\n\n for (let i = 0; i < patternParts.length; i++) {\n if (\n patternParts[i] !== pathParts[i] &&\n !patternParts[i].startsWith(\":\")\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * 提取路径参数\n */\n protected extractParams(\n pattern: string,\n path: string,\n ): Record<string, string> {\n const params: Record<string, string> = {};\n const patternParts = pattern.split(\"/\").filter(Boolean);\n const pathParts = path.split(\"/\").filter(Boolean);\n\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i].startsWith(\":\")) {\n const paramName = patternParts[i].slice(1);\n params[paramName] = pathParts[i];\n }\n }\n\n return params;\n }\n}\n","/**\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","/**\n * Vafast 核心服务器\n *\n * 基于 Radix Tree 的高性能路由匹配\n * 时间复杂度: O(k),k 为路径段数\n */\n\nimport type { Route, NestedRoute, FlattenedRoute, Method } from \"../types\";\nimport { flattenNestedRoutes } from \"../router\";\nimport { composeMiddleware } from \"../middleware\";\nimport { json } from \"../utils/response\";\nimport { BaseServer } from \"./base-server\";\nimport { RadixRouter } from \"../router/radix-tree\";\n\n/**\n * Vafast 服务器\n *\n * @example\n * ```typescript\n * const server = new Server([\n * { method: \"GET\", path: \"/\", handler: () => new Response(\"Hello\") },\n * ]);\n * export default { fetch: server.fetch };\n * ```\n */\nexport class Server extends BaseServer {\n private router: RadixRouter;\n private routes: FlattenedRoute[];\n /** 是否已预编译 */\n private isCompiled = false;\n /** 预编译时的全局中间件数量 */\n private compiledWithMiddlewareCount = 0;\n\n constructor(routes: (Route | NestedRoute)[] = []) {\n super();\n this.router = new RadixRouter();\n this.routes = [];\n\n // 设置中间件编译器\n this.router.setCompiler((middleware, handler) =>\n composeMiddleware(middleware, handler),\n );\n\n if (routes.length > 0) {\n this.registerRoutes(routes);\n }\n }\n\n /**\n * 预编译所有路由处理链\n * 在添加所有路由和全局中间件后调用,可提升运行时性能\n */\n compile(): this {\n this.router.precompileAll(this.globalMiddleware);\n this.isCompiled = true;\n this.compiledWithMiddlewareCount = this.globalMiddleware.length;\n return this;\n }\n\n private registerRoutes(routes: (Route | NestedRoute)[]): void {\n const flattened = flattenNestedRoutes(routes);\n this.routes.push(...flattened);\n\n for (const route of flattened) {\n this.router.register(\n route.method as Method,\n route.fullPath,\n route.handler,\n route.middlewareChain || [],\n );\n }\n\n this.detectRouteConflicts(flattened);\n this.logFlattenedRoutes(flattened);\n\n // 自动预编译(如果没有全局中间件)\n if (this.globalMiddleware.length === 0 && !this.isCompiled) {\n this.compile();\n }\n }\n\n /** 快速提取 pathname */\n private extractPathname(url: string): string {\n let start = url.indexOf(\"://\");\n start = start === -1 ? 0 : start + 3;\n\n const pathStart = url.indexOf(\"/\", start);\n if (pathStart === -1) return \"/\";\n\n let end = url.indexOf(\"?\", pathStart);\n if (end === -1) end = url.indexOf(\"#\", pathStart);\n if (end === -1) end = url.length;\n\n return url.substring(pathStart, end) || \"/\";\n }\n\n /** 处理请求 */\n fetch = async (req: Request): Promise<Response> => {\n const pathname = this.extractPathname(req.url);\n const method = req.method as Method;\n\n const match = this.router.match(method, pathname);\n\n if (match) {\n (req as unknown as Record<string, unknown>).params = match.params;\n\n // 优先使用预编译的处理链(仅当全局中间件未变化时)\n if (\n match.compiled &&\n this.globalMiddleware.length === this.compiledWithMiddlewareCount\n ) {\n return match.compiled(req);\n }\n\n // 回退:运行时组合中间件\n const allMiddleware = [...this.globalMiddleware, ...match.middleware];\n const handler = composeMiddleware(allMiddleware, match.handler);\n\n return handler(req);\n }\n\n // 405 Method Not Allowed\n const allowedMethods = this.router.getAllowedMethods(pathname);\n if (allowedMethods.length > 0) {\n return json(\n {\n success: false,\n error: \"Method Not Allowed\",\n message: `Method ${method} not allowed for this endpoint`,\n allowedMethods,\n },\n 405,\n { Allow: allowedMethods.join(\", \") },\n );\n }\n\n // 404 Not Found\n return json({ success: false, error: \"Not Found\" }, 404);\n };\n\n addRoute(route: Route): void {\n const flattenedRoute: FlattenedRoute = {\n ...route,\n fullPath: route.path,\n middlewareChain: route.middleware || [],\n };\n\n this.routes.push(flattenedRoute);\n this.router.register(\n route.method as Method,\n route.path,\n route.handler,\n route.middleware || [],\n );\n }\n\n addRoutes(routes: (Route | NestedRoute)[]): void {\n this.registerRoutes(routes);\n }\n\n getRoutes(): Array<{ method: Method; path: string }> {\n return this.router.getRoutes();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Middleware } from './route.js';
|
|
2
|
+
import './types.js';
|
|
3
|
+
|
|
2
4
|
/**
|
|
3
5
|
* 组件路由配置
|
|
4
6
|
* 支持声明式的组件关联
|
|
5
7
|
*/
|
|
6
|
-
|
|
8
|
+
interface ComponentRoute {
|
|
7
9
|
path: string;
|
|
8
10
|
component: () => Promise<any>;
|
|
9
11
|
middleware?: Middleware[];
|
|
@@ -11,7 +13,7 @@ export interface ComponentRoute {
|
|
|
11
13
|
/**
|
|
12
14
|
* 嵌套组件路由配置
|
|
13
15
|
*/
|
|
14
|
-
|
|
16
|
+
interface NestedComponentRoute {
|
|
15
17
|
path: string;
|
|
16
18
|
middleware?: Middleware[];
|
|
17
19
|
children?: (ComponentRoute | NestedComponentRoute)[];
|
|
@@ -19,7 +21,9 @@ export interface NestedComponentRoute {
|
|
|
19
21
|
/**
|
|
20
22
|
* 扁平化后的组件路由
|
|
21
23
|
*/
|
|
22
|
-
|
|
24
|
+
interface FlattenedComponentRoute extends ComponentRoute {
|
|
23
25
|
fullPath: string;
|
|
24
26
|
middlewareChain: Middleware[];
|
|
25
27
|
}
|
|
28
|
+
|
|
29
|
+
export type { ComponentRoute, FlattenedComponentRoute, NestedComponentRoute };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
//# sourceMappingURL=component-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
4
|
-
export
|
|
5
|
-
|
|
1
|
+
export { FlattenedRoute, Handler, Method, Middleware, NestedRoute, ResponseBody, Route } from './types.js';
|
|
2
|
+
export { BaseRouteConfig, CompatibleRoute, ExtendedRouteConfig, NestedRouteConfig, TypedRoute, createTypedRoute, isTypedRoute } from './route.js';
|
|
3
|
+
export { ComponentRoute, FlattenedComponentRoute, NestedComponentRoute } from './component-route.js';
|
|
4
|
+
export { HandlerContext, HandlerContextWithExtra, InferSchema, RouteSchema, TypedHandler, TypedRouteConfig } from './schema.js';
|
|
5
|
+
import '@sinclair/typebox';
|
package/dist/types/index.js
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// src/types/route.ts
|
|
2
|
+
function createTypedRoute(config) {
|
|
3
|
+
return config;
|
|
4
|
+
}
|
|
5
|
+
function isTypedRoute(route) {
|
|
6
|
+
return route && typeof route === "object" && "method" in route && "path" in route && "handler" in route;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
createTypedRoute,
|
|
10
|
+
isTypedRoute
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Schema 类型定义
|
|
14
|
+
*
|
|
15
|
+
* 使用 TSchema 约束替代 any,提供完整的类型安全
|
|
16
|
+
*
|
|
17
|
+
* @author Framework Team
|
|
18
|
+
* @version 1.0.0
|
|
19
|
+
* @license MIT
|
|
20
|
+
*/
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/route.ts"],"sourcesContent":["import { Route, ResponseBody } from \"./types\";\n\n// 定义中间件类型\nexport interface Middleware {\n (req: Request, next: () => Promise<Response>): Promise<Response>;\n}\n\n// 基础路由配置\nexport interface BaseRouteConfig {\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"OPTIONS\" | \"HEAD\";\n path: string;\n handler: (req: Request) => ResponseBody | Promise<ResponseBody>;\n}\n\n// 扩展的路由配置 - 只保留Schema验证和中间件\nexport interface ExtendedRouteConfig extends BaseRouteConfig {\n // Tirne 中间件系统\n middleware?: Middleware[];\n\n // Schema验证配置\n body?: any;\n query?: any;\n params?: any;\n headers?: any;\n cookies?: any;\n\n // 其他配置\n docs?: {\n description?: string;\n tags?: string[];\n security?: any[];\n responses?: Record<string, any>;\n };\n timeout?: number;\n maxBodySize?: string;\n\n // 允许任意扩展\n [key: string]: any;\n}\n\n// 嵌套路由配置\nexport interface NestedRouteConfig {\n path: string;\n middleware?: Middleware[];\n children?: (NestedRouteConfig | ExtendedRouteConfig)[];\n}\n\n// 类型安全的路由\nexport type TypedRoute = ExtendedRouteConfig;\n\n// 兼容类型:可以接受Route或TypedRoute\nexport type CompatibleRoute = Route | TypedRoute;\n\n// 扁平化后的路由,包含完整的中间件链\nexport interface FlattenedRoute extends ExtendedRouteConfig {\n fullPath: string;\n middlewareChain: Middleware[];\n}\n\n// 导出一些实际的函数,确保 JavaScript 代码生成\nexport function createTypedRoute(\n config: ExtendedRouteConfig,\n): ExtendedRouteConfig {\n return config;\n}\n\nexport function isTypedRoute(route: any): route is TypedRoute {\n return (\n route &&\n typeof route === \"object\" &&\n \"method\" in route &&\n \"path\" in route &&\n \"handler\" in route\n );\n}\n"],"mappings":";AA4DO,SAAS,iBACd,QACqB;AACrB,SAAO;AACT;AAEO,SAAS,aAAa,OAAiC;AAC5D,SACE,SACA,OAAO,UAAU,YACjB,YAAY,SACZ,UAAU,SACV,aAAa;AAEjB;","names":[]}
|
package/dist/types/route.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { ResponseBody, Route } from './types.js';
|
|
2
|
+
|
|
3
|
+
interface Middleware {
|
|
3
4
|
(req: Request, next: () => Promise<Response>): Promise<Response>;
|
|
4
5
|
}
|
|
5
|
-
|
|
6
|
+
interface BaseRouteConfig {
|
|
6
7
|
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
7
8
|
path: string;
|
|
8
9
|
handler: (req: Request) => ResponseBody | Promise<ResponseBody>;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
interface ExtendedRouteConfig extends BaseRouteConfig {
|
|
11
12
|
middleware?: Middleware[];
|
|
12
13
|
body?: any;
|
|
13
14
|
query?: any;
|
|
@@ -24,16 +25,18 @@ export interface ExtendedRouteConfig extends BaseRouteConfig {
|
|
|
24
25
|
maxBodySize?: string;
|
|
25
26
|
[key: string]: any;
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
+
interface NestedRouteConfig {
|
|
28
29
|
path: string;
|
|
29
30
|
middleware?: Middleware[];
|
|
30
31
|
children?: (NestedRouteConfig | ExtendedRouteConfig)[];
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
type TypedRoute = ExtendedRouteConfig;
|
|
34
|
+
type CompatibleRoute = Route | TypedRoute;
|
|
35
|
+
interface FlattenedRoute extends ExtendedRouteConfig {
|
|
35
36
|
fullPath: string;
|
|
36
37
|
middlewareChain: Middleware[];
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
declare function createTypedRoute(config: ExtendedRouteConfig): ExtendedRouteConfig;
|
|
40
|
+
declare function isTypedRoute(route: any): route is TypedRoute;
|
|
41
|
+
|
|
42
|
+
export { type BaseRouteConfig, type CompatibleRoute, type ExtendedRouteConfig, type FlattenedRoute, type Middleware, type NestedRouteConfig, type TypedRoute, createTypedRoute, isTypedRoute };
|
package/dist/types/route.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/types/route.ts
|
|
2
|
+
function createTypedRoute(config) {
|
|
3
|
+
return config;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
typeof route === "object" &&
|
|
8
|
-
"method" in route &&
|
|
9
|
-
"path" in route &&
|
|
10
|
-
"handler" in route);
|
|
5
|
+
function isTypedRoute(route) {
|
|
6
|
+
return route && typeof route === "object" && "method" in route && "path" in route && "handler" in route;
|
|
11
7
|
}
|
|
8
|
+
export {
|
|
9
|
+
createTypedRoute,
|
|
10
|
+
isTypedRoute
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/route.ts"],"sourcesContent":["import { Route, ResponseBody } from \"./types\";\n\n// 定义中间件类型\nexport interface Middleware {\n (req: Request, next: () => Promise<Response>): Promise<Response>;\n}\n\n// 基础路由配置\nexport interface BaseRouteConfig {\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"OPTIONS\" | \"HEAD\";\n path: string;\n handler: (req: Request) => ResponseBody | Promise<ResponseBody>;\n}\n\n// 扩展的路由配置 - 只保留Schema验证和中间件\nexport interface ExtendedRouteConfig extends BaseRouteConfig {\n // Tirne 中间件系统\n middleware?: Middleware[];\n\n // Schema验证配置\n body?: any;\n query?: any;\n params?: any;\n headers?: any;\n cookies?: any;\n\n // 其他配置\n docs?: {\n description?: string;\n tags?: string[];\n security?: any[];\n responses?: Record<string, any>;\n };\n timeout?: number;\n maxBodySize?: string;\n\n // 允许任意扩展\n [key: string]: any;\n}\n\n// 嵌套路由配置\nexport interface NestedRouteConfig {\n path: string;\n middleware?: Middleware[];\n children?: (NestedRouteConfig | ExtendedRouteConfig)[];\n}\n\n// 类型安全的路由\nexport type TypedRoute = ExtendedRouteConfig;\n\n// 兼容类型:可以接受Route或TypedRoute\nexport type CompatibleRoute = Route | TypedRoute;\n\n// 扁平化后的路由,包含完整的中间件链\nexport interface FlattenedRoute extends ExtendedRouteConfig {\n fullPath: string;\n middlewareChain: Middleware[];\n}\n\n// 导出一些实际的函数,确保 JavaScript 代码生成\nexport function createTypedRoute(\n config: ExtendedRouteConfig,\n): ExtendedRouteConfig {\n return config;\n}\n\nexport function isTypedRoute(route: any): route is TypedRoute {\n return (\n route &&\n typeof route === \"object\" &&\n \"method\" in route &&\n \"path\" in route &&\n \"handler\" in route\n );\n}\n"],"mappings":";AA4DO,SAAS,iBACd,QACqB;AACrB,SAAO;AACT;AAEO,SAAS,aAAa,OAAiC;AAC5D,SACE,SACA,OAAO,UAAU,YACjB,YAAY,SACZ,UAAU,SACV,aAAa;AAEjB;","names":[]}
|
package/dist/types/schema.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TSchema, Static } from '@sinclair/typebox';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Schema 类型定义
|
|
3
5
|
*
|
|
@@ -7,12 +9,12 @@
|
|
|
7
9
|
* @version 1.0.0
|
|
8
10
|
* @license MIT
|
|
9
11
|
*/
|
|
10
|
-
|
|
12
|
+
|
|
11
13
|
/**
|
|
12
14
|
* 路由 Schema 配置
|
|
13
15
|
* 所有 schema 字段使用 TSchema 约束
|
|
14
16
|
*/
|
|
15
|
-
|
|
17
|
+
interface RouteSchema {
|
|
16
18
|
body?: TSchema;
|
|
17
19
|
query?: TSchema;
|
|
18
20
|
params?: TSchema;
|
|
@@ -22,7 +24,7 @@ export interface RouteSchema {
|
|
|
22
24
|
/**
|
|
23
25
|
* 从 Schema 配置推导出具体类型
|
|
24
26
|
*/
|
|
25
|
-
|
|
27
|
+
type InferSchema<T extends RouteSchema> = {
|
|
26
28
|
body: T["body"] extends TSchema ? Static<T["body"]> : unknown;
|
|
27
29
|
query: T["query"] extends TSchema ? Static<T["query"]> : Record<string, string>;
|
|
28
30
|
params: T["params"] extends TSchema ? Static<T["params"]> : Record<string, string>;
|
|
@@ -32,7 +34,7 @@ export type InferSchema<T extends RouteSchema> = {
|
|
|
32
34
|
/**
|
|
33
35
|
* Handler 上下文类型
|
|
34
36
|
*/
|
|
35
|
-
|
|
37
|
+
interface HandlerContext<T extends RouteSchema = RouteSchema> {
|
|
36
38
|
/** 原始请求对象 */
|
|
37
39
|
req: Request;
|
|
38
40
|
/** 请求体 (经过 schema 验证) */
|
|
@@ -50,15 +52,15 @@ export interface HandlerContext<T extends RouteSchema = RouteSchema> {
|
|
|
50
52
|
* 带额外上下文的 Handler 上下文类型
|
|
51
53
|
* 用于中间件注入额外数据
|
|
52
54
|
*/
|
|
53
|
-
|
|
55
|
+
type HandlerContextWithExtra<T extends RouteSchema = RouteSchema, TExtra extends Record<string, unknown> = Record<string, never>> = HandlerContext<T> & TExtra;
|
|
54
56
|
/**
|
|
55
57
|
* Handler 函数类型
|
|
56
58
|
*/
|
|
57
|
-
|
|
59
|
+
type TypedHandler<T extends RouteSchema = RouteSchema, TExtra extends Record<string, unknown> = Record<string, never>, TReturn = unknown> = (ctx: HandlerContextWithExtra<T, TExtra>) => TReturn | Promise<TReturn>;
|
|
58
60
|
/**
|
|
59
61
|
* 扩展的路由配置 (包含 schema)
|
|
60
62
|
*/
|
|
61
|
-
|
|
63
|
+
interface TypedRouteConfig<T extends RouteSchema = RouteSchema> {
|
|
62
64
|
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
63
65
|
path: string;
|
|
64
66
|
schema?: T;
|
|
@@ -73,3 +75,5 @@ export interface TypedRouteConfig<T extends RouteSchema = RouteSchema> {
|
|
|
73
75
|
timeout?: number;
|
|
74
76
|
maxBodySize?: string;
|
|
75
77
|
}
|
|
78
|
+
|
|
79
|
+
export type { HandlerContext, HandlerContextWithExtra, InferSchema, RouteSchema, TypedHandler, TypedRouteConfig };
|
package/dist/types/schema.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
|
|
2
2
|
/** 支持的响应类型 - 由 mapResponse 自动转换 */
|
|
3
|
-
|
|
3
|
+
type ResponseBody = Response | string | number | boolean | object | null | undefined | ReadableStream | Blob | ArrayBuffer;
|
|
4
4
|
/** Handler 返回值(支持同步/异步,任意类型) */
|
|
5
5
|
/** 传统 Handler 类型 */
|
|
6
|
-
|
|
6
|
+
type LegacyHandler = (req: Request, params?: Record<string, string>, user?: Record<string, any>) => ResponseBody | Promise<ResponseBody>;
|
|
7
7
|
/** createHandler 返回的类型 */
|
|
8
|
-
|
|
8
|
+
type FactoryHandler = (req: Request) => Promise<Response>;
|
|
9
9
|
/** Handler 联合类型(支持两种风格) */
|
|
10
|
-
|
|
10
|
+
type Handler = LegacyHandler | FactoryHandler;
|
|
11
11
|
/** 中间件(返回值必须是 Response 或 Promise<Response>) */
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
type Middleware = (req: Request, next: () => Promise<Response>) => Response | Promise<Response>;
|
|
13
|
+
interface Route {
|
|
14
14
|
method: Method;
|
|
15
15
|
path: string;
|
|
16
16
|
handler: Handler;
|
|
17
17
|
middleware?: Middleware[];
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
interface NestedRoute {
|
|
20
20
|
path: string;
|
|
21
21
|
middleware?: Middleware[];
|
|
22
22
|
children?: (NestedRoute | Route)[];
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
interface FlattenedRoute extends Route {
|
|
25
25
|
fullPath: string;
|
|
26
26
|
middlewareChain: Middleware[];
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
export type { FactoryHandler, FlattenedRoute, Handler, LegacyHandler, Method, Middleware, NestedRoute, ResponseBody, Route };
|
package/dist/types/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
declare function base64urlEncode(str: string): string;
|
|
2
|
+
declare function base64urlDecode(str: string): string;
|
|
3
|
+
|
|
4
|
+
export { base64urlDecode, base64urlEncode };
|
package/dist/utils/base64url.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
.replace(/\+/g, "-")
|
|
5
|
-
.replace(/\//g, "_");
|
|
1
|
+
// src/utils/base64url.ts
|
|
2
|
+
function base64urlEncode(str) {
|
|
3
|
+
return btoa(str).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
6
4
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
function base64urlDecode(str) {
|
|
6
|
+
const pad = str.length % 4 === 0 ? "" : "=".repeat(4 - str.length % 4);
|
|
7
|
+
const base64 = str.replace(/-/g, "+").replace(/_/g, "/") + pad;
|
|
8
|
+
return atob(base64);
|
|
11
9
|
}
|
|
10
|
+
export {
|
|
11
|
+
base64urlDecode,
|
|
12
|
+
base64urlEncode
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=base64url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/base64url.ts"],"sourcesContent":["export function base64urlEncode(str: string): string {\n return btoa(str)\n .replace(/=/g, \"\") // ✅ 删除填充\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\");\n}\n\nexport function base64urlDecode(str: string): string {\n const pad = str.length % 4 === 0 ? \"\" : \"=\".repeat(4 - (str.length % 4));\n const base64 = str.replace(/-/g, \"+\").replace(/_/g, \"/\") + pad;\n return atob(base64);\n}\n"],"mappings":";AAAO,SAAS,gBAAgB,KAAqB;AACnD,SAAO,KAAK,GAAG,EACZ,QAAQ,MAAM,EAAE,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG;AACvB;AAEO,SAAS,gBAAgB,KAAqB;AACnD,QAAM,MAAM,IAAI,SAAS,MAAM,IAAI,KAAK,IAAI,OAAO,IAAK,IAAI,SAAS,CAAE;AACvE,QAAM,SAAS,IAAI,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,IAAI;AAC3D,SAAO,KAAK,MAAM;AACpB;","names":[]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { RouteSchema, HandlerContext, HandlerContextWithExtra } from '../types/schema.js';
|
|
2
|
+
import '@sinclair/typebox';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* 类型安全的路由处理器工厂
|
|
3
6
|
*
|
|
@@ -7,7 +10,7 @@
|
|
|
7
10
|
* @version 3.0.0
|
|
8
11
|
* @license MIT
|
|
9
12
|
*/
|
|
10
|
-
|
|
13
|
+
|
|
11
14
|
/** 空 schema 的上下文类型 */
|
|
12
15
|
type EmptySchemaContext = {
|
|
13
16
|
req: Request;
|
|
@@ -32,8 +35,8 @@ type EmptySchemaContext = {
|
|
|
32
35
|
* )
|
|
33
36
|
* ```
|
|
34
37
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
declare function createHandler<R>(handler: (ctx: EmptySchemaContext) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
39
|
+
declare function createHandler<const T extends RouteSchema, R>(schema: T, handler: (ctx: HandlerContext<T>) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
37
40
|
/**
|
|
38
41
|
* 创建带额外上下文的路由处理器
|
|
39
42
|
*
|
|
@@ -56,8 +59,8 @@ export declare function createHandler<const T extends RouteSchema, R>(schema: T,
|
|
|
56
59
|
* )
|
|
57
60
|
* ```
|
|
58
61
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
declare function createHandlerWithExtra<TExtra extends Record<string, unknown> = Record<string, never>, R = unknown>(handler: (ctx: EmptySchemaContext & TExtra) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
63
|
+
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
64
|
/**
|
|
62
65
|
* 简单的路由处理器 (无 schema 验证,只有 req)
|
|
63
66
|
*
|
|
@@ -68,7 +71,8 @@ export declare function createHandlerWithExtra<TExtra extends Record<string, unk
|
|
|
68
71
|
* })
|
|
69
72
|
* ```
|
|
70
73
|
*/
|
|
71
|
-
|
|
74
|
+
declare function simpleHandler<R>(handler: (ctx: {
|
|
72
75
|
req: Request;
|
|
73
76
|
}) => R | Promise<R>): (req: Request) => Promise<Response>;
|
|
74
|
-
|
|
77
|
+
|
|
78
|
+
export { createHandler, createHandlerWithExtra, simpleHandler };
|