/** * route-cache.ts — 路由级响应缓存中间件工厂 * * 职责: * 1. normalizeCacheOptions:统一 false/number/object → RouteCacheOptions | null * 2. defaultCacheKey:默认 key 生成(method:path?sortedQuery|varyHeaders) * 3. buildRouteCacheMiddleware:构建路由级响应缓存中间件 * * 设计: * - 缓存中间件插入在路由级中间件之后、validate 之前 * - HIT:直接发送 response-cache-kit 结果(跳过 validate + handler) * - MISS:注册 res._onSend 钩子,handler 执行 res.json() 时捕获原始 data * - 204 / 非 JSON 响应不缓存 * - 空 key 跳过缓存 * * @module lib/middlewares/route-cache * @see 15-route-cache.md §4(内部架构) */ import type { VextMiddleware } from "../../types/middleware.js"; import type { RouteCacheOptions } from "../../types/app.js"; import type { VextRequest } from "../../types/request.js"; import type { VextInternalHooks } from "../../types/hooks.js"; import type { ResponseCache } from "response-cache-kit"; /** * 统一路由级 cache 配置 * * @param cache RouteOptions.cache 原始值 * @param globalDefaultTtl 全局默认 TTL(来自 config.cache.defaultTtl) * @returns 规范化的 RouteCacheOptions | null(null 表示不缓存) * * 规则: * - `undefined` → null(未配置,不缓存) * - `false` → null(显式禁用) * - `0` 或负值 → null(数字简写禁用) * - `number > 0` → { ttl: number }(数字简写) * - `{ ttl, ... }` → 原样返回(对象形式) */ export declare function normalizeCacheOptions(cache: false | number | RouteCacheOptions | undefined, globalDefaultTtl?: number): RouteCacheOptions | null; /** * 默认缓存 key 生成 * * 格式: `${method}:${path}[?${sortedQuery}][|${varyValues}]` * * 设计原则: * 1. method + path 天然区分不同路由和动态参数 * (req.path = '/users/42' 而非 '/users/:id') * 2. query 参数排序确保 ?a=1&b=2 ≡ ?b=2&a=1 * 3. vary headers 区分同路径不同语言/编码 * 4. 不含 auth/cookie → 安全默认 * * 示例: * GET /products → 'GET:/products' * GET /products?limit=10&page=2 → 'GET:/products?limit=10&page=2' * GET /products + zh-CN → 'GET:/products|accept-language=zh-CN' */ export declare function defaultCacheKey(req: VextRequest, vary?: string[] | "*"): string; /** * 构建路由级响应缓存中间件 * * @param cacheOpts 规范化后的缓存配置(null 时返回 null,不构建中间件) * @param getResponseCache 延迟获取 ResponseCache 实例(避免在路由注册时实例尚未就绪) * @returns VextMiddleware | null */ export declare function buildRouteCacheMiddleware(cacheOpts: RouteCacheOptions | null, getResponseCache: () => ResponseCache, hooks?: VextInternalHooks): VextMiddleware | null;