Skip to content

@lastshotlabs/slingshot-webhooks

npm install @lastshotlabs/slingshot-webhooks

In-memory WebhookAdapter with synchronous endpoint management helpers for testing.

function createMemoryWebhookAdapter(): MemoryWebhookAdapter

Source: packages/slingshot-webhooks/src/adapters/memory.ts

Pluggable encryptor for at-rest webhook endpoint secrets.

Apps can supply a custom implementation backed by KMS, HashiCorp Vault, or any other key manager. The default implementation built from createSecretCipher performs local AES-256-GCM with a base64 key, but the framework only depends on this interface so an external provider can be dropped in without touching the storage path.

Implementations should:

  • Return strings that round-trip through decrypt unchanged.
  • Tolerate values produced before encryption was enabled (the local implementation passes such values through and operators rotate by re-saving).

encrypt/decrypt may be sync or async; the runtime awaits both.

function createSecretCipher(keyB64: string | undefined | null): SecretCipher

Source: packages/slingshot-webhooks/src/lib/secretCipher.ts

In-memory sliding-window rate limiter for inbound webhook endpoints.

Each provider name is tracked independently with a configurable maximum number of requests within a rolling time window. Old entries are pruned on every check so memory does not grow unbounded under low-traffic conditions.

This limiter is per-process only. In multi-instance deployments, pair it with a distributed rate limiter (e.g. Redis-backed) — the RateLimiter interface is intentionally narrow so consumers can swap in a different backend without changing the route code.

function createSlidingWindowRateLimiter(options: Partial<SlidingWindowRateLimiterOptions> = {},): RateLimiter

Source: packages/slingshot-webhooks/src/lib/rateLimit.ts

Optional configuration for createWebhookMemoryQueue.

Remarks: All fields are optional — the queue uses safe defaults when omitted.

function createWebhookMemoryQueue(config?: MemoryQueueConfig): WebhookQueue

Source: packages/slingshot-webhooks/src/queues/memory.ts

Webhooks package factory.

Creates a SlingshotPackageDefinition that mounts the WebhookEndpoint and WebhookDelivery entities, wires the queue lifecycle, dispatches delivery jobs, supplies the /endpoints/:id/test and /admin/deliveries/:id/replay routes, and mounts the inbound webhook receiver router. Cross-package consumers resolve the runtime adapter via WebhooksAdapterCap.

Every adapter ref, queue handle, rate-limit backend, and inbound router closure is owned by the factory’s closure (Rule 3) — multiple package instances in the same process do not share state.

function createWebhooksPackage(rawConfig: WebhookPluginConfig): SlingshotPackageDefinition

Source: packages/slingshot-webhooks/src/plugin.ts

Optional configuration for createWebhookMemoryQueue.

Remarks: All fields are optional — the queue uses safe defaults when omitted.

async function replayWebhookDlq(storagePath: string, enqueueFn: (job: WebhookJob) => Promise<void>,): Promise<

Source: packages/slingshot-webhooks/src/queues/memory.ts

Helpers for implementing InboundProvider.verify() safely.

Inbound webhook bodies arrive as raw strings supplied by an external sender. A naive JSON.parse(rawBody) will throw a SyntaxError when the sender (whether buggy or malicious) posts a malformed payload, which would otherwise propagate up into the route handler and surface as a generic 500. safeParseInboundBody keeps that failure mode local to the provider so it can return { verified: false, reason } cleanly.

function safeParseInboundBody(rawBody: string): SafeParseInboundBodyResult

Source: packages/slingshot-webhooks/src/lib/inbound.ts

Signs a webhook payload using HMAC-SHA256 and returns a Stripe-style signature header value.

Signature format: t=<unix_timestamp>,v1=<hex_hmac> where the signed data is <ts>.<body>. This format is intentionally compatible with Stripe’s webhook signature scheme.

async function signPayload(secret: string, body: string, timestamp?: number,): Promise<string>

Source: packages/slingshot-webhooks/src/lib/signing.ts

Signs a webhook payload using HMAC-SHA256 and returns a Stripe-style signature header value.

