UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

248 lines 7.95 kB
/** * @beignet/core/webhooks * * Provider-neutral inbound webhook primitives for Beignet applications. */ import type { StandardSchemaV1 } from "@standard-schema/spec"; /** * Raw webhook payload. Signature verification must use this unparsed body. */ export type WebhookRawBody = string | Uint8Array | ArrayBuffer; /** * Request headers normalized to lowercase keys. */ export type WebhookHeaders = Record<string, string | undefined>; /** * Input passed to webhook verifiers. */ export interface VerifyWebhookInput { rawBody: WebhookRawBody; headers?: WebhookHeaders; signature?: string; receivedAt?: Date; } /** * Provider-neutral inbound webhook event. */ export interface WebhookEvent<TPayload = unknown> { id: string; type: string; provider?: string; createdAt?: Date; payload: TPayload; raw?: unknown; metadata?: Record<string, unknown>; } /** * Verifies an inbound webhook and converts it into a provider-neutral event. */ export interface WebhookVerifier<TEvent extends WebhookEvent = WebhookEvent> { verify(input: VerifyWebhookInput): Promise<TEvent>; } /** * Standard Schema payload catalog keyed by provider event type. */ export type WebhookEventSchemas = Record<string, StandardSchemaV1>; /** * Infer the parsed output type from a Standard Schema. */ export type InferSchemaOutput<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>; /** * Infer a typed webhook event from an event catalog entry. */ export type WebhookEventForSchema<Events extends WebhookEventSchemas, Type extends keyof Events & string> = WebhookEvent<InferSchemaOutput<Events[Type]>> & { type: Type; }; /** * Infer any typed event from a webhook definition's event catalog. */ export type InferWebhookEvent<TWebhook> = TWebhook extends WebhookDef<string, infer Events> ? { [Type in keyof Events & string]: WebhookEventForSchema<Events, Type>; }[keyof Events & string] : WebhookEvent; /** * Provider-neutral webhook definition. */ export interface WebhookDef<Name extends string = string, Events extends WebhookEventSchemas = WebhookEventSchemas> { kind: "webhook"; name: Name; provider?: string; events: Events; verifier?: WebhookVerifier; metadata?: Record<string, unknown>; } /** * Options accepted by `defineWebhook(...)`. */ export interface DefineWebhookOptions<Events extends WebhookEventSchemas = WebhookEventSchemas> { provider?: string; events?: Events; verifier?: WebhookVerifier; metadata?: Record<string, unknown>; } /** * Options accepted by `verifyWebhook(...)`. */ export interface VerifyWebhookOptions<AllowUnknownEvents extends boolean = boolean> { verifier?: WebhookVerifier; allowUnknownEvents?: AllowUnknownEvents; } type InferWebhookVerificationResult<TWebhook extends WebhookDef<string, WebhookEventSchemas>, AllowUnknownEvents extends boolean> = true extends AllowUnknownEvents ? InferWebhookEvent<TWebhook> | WebhookEvent : InferWebhookEvent<TWebhook>; /** * Timestamp formats accepted by the generic HMAC webhook verifier. */ export type HmacWebhookTimestampFormat = "unix-seconds" | "unix-milliseconds" | "iso8601"; /** * Timestamp source and tolerance for generic HMAC replay protection. */ export type HmacWebhookTimestampOptions = { /** * Header that carries the provider event timestamp. Header timestamps * are authenticated as `<timestamp>.<rawBody>`. */ header: string; payloadPath?: never; /** * Timestamp format. * * @default "unix-seconds" */ format?: HmacWebhookTimestampFormat; /** * Maximum absolute clock skew between the event timestamp and receipt. * * @default 300 */ toleranceSec?: number; } | { header?: never; /** * Dot path used to read the provider event timestamp from the JSON * payload. */ payloadPath: string; /** * Timestamp format. * * @default "unix-seconds" */ format?: HmacWebhookTimestampFormat; /** * Maximum absolute clock skew between the event timestamp and receipt. * * @default 300 */ toleranceSec?: number; }; /** * Options for the in-memory webhook verifier. */ export interface CreateMemoryWebhookVerifierOptions { events?: readonly WebhookEvent[]; } /** * In-memory verifier exposed for tests. */ export interface MemoryWebhookVerifier extends WebhookVerifier { readonly verifiedEvents: readonly WebhookEvent[]; queue(event: WebhookEvent): void; reset(): void; } /** * Options for the generic HMAC webhook verifier. */ export interface CreateHmacWebhookVerifierOptions { secret: string; /** * Header that carries the provider signature. * * @default "x-webhook-signature" */ signatureHeader?: string; /** * Web Crypto HMAC hash algorithm. * * @default "SHA-256" */ algorithm?: "SHA-256" | "SHA-384" | "SHA-512"; /** * Optional signature prefix, such as "sha256=". */ signaturePrefix?: string; /** * Provider name attached to verified events. */ provider?: string; /** * Dot path used to read the event ID from a JSON payload. * * @default "id" */ eventIdPath?: string; /** * Dot path used to read the event type from a JSON payload. * * @default "type" */ eventTypePath?: string; /** * Optional timestamp source used to reject replayed generic HMAC webhooks. */ timestamp?: HmacWebhookTimestampOptions; } /** * Error thrown for invalid webhook definitions and inputs. */ export declare class WebhookOptionsError extends Error { constructor(message: string); } /** * Error thrown when verification fails. */ export declare class WebhookVerificationError extends Error { readonly webhookName?: string; readonly provider?: string; readonly code: string; readonly cause?: unknown; constructor(args: { message: string; webhookName?: string; provider?: string; code: string; cause?: unknown; }); } /** * Error thrown when a verified event fails payload validation. */ export declare class WebhookValidationError extends Error { readonly webhookName: string; readonly eventType: string; readonly issues: readonly StandardSchemaV1.Issue[]; constructor(args: { webhookName: string; eventType: string; issues: readonly StandardSchemaV1.Issue[]; }); } /** * Define a typed inbound webhook surface. */ export declare function defineWebhook<Name extends string, Events extends WebhookEventSchemas = WebhookEventSchemas>(name: Name, options?: DefineWebhookOptions<Events>): WebhookDef<Name, Events>; /** * Verify a raw webhook request and validate the matching event payload schema. */ export declare function verifyWebhook<TWebhook extends WebhookDef<string, WebhookEventSchemas>, AllowUnknownEvents extends boolean = false>(webhook: TWebhook, input: VerifyWebhookInput, options?: VerifyWebhookOptions<AllowUnknownEvents>): Promise<InferWebhookVerificationResult<TWebhook, AllowUnknownEvents>>; /** * Validate a verified webhook event against its catalog entry. */ export declare function parseWebhookEvent<TWebhook extends WebhookDef<string, WebhookEventSchemas>, AllowUnknownEvents extends boolean = false>(webhook: TWebhook, event: WebhookEvent, options?: Pick<VerifyWebhookOptions<AllowUnknownEvents>, "allowUnknownEvents">): Promise<InferWebhookVerificationResult<TWebhook, AllowUnknownEvents>>; /** * Create an in-memory verifier for tests. */ export declare function createMemoryWebhookVerifier(options?: CreateMemoryWebhookVerifierOptions): MemoryWebhookVerifier; /** * Create a generic JSON + HMAC verifier. */ export declare function createHmacWebhookVerifier(options: CreateHmacWebhookVerifierOptions): WebhookVerifier; export {}; //# sourceMappingURL=index.d.ts.map