@beignet/core
Version:
Core framework primitives for Beignet
248 lines • 7.95 kB
TypeScript
/**
* @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