/** * generator.ts — OpenAPIGenerator(OpenAPI 3.0 文档生成器) * * 接收 RouteMetadata[] 路由元信息列表,生成完整的 OpenAPI 3.0.3 文档。 * * 核心职责: * 1. 遍历路由元信息,为每条路由构建 Operation 对象 * 2. 将 validate.param / query / header / cookie → parameters * 3. 将 validate.body → requestBody * 4. 将 RouteOptions.responses + docs.responses → OpenAPI responses * 5. 从 middlewares 推断 security(auth → bearerAuth) * 6. 从 middlewares 推断 x-rate-limit 扩展 * 7. 自动推断 tags(从文件路径)和 operationId(从方法+路径) * 8. 注册通用 ErrorResponse / SuccessResponse components/schemas * * 路径格式转换: * vext: /users/:id → OpenAPI: /users/{id} * vext: /files/*path → OpenAPI: /files/{path} * * @module lib/openapi/generator * @see 14-openapi.md §5(OpenAPIGenerator — 文档生成器) */ import type { RouteMetadata, OpenAPIConfig, OpenAPIDocument } from "./types.js"; export declare const DEPRECATED_ROUTE_DOCS_TAGS_WARNING = "[openapi] route docs.tags is deprecated and ignored. Tags are inferred automatically from route path/source."; export interface DeprecatedRouteDocsTagsUsage { method: string; path: string; sourceFile: string; tags: string[]; } export declare function collectDeprecatedRouteDocsTagsUsage(routes: RouteMetadata[]): DeprecatedRouteDocsTagsUsage[]; export declare function createDeprecatedRouteDocsTagsWarning(routes: RouteMetadata[]): string | undefined; /** * OpenAPIGenerator — OpenAPI 3.0 文档生成器 * * 无状态生成器(converter 内部也无状态),可安全多次调用 generate()。 * * @example * ```typescript * const generator = new OpenAPIGenerator({ * title: 'My API', * version: '1.0.0', * servers: [{ url: 'http://localhost:3000', description: 'Development' }], * }) * * const routes = collector.getRoutes() * const doc = generator.generate(routes) * const json = generator.generateJSON(routes) * ``` */ export declare class OpenAPIGenerator { private converter; private config; private responseWrap; constructor(config?: OpenAPIConfig, runtime?: { responseWrap?: boolean; }); /** * 生成完整的 OpenAPI 3.0 文档 * * @param routes RouteMetadata[] 路由元信息列表(由 collector.getRoutes() 提供) * @returns OpenAPIDocument 完整的 OpenAPI 3.0 文档对象 */ generate(routes: RouteMetadata[]): OpenAPIDocument; /** * 生成 JSON 格式的 OpenAPI 文档字符串 * * @param routes RouteMetadata[] 路由元信息列表 * @returns JSON 字符串(格式化缩进 2 空格) */ generateJSON(routes: RouteMetadata[]): string; private assertUniqueOperationId; private describeOperationIdRoute; private formatOperationIdRoute; /** * 构建单个路由的 Operation 对象 * * 依次处理: * 1. summary / operationId / tags / deprecated / description * 2. 路径参数(validate.param → parameters[in=path]) * 3. 查询参数(validate.query → parameters[in=query]) * 4. 请求头(validate.header → parameters[in=header]) * 5. Cookie(validate.cookie → parameters[in=cookie]) * 6. 请求体(validate.body → requestBody,仅 POST/PUT/PATCH) * 7. 响应(docs.responses → responses,成功响应自动包装) * 8. 默认响应(未声明时添加 200 OK) * 9. 安全方案(从 middlewares 或 docs.security 推断) * 10. 自定义扩展(docs.extensions → x-* 字段) * 11. 文档权限 metadata(docs.access → x-vext-docs-access) * 12. 速率限制(从 rate-limit 中间件推断 x-rate-limit) * 13. 清空空参数数组 * * @param route 单条路由的元信息 * @returns OpenAPIOperation 对象 */ private buildOperation; private buildRateLimitExtension; private isPositiveFiniteNumber; /** * 包装响应 schema 为 vext 标准格式 * * 成功响应(2xx,非 204): * { code: 0, data: <原始 schema>, requestId: string } * * 204 No Content: * 空对象(无响应体) * * 错误响应(4xx/5xx): * 直接使用原始 schema(通常是 ErrorResponse 格式) * * @param statusCode HTTP 状态码 * @param dataSchema 原始数据 schema * @returns 包装后的 JsonSchema */ private wrapResponseSchema; /** Runtime schemas describe res.json() business data for every body status. */ private wrapRuntimeResponseSchema; /** * 包装响应示例为 vext 标准格式 * * 成功响应(2xx,非 204)自动包装为 { code: 0, data: ..., requestId: '...' } * 错误响应直接返回原始示例 * * @param statusCode HTTP 状态码 * @param example 原始示例值 * @returns 包装后的示例值 */ private wrapResponseExample; private wrapRuntimeResponseExample; /** * 转换路由路径格式 * * vext 使用 Express 风格的路径参数(:param), * OpenAPI 使用花括号风格({param})。 * * vext: /users/:id → OpenAPI: /users/{id} * vext: /files/*path → OpenAPI: /files/{path} * * @param path vext 格式的路由路径 * @returns OpenAPI 格式的路由路径 */ private convertPath; private extractPathParameterNames; /** * 从 middlewares 推断 security * * 检测 middleware 名称是否匹配 guardSecurityMap 中的 key。 * middlewares 可以是 string 或 { name, options } 对象,需统一提取 name。 * * 默认映射: * - 'auth' → bearerAuth * - 'api-key' → apiKeyAuth * * 用户可通过 config.guardSecurityMap 自定义映射。 * * @param middlewares 路由级中间件列表 * @returns 推断出的 security 数组 */ private inferSecurityFromMiddlewares; /** * 构建 securitySchemes * * 优先使用用户配置的 securitySchemes。 * 若未配置,提供默认的 Bearer Token 方案。 * * @returns securitySchemes 对象 */ private buildSecuritySchemes; /** * 构建显式 x-tagGroups vendor extension * * 只有用户显式配置 openapi.tagGroups 时才输出。 * 默认 Vext Docs renderer 已使用 OpenAPI path segment 生成递归导航; * 自动把业务 tags 归入文件目录分组容易生成误导性的 General 分组。 */ private buildTagGroups; /** * 从路由列表推断 tags * * 收集所有路由的 tags(显式声明或从文件路径推断), * 去重排序后返回。 * * @param routes 路由元信息列表 * @returns tag 定义列表(按名称排序) */ private inferTags; private inferTag; private inferTagFromPath; private isApiVersionTagSegment; private formatApiVersionTagSegment; private isDynamicPathSegment; private humanizeTagSegment; /** * 从文件路径推断 tag * * 提取 routes/ 后面的相对路径,移除扩展名: * routes/users.ts → 'users' * routes/admin/roles.ts → 'admin-roles' * routes/index.ts → 'default' * * @param sourceFile 路由文件的绝对路径 * @returns 推断的 tag 名称 */ private inferTagFromFile; }