import type { VextApp } from "../types/app.js"; import type { VextMiddleware } from "../types/middleware.js"; import type { MiddlewareRegistry } from "./middleware-loader.js"; import type { RouteMetadataCollector } from "./openapi/collector.js"; /** * router-loader.ts — 路由自动加载器(Phase 1 升级版) * * 扫描用户项目的 src/routes/ 目录,自动加载所有路由文件, * 提取挂载前缀,依次注册到底层 adapter。 * * Phase 1 升级内容(相对 Phase 0 骨架): * - 集成 MiddlewareRegistry(替换 Phase 0 的 Map) * - 集成 buildValidateMiddleware:为有 validate 配置的路由自动构建校验中间件 * - 重复路由检测:同 method + path 不允许重复注册 * - validateMiddlewareRefs:所有路由加载后统一验证中间件引用合法性 * - 路由级中间件通过 resolveMiddlewares 从 registry 解析(支持工厂参数合并) * - 测试文件检测:routes/ 内不应包含 .test. / .spec. 文件(Fail Fast 警告) * * 核心流程: * 1. 递归扫描 routesDir 下的所有 .ts/.js/.mjs/.cjs 文件 * 2. 排除 _ 开头的文件/目录、.d.ts 文件 * 3. 检测 .test./.spec. 文件 → Fail Fast 报错 * 4. 按文件路径推导路由前缀([param] → :param、index → 空) * 5. 检测前缀冲突 * 6. 静态段文件排在动态段文件之前(排序) * 7. 对每个文件:import → 获取 RouteDefinition → 执行 factory → 收集路由 * 8. 重复路由检测(同 method + path) * 9. 路由级中间件解析(MiddlewareRegistry)+ validate 中间件构建 * 10. 注册到 adapter * 11. 所有路由加载后统一验证中间件引用(validateMiddlewareRefs) * * Fail Fast 策略: * - 前缀冲突 → 启动时报错 * - 文件无 default export → 启动时报错 * - routes/ 内存在 .test./.spec. 文件 → 启动时报错 * - 重复路由(同 method + path)→ 启动时报错 * - 中间件引用不在 registry 中 → 启动时报错 * * @module lib/router-loader * @see IMPLEMENTATION-PLAN.md 任务 1.14 * @see 01d-router-loader.md(router-loader 内部实现详细方案) */ /** * router-loader 配置选项 * * 由 bootstrap 在调用 loadRoutes 时传入, * 包含已加载的中间件注册表和全局中间件列表。 */ export interface LoadRoutesOptions { /** * 已加载的路由级中间件注册表 * * Phase 1 升级:从 Map 改为 MiddlewareRegistry, * 支持工厂中间件参数合并和显式类型检测。 * * 为了向后兼容 Phase 0 bootstrap 中的 `new Map()` 调用, * 同时接受 Map 类型(空 map 场景)。 */ middlewareDefs: MiddlewareRegistry | Map; /** 全局中间件列表(插件通过 app.use() 注册的) */ globalMiddlewares: VextMiddleware[]; } /** * loadRoutes — 扫描 routes/ 目录加载路由文件并注册到 adapter * * @param app VextApp 实例 * @param routesDir routes/ 目录的绝对路径(如 /path/to/my-app/src/routes) * @param options 加载选项(中间件注册表 + 全局中间件) * @param collector 🆕 OpenAPI 路由元信息收集器(可选,未配置 openapi 时为 null) * * @example * ```typescript * // bootstrap 内部(Phase 1) * await loadRoutes(app, path.join(rootDir, 'src/routes'), { * middlewareDefs: middlewareRegistry, * globalMiddlewares: internals.getGlobalMiddlewares(), * }, collector) * ``` */ export declare function loadRoutes(app: VextApp, routesDir: string, options: LoadRoutesOptions, collector?: RouteMetadataCollector | null): Promise;