import type { VextMiddleware } from "../../types/middleware.js"; import type { VextRequestIdConfig } from "../../types/app.js"; import type { VextLocaleConfig } from "../../types/app.js"; /** * createRequestIdMiddleware — 请求 ID 中间件工厂 * * 内置中间件 #1(执行顺序最靠前),职责: * 1. 从请求头透传 requestId(网关注入场景),不存在则生成 UUID v4 * 2. 挂载到 req.requestId * 3. 写入 AsyncLocalStorage(requestContext)— logger / app.throw / app.fetch 等依赖此数据 * 4. 写入响应头(默认 x-request-id) * 5. 从入站请求中捕获 propagateHeaders 列表中的头,写入 store.propagatedHeaders * 供 app.fetch 在出站请求时自动透传(分布式追踪头、多租户头等) * * 配置项(config.requestId): * - enabled: 是否启用(默认 true);false 时 req.requestId = '',不写入 store * - header: 从哪个请求头读取(默认 'x-request-id') * - responseHeader: 将 requestId 写入响应头(默认 'x-request-id') * - generate: 自定义生成函数(默认 crypto.randomUUID); * 插件可通过 app.setRequestIdGenerator() 覆盖 * * 与 requestContext 的关系: * adapter 在 registerRoute 中已调用 requestContext.run({ requestId: '', locale: undefined }, ...) * 创建了请求作用域。本中间件在链最前端执行,将真实 requestId 写入已有的 store 中。 * 后续代码通过 requestContext.getStore()?.requestId 读取(logger mixin / defaultThrow / app.fetch)。 * * propagatedHeaders 写入机制: * 从入站请求头中提取 propagateHeaderNames 列表中指定的头(小写匹配), * 存入 store.propagatedHeaders(Record),键名统一小写。 * app.fetch 在构建出站请求时从此字段读取并注入,实现"入站头 → store → 出站头"完整链路。 * * @param config requestId 配置(从 VextConfig.requestId 提取) * @param getGenerator 获取当前 ID 生成函数的 getter(支持 app.setRequestIdGenerator() 运行时替换) * @param propagateHeaderNames 需要从入站请求捕获并透传到下游的头名称列表(来自 config.fetch.propagateHeaders) * @param localeConfig i18n locale 配置(从 VextConfig.locale 提取),用于解析 Accept-Language 并写入 store.locale * @returns VextMiddleware */ export declare function createRequestIdMiddleware(config: VextRequestIdConfig, getGenerator: () => (() => string) | null, propagateHeaderNames?: string[], localeConfig?: VextLocaleConfig): VextMiddleware;