Signature format: t=<unix_timestamp>,v1=<hex_hmac> where the signed data is <ts>.<body>. This format is intentionally compatible with Stripe’s webhook signature scheme.

async function verifySignature(secret: string, body: string, header: string, toleranceSeconds = 300,): Promise<boolean>

Source: packages/slingshot-webhooks/src/lib/signing.ts

Zod schema for validating WebhookPluginConfig.

FieldDescription
`/**
  • Advanced outbound dispatch overrides. Production traffic should normally
  • use the default safeFetch transport; tests can inject fetchImpl and a
  • deterministic resolver without weakening SSRF validation. / dispatch| Optional host resolver override for outbound delivery validation. | |/* Delivery queue implementation. Defaults to the in-process memory queue. / queue| In-memory webhook delivery queue (development only). | |/* Mount path for webhook routes. Default| URL path prefix for webhook routes. Omit to use '/webhooks'. | |/** Role required for webhook management routes. Default| Role required for webhook management routes. Omit to use 'admin'. | |each inbound provider (e.g. ‘stripe’, ‘github’) is rate-limited
  • independently using an in-memory sliding window counter. Requests that exceed
  • the limit receive HTTP 429 with Retry-After and X-RateLimit-* headers.
  • Provide a custom RateLimiter instance for distributed deployments (e.g. Redis
  • sliding window) or use the shorthand object form for the built-in per-process
  • limiter.
  • Omit entirely to disable inbound rate limiting (not recommended in production). */ inboundRateLimit| Custom RateLimiter instance (e.g. Redis-backed). | |in bytes. Default` | Maximum body size (bytes) accepted on inbound webhook routes. Defaults to 1 MiB. |

Source: packages/slingshot-webhooks/src/types/config.ts

Named constants for the two route groups mounted by the webhook plugin. Pass values to WebhookPluginConfig.disableRoutes to skip mounting specific route groups.

Source: packages/slingshot-webhooks/src/routes/index.ts

Public contract for slingshot-webhooks.

Cross-package consumers resolve WebhooksAdapterCap through ctx.capabilities.require(...) to send/manage outbound webhook deliveries through the unified adapter.

Source: packages/slingshot-webhooks/src/public.ts

Public contract for slingshot-webhooks.

Cross-package consumers resolve WebhooksAdapterCap through ctx.capabilities.require(...) to send/manage outbound webhook deliveries through the unified adapter.

Source: packages/slingshot-webhooks/src/public.ts

A single webhook delivery job tracked by the queue.

Contains all the data needed to execute one HTTP delivery attempt without additional database lookups. Exposed to queue processors and onDeadLetter callbacks.

Source: packages/slingshot-webhooks/src/types/queue.ts

A single webhook delivery job tracked by the queue.

Contains all the data needed to execute one HTTP delivery attempt without additional database lookups. Exposed to queue processors and onDeadLetter callbacks.

Source: packages/slingshot-webhooks/src/types/queue.ts

Interface for verifying and processing inbound webhook payloads from external services.

Each provider handles one external service (e.g. Stripe, GitHub). On receipt of a POST /webhooks/inbound/<provider> request, the plugin calls verify(). If verification passes, the payload is re-emitted as webhook:inbound.<provider> on the bus.

Implementers MUST handle malformed JSON. The rawBody is attacker-controlled, so a naive JSON.parse(rawBody) will throw on bad input and surface as an unhelpful 500. Use the safeParseInboundBody helper exported from this package, or wrap JSON.parse in your own try/catch and return { verified: false, reason } on failure.

Source: packages/slingshot-webhooks/src/types/inbound.ts

Optional configuration for createWebhookMemoryQueue.

Remarks: All fields are optional — the queue uses safe defaults when omitted.

Source: packages/slingshot-webhooks/src/queues/memory.ts

In-memory WebhookAdapter with synchronous endpoint management helpers for testing.

Source: packages/slingshot-webhooks/src/adapters/memory.ts

In-memory sliding-window rate limiter for inbound webhook endpoints.

Each provider name is tracked independently with a configurable maximum number of requests within a rolling time window. Old entries are pruned on every check so memory does not grow unbounded under low-traffic conditions.

