import type { Context } from "hono"; import type { VextResponse } from "../../types/response.js"; /** * 共享 Response 容器 * * Hono 的 route handler 必须返回 Response 对象。 * 但 vext 的中间件链通过 VextResponse 的方法(json/text/...)间接调用 Hono 的 API。 * 这些 API(c.json / c.body / c.text / c.redirect)都返回 Response 对象。 * * 通过 ResponseBox 容器,VextResponse 的每个发送方法将 Hono 返回的 Response * 存储到 box.value 中,adapter 的 route handler 随后通过 box.value 获取最终 Response * 返回给 Hono。 * * 如果中间件链执行完毕后 box.value 仍为 null,说明 handler 没有调用任何发送方法, * adapter 将返回一个空的 204 Response 作为兜底。 */ export interface ResponseBox { value: Response | null; } /** * 创建 ResponseBox 容器 * * 由 adapter 的 registerRoute / registerNotFound 中调用, * 传给 createVextResponse,并在 handler 返回后读取 box.value。 */ export declare function createResponseBox(): ResponseBox; /** * HonoContext → VextResponse 转换 * * 核心设计(P0-1 修复): * * 1. 延迟绑定 requestId(getRequestId getter) * requestId 在 createVextResponse 调用时尚未生成(requestId 中间件还没执行), * 传入 getter 函数确保 json() 实际调用时才取值(此时 requestId 必然已由中间件生成)。 * * 2. 内建出口包装(_wrapEnabled 标志) * response-wrapper 中间件通过 _enableWrap() 开启包装标志。 * json() 根据标志决定是否将响应体包装为 { code: 0, data, requestId }。 * rawJson() 始终绕过包装——仅供框架内部错误处理使用。 * * 3. 重复发送保护(_sent 标志) * 防止 handler 中误调用多次 res.json(),dev 模式打印警告,生产模式静默忽略。 * * 4. 链式调用(status / setHeader 返回 this) * res.status(201).json(data) 正确设置 HTTP 201。 * * 5. 204 No Content 合规(RFC 9110 §15.3.5) * 无论包装是否开启,204 均发送无消息体的响应。 * * 6. Response 捕获(ResponseBox) * 每个发送方法将 Hono 返回的 Response 存储到 box.value 中, * adapter handler 通过 box.value 将 Response 返回给 Hono。 * * 时序保证: * createVextResponse(c, () => req.requestId, box) * ↓ executeChain 开始 * [requestIdMiddleware] → req.requestId = 'a1b2c3d4...' * [responseWrapperMiddleware] → res._enableWrap() * ↓ * [handler] res.status(201).json(data) * → _wrapEnabled = true * → getRequestId() → 'a1b2c3d4...'(已设置) * → c.json(...) 返回 Response,存入 box.value * → HTTP 201 ✅ * * @param c Hono Context 对象 * @param getRequestId 延迟获取 requestId 的 getter 函数 * @param box Response 捕获容器 * @returns VextResponse 实例(含内部方法 _enableWrap) */ export declare function createVextResponse(c: Context, getRequestId: () => string, box: ResponseBox): VextResponse;