/** * Webhook runtime handler — the HTTP surface for inbound `webhook` declarations. * * A `webhook` in the IR (see docs/spec/ir/ir-v1.schema.json → IRWebhook) declares * an inbound HTTP endpoint that dispatches a command. Until this module, that IR * had no reference-runtime behavior outside the Convex projection: no signature * verification, no idempotency, no transform evaluation (2026-07-01 docs↔feature * reconciliation audit, "Webhook declarations produce no HTTP surface outside * Convex"). This is that behavior, and it is the executable contract the spec * (docs/spec/semantics.md § "Webhooks") and every projected webhook route bind to. * * Everything here is fail-closed: an under-configured or unauthenticated request * is rejected, never coerced into a success. The handler is transport-agnostic — * a projection adapts its framework's Request into {@link WebhookHttpRequest} and * turns {@link WebhookHttpResponse} back into a framework Response. * * Determinism: the handler performs no wall-clock reads. HMAC, JSON parsing, and * string comparison only; identical IR + context + request produce an identical * response (house-style determinism invariant). */ import type { RuntimeEngine } from '../runtime-engine'; import type { IRWebhook } from '../ir'; /** An inbound HTTP request, normalized from whatever framework served it. */ export interface WebhookHttpRequest { method: string; /** Path as received, e.g. `/webhooks/stripe`. Matched verbatim against the IR. */ path: string; headers: Record; /** Exact request bytes as a string. HMAC is computed over THIS, not a re-serialization. */ rawBody: string; query?: Record; } /** The handler's response. `body` is a `ManifestCommandResponse`-shaped object or `{ error }`. */ export interface WebhookHttpResponse { status: number; body: unknown; } export interface WebhookHandlerOptions { /** * Explicit secret resolution override. Called with the matched webhook; a * non-empty return value is used as the HMAC secret. When it returns * `undefined`/empty, the handler falls back to resolving the IR's context path * (`webhook.signature.secret`) against the engine's runtime context. If neither * yields a secret the request is rejected fail-closed (config error). */ resolveSecret?: (webhook: IRWebhook) => string | undefined; } /** * Handle one inbound webhook request against a runtime. * * Pipeline (each step fails closed): * 1. MATCH — exact `path`, then `method` (default POST, case-insensitive). * 2. VERIFY — HMAC signature when declared. * 3. DEDUPE — idempotency key when declared. * 4. PARSE — JSON body + transform expressions → command input. * 5. DISPATCH— runCommand, mapped to the shared command-response envelope. */ export declare function handleWebhookRequest(runtime: RuntimeEngine, request: WebhookHttpRequest, options?: WebhookHandlerOptions): Promise; //# sourceMappingURL=handler.d.ts.map