This limiter is per-process only. In multi-instance deployments, pair it with a distributed rate limiter (e.g. Redis-backed) — the RateLimiter interface is intentionally narrow so consumers can swap in a different backend without changing the route code.

Source: packages/slingshot-webhooks/src/lib/rateLimit.ts

In-memory sliding-window rate limiter for inbound webhook endpoints.

Each provider name is tracked independently with a configurable maximum number of requests within a rolling time window. Old entries are pruned on every check so memory does not grow unbounded under low-traffic conditions.

This limiter is per-process only. In multi-instance deployments, pair it with a distributed rate limiter (e.g. Redis-backed) — the RateLimiter interface is intentionally narrow so consumers can swap in a different backend without changing the route code.

Source: packages/slingshot-webhooks/src/lib/rateLimit.ts

Pluggable encryptor for at-rest webhook endpoint secrets.

Apps can supply a custom implementation backed by KMS, HashiCorp Vault, or any other key manager. The default implementation built from createSecretCipher performs local AES-256-GCM with a base64 key, but the framework only depends on this interface so an external provider can be dropped in without touching the storage path.

Implementations should:

  • Return strings that round-trip through decrypt unchanged.
  • Tolerate values produced before encryption was enabled (the local implementation passes such values through and operators rotate by re-saving).

encrypt/decrypt may be sync or async; the runtime awaits both.

Source: packages/slingshot-webhooks/src/lib/secretCipher.ts

Pluggable encryptor for at-rest webhook endpoint secrets.

Apps can supply a custom implementation backed by KMS, HashiCorp Vault, or any other key manager. The default implementation built from createSecretCipher performs local AES-256-GCM with a base64 key, but the framework only depends on this interface so an external provider can be dropped in without touching the storage path.

Implementations should:

  • Return strings that round-trip through decrypt unchanged.
  • Tolerate values produced before encryption was enabled (the local implementation passes such values through and operators rotate by re-saving).

encrypt/decrypt may be sync or async; the runtime awaits both.

Source: packages/slingshot-webhooks/src/lib/secretCipher.ts

In-memory sliding-window rate limiter for inbound webhook endpoints.

Each provider name is tracked independently with a configurable maximum number of requests within a rolling time window. Old entries are pruned on every check so memory does not grow unbounded under low-traffic conditions.

This limiter is per-process only. In multi-instance deployments, pair it with a distributed rate limiter (e.g. Redis-backed) — the RateLimiter interface is intentionally narrow so consumers can swap in a different backend without changing the route code.

Source: packages/slingshot-webhooks/src/lib/rateLimit.ts

Runtime persistence contract used by webhook orchestration.

Source: packages/slingshot-webhooks/src/types/adapter.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

A single webhook delivery job tracked by the queue.

Contains all the data needed to execute one HTTP delivery attempt without additional database lookups. Exposed to queue processors and onDeadLetter callbacks.

Source: packages/slingshot-webhooks/src/types/queue.ts

A single webhook delivery job tracked by the queue.

Contains all the data needed to execute one HTTP delivery attempt without additional database lookups. Exposed to queue processors and onDeadLetter callbacks.

Source: packages/slingshot-webhooks/src/types/queue.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Helpers for implementing InboundProvider.verify() safely.

Inbound webhook bodies arrive as raw strings supplied by an external sender. A naive JSON.parse(rawBody) will throw a SyntaxError when the sender (whether buggy or malicious) posts a malformed payload, which would otherwise propagate up into the route handler and surface as a generic 500. safeParseInboundBody keeps that failure mode local to the provider so it can return { verified: false, reason } cleanly.

Source: packages/slingshot-webhooks/src/lib/inbound.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts

Zod schema for validating WebhookPluginConfig.

Source: packages/slingshot-webhooks/src/types/config.ts

Named constants for the two route groups mounted by the webhook plugin. Pass values to WebhookPluginConfig.disableRoutes to skip mounting specific route groups.

Source: packages/slingshot-webhooks/src/routes/index.ts

Zod schema for validating WebhookPluginConfig.

Source: packages/slingshot-webhooks/src/types/config.ts

Lifecycle status of a webhook delivery.

Source: packages/slingshot-webhooks/src/types/models.ts