vafast 0.3.11 → 0.4.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.
@@ -1 +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 /** 生成 404/405 响应 */\n private createErrorResponse(method: string, pathname: string): Response {\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 return json({ success: false, error: \"Not Found\" }, 404);\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 // OPTIONS 预检请求特殊处理:查找同路径其他方法的路由,使用其中间件\n // 这允许路由级 CORS 中间件正常工作\n if (method === \"OPTIONS\") {\n const allowedMethods = this.router.getAllowedMethods(pathname);\n if (allowedMethods.length > 0) {\n // 尝试获取该路径任意方法的路由中间件\n const anyMatch = this.router.match(\n allowedMethods[0] as Method,\n pathname,\n );\n const routeMiddleware = anyMatch?.middleware || [];\n const allMiddleware = [...this.globalMiddleware, ...routeMiddleware];\n\n // OPTIONS 请求默认返回 204(中间件如 CORS 可能会提前响应)\n const optionsHandler = () =>\n new Response(null, {\n status: 204,\n headers: { Allow: allowedMethods.join(\", \") },\n });\n\n const handler = composeMiddleware(allMiddleware, optionsHandler);\n return handler(req);\n }\n }\n\n // 未匹配路由时,仍执行全局中间件(如 CORS 处理 OPTIONS 预检)\n if (this.globalMiddleware.length > 0) {\n const handler = composeMiddleware(this.globalMiddleware, () =>\n this.createErrorResponse(method, pathname),\n );\n return handler(req);\n }\n\n return this.createErrorResponse(method, pathname);\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
+ {"version":3,"sources":["../../src/router.ts","../../src/utils/response.ts","../../src/middleware.ts","../../src/server/base-server.ts","../../src/router/radix-tree.ts","../../src/utils/route-registry.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 const leafRoute = route as Route;\n flattened.push({\n ...leafRoute,\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 * 路由注册表\n *\n * 提供路由元信息的收集和查询能力\n * 可用于:API 文档生成、Webhook 事件注册、权限检查、审计日志等\n *\n * @example\n * ```typescript\n * // 创建注册表\n * const registry = createRouteRegistry(server.getRoutes())\n *\n * // 查询路由\n * const route = registry.get('POST', '/auth/signIn')\n *\n * // 筛选有 webhook 配置的路由\n * const webhookRoutes = registry.filter('webhook')\n *\n * // 按分类获取\n * const authRoutes = registry.getByCategory('auth')\n * ```\n */\n\nimport type { FlattenedRoute, Method } from '../types'\n\n/**\n * 路由元信息(不含 handler 和 middleware)\n */\nexport interface RouteMeta {\n method: Method\n path: string\n fullPath: string\n name?: string\n description?: string\n /** 扩展字段 */\n [key: string]: unknown\n}\n\n/**\n * 路由注册表\n *\n * 泛型 T 用于定义扩展字段的类型\n */\nexport class RouteRegistry<T extends Record<string, unknown> = Record<string, unknown>> {\n /** 所有路由元信息 */\n private routes: RouteMeta[] = []\n\n /** 路由映射表:METHOD:fullPath -> RouteMeta */\n private routeMap = new Map<string, RouteMeta>()\n\n /** 分类映射表:category -> RouteMeta[] */\n private categoryMap = new Map<string, RouteMeta[]>()\n\n constructor(routes: FlattenedRoute[]) {\n this.buildRegistry(routes)\n }\n\n /**\n * 构建注册表\n */\n private buildRegistry(routes: FlattenedRoute[]): void {\n for (const route of routes) {\n // 提取元信息(排除 handler 和 middleware)\n const meta: RouteMeta = {\n method: route.method,\n path: route.path,\n fullPath: route.fullPath,\n name: route.name,\n description: route.description,\n }\n\n // 复制扩展字段\n for (const key of Object.keys(route)) {\n if (!['method', 'path', 'fullPath', 'name', 'description', 'handler', 'middleware', 'middlewareChain'].includes(key)) {\n meta[key] = route[key as keyof FlattenedRoute]\n }\n }\n\n this.routes.push(meta)\n this.routeMap.set(`${route.method}:${route.fullPath}`, meta)\n\n // 按分类索引\n const category = this.extractCategory(route.fullPath)\n if (!this.categoryMap.has(category)) {\n this.categoryMap.set(category, [])\n }\n this.categoryMap.get(category)!.push(meta)\n }\n }\n\n /**\n * 提取分类(第一段路径)\n */\n private extractCategory(path: string): string {\n const segments = path.split('/').filter(Boolean)\n return segments[0] || 'root'\n }\n\n // ============================================\n // 查询接口\n // ============================================\n\n /**\n * 获取所有路由元信息\n */\n getAll(): RouteMeta[] {\n return [...this.routes]\n }\n\n /**\n * 按 method + path 查询路由\n */\n get(method: string, path: string): (RouteMeta & T) | undefined {\n return this.routeMap.get(`${method}:${path}`) as (RouteMeta & T) | undefined\n }\n\n /**\n * 检查路由是否存在\n */\n has(method: string, path: string): boolean {\n return this.routeMap.has(`${method}:${path}`)\n }\n\n /**\n * 按分类获取路由\n */\n getByCategory(category: string): RouteMeta[] {\n return this.categoryMap.get(category) || []\n }\n\n /**\n * 获取所有分类\n */\n getCategories(): string[] {\n return Array.from(this.categoryMap.keys()).sort()\n }\n\n /**\n * 筛选有特定字段的路由\n *\n * @example\n * ```typescript\n * // 获取所有配置了 webhook 的路由\n * const webhookRoutes = registry.filter('webhook')\n * ```\n */\n filter<K extends string>(field: K): (RouteMeta & Record<K, unknown>)[] {\n return this.routes.filter((r) => field in r && r[field] !== undefined) as (RouteMeta & Record<K, unknown>)[]\n }\n\n /**\n * 按条件筛选路由\n *\n * @example\n * ```typescript\n * // 获取所有 POST 请求\n * const postRoutes = registry.filterBy(r => r.method === 'POST')\n * ```\n */\n filterBy(predicate: (route: RouteMeta) => boolean): RouteMeta[] {\n return this.routes.filter(predicate)\n }\n\n /**\n * 获取路由数量\n */\n get size(): number {\n return this.routes.length\n }\n\n /**\n * 遍历所有路由\n */\n forEach(callback: (route: RouteMeta, index: number) => void): void {\n this.routes.forEach(callback)\n }\n\n /**\n * 映射所有路由\n */\n map<R>(callback: (route: RouteMeta, index: number) => R): R[] {\n return this.routes.map(callback)\n }\n}\n\n/**\n * 创建路由注册表\n *\n * @example\n * ```typescript\n * // 定义扩展字段类型\n * interface MyRouteMeta {\n * webhook?: { eventKey: string }\n * permission?: string\n * }\n *\n * // 创建带类型的注册表\n * const registry = createRouteRegistry<MyRouteMeta>(server.getRoutes())\n *\n * // 类型安全的查询\n * const route = registry.get('POST', '/auth/signIn')\n * if (route?.webhook) {\n * console.log(route.webhook.eventKey)\n * }\n * ```\n */\nexport function createRouteRegistry<T extends Record<string, unknown> = Record<string, unknown>>(\n routes: FlattenedRoute[]\n): RouteRegistry<T> {\n return new RouteRegistry<T>(routes)\n}\n\n// ============================================\n// 全局 Registry(单例模式)\n// ============================================\n\n/** 全局 registry 实例 */\nlet globalRegistry: RouteRegistry | null = null\n\n/**\n * 设置全局 registry(框架内部使用)\n * @internal\n */\nexport function setGlobalRegistry(registry: RouteRegistry): void {\n globalRegistry = registry\n}\n\n/**\n * 获取全局路由注册表\n *\n * @example\n * ```typescript\n * // 在任意文件中\n * import { getRouteRegistry } from 'vafast'\n *\n * const registry = getRouteRegistry()\n * const webhookRoutes = registry.filter('webhook')\n * ```\n *\n * @throws 如果 Server 尚未创建\n */\nexport function getRouteRegistry<T extends Record<string, unknown> = Record<string, unknown>>(): RouteRegistry<T> {\n if (!globalRegistry) {\n throw new Error('RouteRegistry not initialized. Make sure Server is created first.')\n }\n return globalRegistry as RouteRegistry<T>\n}\n\n/**\n * 按 method + path 获取单个路由\n *\n * 便捷函数,无需先获取 registry\n *\n * @example\n * ```typescript\n * // 在中间件或接口中\n * import { getRoute } from 'vafast'\n *\n * const route = getRoute('POST', '/auth/signIn')\n * if (route?.webhook) {\n * console.log('This route has webhook:', route.webhook)\n * }\n * ```\n */\nexport function getRoute<T extends Record<string, unknown> = Record<string, unknown>>(\n method: string,\n path: string\n): (RouteMeta & T) | undefined {\n return getRouteRegistry<T>().get(method, path)\n}\n\n/**\n * 获取所有路由\n *\n * @example\n * ```typescript\n * import { getAllRoutes } from 'vafast'\n *\n * const routes = getAllRoutes()\n * console.log(`Total ${routes.length} routes`)\n * ```\n */\nexport function getAllRoutes(): RouteMeta[] {\n return getRouteRegistry().getAll()\n}\n\n/**\n * 筛选有特定字段的路由\n *\n * @example\n * ```typescript\n * import { filterRoutes } from 'vafast'\n *\n * // 获取所有配置了 webhook 的路由\n * const webhookRoutes = filterRoutes('webhook')\n * ```\n */\nexport function filterRoutes<K extends string>(field: K): (RouteMeta & Record<K, unknown>)[] {\n return getRouteRegistry().filter(field)\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\";\nimport { RouteRegistry, setGlobalRegistry } from \"../utils/route-registry\";\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 // 自动设置全局 RouteRegistry(支持在任意位置通过 getRouteRegistry() 访问)\n setGlobalRegistry(new RouteRegistry(this.routes));\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 /** 生成 404/405 响应 */\n private createErrorResponse(method: string, pathname: string): Response {\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 return json({ success: false, error: \"Not Found\" }, 404);\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 // OPTIONS 预检请求特殊处理:查找同路径其他方法的路由,使用其中间件\n // 这允许路由级 CORS 中间件正常工作\n if (method === \"OPTIONS\") {\n const allowedMethods = this.router.getAllowedMethods(pathname);\n if (allowedMethods.length > 0) {\n // 尝试获取该路径任意方法的路由中间件\n const anyMatch = this.router.match(\n allowedMethods[0] as Method,\n pathname,\n );\n const routeMiddleware = anyMatch?.middleware || [];\n const allMiddleware = [...this.globalMiddleware, ...routeMiddleware];\n\n // OPTIONS 请求默认返回 204(中间件如 CORS 可能会提前响应)\n const optionsHandler = () =>\n new Response(null, {\n status: 204,\n headers: { Allow: allowedMethods.join(\", \") },\n });\n\n const handler = composeMiddleware(allMiddleware, optionsHandler);\n return handler(req);\n }\n }\n\n // 未匹配路由时,仍执行全局中间件(如 CORS 处理 OPTIONS 预检)\n if (this.globalMiddleware.length > 0) {\n const handler = composeMiddleware(this.globalMiddleware, () =>\n this.createErrorResponse(method, pathname),\n );\n return handler(req);\n }\n\n return this.createErrorResponse(method, pathname);\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 /**\n * 获取完整的路由元信息(不含 handler 和 middleware)\n *\n * 用于 API 文档生成、Webhook 事件注册、权限检查等场景\n *\n * @example\n * ```typescript\n * const routes = server.getRoutesWithMeta()\n * for (const route of routes) {\n * console.log(route.fullPath, route.name, route.description)\n * }\n * ```\n */\n getRoutesWithMeta(): FlattenedRoute[] {\n return this.routes;\n }\n}\n"],"mappings":"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","names":[]}
@@ -15,11 +15,23 @@ interface Route {
15
15
  path: string;
16
16
  handler: Handler;
17
17
  middleware?: Middleware[];
18
+ /** 路由名称(用于文档、事件等) */
19
+ name?: string;
20
+ /** 路由描述 */
21
+ description?: string;
22
+ /** 允许任意扩展(支持 Webhook、权限等插件) */
23
+ [key: string]: unknown;
18
24
  }
19
25
  interface NestedRoute {
20
26
  path: string;
21
27
  middleware?: Middleware[];
22
28
  children?: (NestedRoute | Route)[];
29
+ /** 路由组名称 */
30
+ name?: string;
31
+ /** 路由组描述 */
32
+ description?: string;
33
+ /** 允许任意扩展 */
34
+ [key: string]: unknown;
23
35
  }
24
36
  interface FlattenedRoute extends Route {
25
37
  fullPath: string;
@@ -10,5 +10,7 @@ export { DependencyManager } from './dependency-manager.js';
10
10
  export { SchemaConfig, ValidationError, ValidationResult, createValidator, getValidatorCacheStats, precompileSchemas, validateAllSchemas, validateFast, validateSchema, validateSchemaOrThrow } from './validators/validators.js';
11
11
  export { Patterns, hasFormat, registerFormat, registerFormats } from './formats.js';
12
12
  export { SSEEvent, SSEHandler, SSEMarker, createSSEHandler } from './sse.js';
13
+ export { RouteMeta, RouteRegistry, createRouteRegistry, filterRoutes, getAllRoutes, getRoute, getRouteRegistry } from './route-registry.js';
13
14
  import '../types/schema.js';
14
15
  import '@sinclair/typebox';
16
+ import '../types/types.js';
@@ -820,21 +820,167 @@ function createSSEHandler(schemaOrGenerator, maybeGenerator) {
820
820
  handler.__returnType = void 0;
821
821
  return handler;
822
822
  }
823
+
824
+ // src/utils/route-registry.ts
825
+ var RouteRegistry = class {
826
+ /** 所有路由元信息 */
827
+ routes = [];
828
+ /** 路由映射表:METHOD:fullPath -> RouteMeta */
829
+ routeMap = /* @__PURE__ */ new Map();
830
+ /** 分类映射表:category -> RouteMeta[] */
831
+ categoryMap = /* @__PURE__ */ new Map();
832
+ constructor(routes) {
833
+ this.buildRegistry(routes);
834
+ }
835
+ /**
836
+ * 构建注册表
837
+ */
838
+ buildRegistry(routes) {
839
+ for (const route of routes) {
840
+ const meta = {
841
+ method: route.method,
842
+ path: route.path,
843
+ fullPath: route.fullPath,
844
+ name: route.name,
845
+ description: route.description
846
+ };
847
+ for (const key of Object.keys(route)) {
848
+ if (!["method", "path", "fullPath", "name", "description", "handler", "middleware", "middlewareChain"].includes(key)) {
849
+ meta[key] = route[key];
850
+ }
851
+ }
852
+ this.routes.push(meta);
853
+ this.routeMap.set(`${route.method}:${route.fullPath}`, meta);
854
+ const category = this.extractCategory(route.fullPath);
855
+ if (!this.categoryMap.has(category)) {
856
+ this.categoryMap.set(category, []);
857
+ }
858
+ this.categoryMap.get(category).push(meta);
859
+ }
860
+ }
861
+ /**
862
+ * 提取分类(第一段路径)
863
+ */
864
+ extractCategory(path) {
865
+ const segments = path.split("/").filter(Boolean);
866
+ return segments[0] || "root";
867
+ }
868
+ // ============================================
869
+ // 查询接口
870
+ // ============================================
871
+ /**
872
+ * 获取所有路由元信息
873
+ */
874
+ getAll() {
875
+ return [...this.routes];
876
+ }
877
+ /**
878
+ * 按 method + path 查询路由
879
+ */
880
+ get(method, path) {
881
+ return this.routeMap.get(`${method}:${path}`);
882
+ }
883
+ /**
884
+ * 检查路由是否存在
885
+ */
886
+ has(method, path) {
887
+ return this.routeMap.has(`${method}:${path}`);
888
+ }
889
+ /**
890
+ * 按分类获取路由
891
+ */
892
+ getByCategory(category) {
893
+ return this.categoryMap.get(category) || [];
894
+ }
895
+ /**
896
+ * 获取所有分类
897
+ */
898
+ getCategories() {
899
+ return Array.from(this.categoryMap.keys()).sort();
900
+ }
901
+ /**
902
+ * 筛选有特定字段的路由
903
+ *
904
+ * @example
905
+ * ```typescript
906
+ * // 获取所有配置了 webhook 的路由
907
+ * const webhookRoutes = registry.filter('webhook')
908
+ * ```
909
+ */
910
+ filter(field) {
911
+ return this.routes.filter((r) => field in r && r[field] !== void 0);
912
+ }
913
+ /**
914
+ * 按条件筛选路由
915
+ *
916
+ * @example
917
+ * ```typescript
918
+ * // 获取所有 POST 请求
919
+ * const postRoutes = registry.filterBy(r => r.method === 'POST')
920
+ * ```
921
+ */
922
+ filterBy(predicate) {
923
+ return this.routes.filter(predicate);
924
+ }
925
+ /**
926
+ * 获取路由数量
927
+ */
928
+ get size() {
929
+ return this.routes.length;
930
+ }
931
+ /**
932
+ * 遍历所有路由
933
+ */
934
+ forEach(callback) {
935
+ this.routes.forEach(callback);
936
+ }
937
+ /**
938
+ * 映射所有路由
939
+ */
940
+ map(callback) {
941
+ return this.routes.map(callback);
942
+ }
943
+ };
944
+ function createRouteRegistry(routes) {
945
+ return new RouteRegistry(routes);
946
+ }
947
+ var globalRegistry = null;
948
+ function getRouteRegistry() {
949
+ if (!globalRegistry) {
950
+ throw new Error("RouteRegistry not initialized. Make sure Server is created first.");
951
+ }
952
+ return globalRegistry;
953
+ }
954
+ function getRoute(method, path) {
955
+ return getRouteRegistry().get(method, path);
956
+ }
957
+ function getAllRoutes() {
958
+ return getRouteRegistry().getAll();
959
+ }
960
+ function filterRoutes(field) {
961
+ return getRouteRegistry().filter(field);
962
+ }
823
963
  export {
824
964
  DependencyManager,
825
965
  HtmlRenderer,
826
966
  Patterns,
967
+ RouteRegistry,
827
968
  base64urlDecode,
828
969
  base64urlEncode,
829
970
  createHandler,
830
971
  createHandlerWithExtra,
831
972
  createRequestValidator,
973
+ createRouteRegistry,
832
974
  createSSEHandler,
833
975
  createValidator,
834
976
  empty,
977
+ filterRoutes,
978
+ getAllRoutes,
835
979
  getCookie,
836
980
  getHeader,
837
981
  getLocals,
982
+ getRoute,
983
+ getRouteRegistry,
838
984
  getValidatorCacheStats,
839
985
  goAwait,
840
986
  hasFormat,