Files
skills/docs/api-stack/api/api-plugin-webhook/src/plugin/plugin.md
2026-05-29 08:20:56 +01:00

3.2 KiB

plugin.ts — createWebhookPlugin factory

(no submodules)

Purpose

Top-level definePlugin consumer for the webhook plugin. Returns a typed PluginDescriptor<WebhookPluginConfig> whose onInit executes the canonical five-step lifecycle: resolve app / openAPIRegistry from the host ServiceRegistry, construct the WebhookService wired to the configured (or default) collaborators, register the service under the webhookService slot, mount the six CRUD + test routes under routePrefix (gated by requireAuth()), and register the routes with the OpenAPIRegistry when one is present so /openapi.json exposes them.

Features

  • Zod-validates options at the factory boundary; invalid input raises WebhookError(WEBHOOK_INVALID_INPUT) carrying the ZodError as cause.
  • Wires defaults for every optional collaborator (MemoryEndpointStore, MemoryDeadLetterSink, system clock, global fetch, noop logger) so createWebhookPlugin() works zero-config.
  • Raises WebhookError(WEBHOOK_SERVICE_NOT_AVAILABLE) if the required app slot is absent.
  • Raises WebhookError(WEBHOOK_ROUTE_PREFIX_COLLISION) when the routePrefix collides with previously-registered routes.
  • Falls back to a manual Hono sub-router mount when no OpenAPIRegistry is present so the runtime surface still works even when the OpenAPI doc is not assembled.

Usage: Basic

import { defineApp } from "@suaveplan/api";
import { createWebhookPlugin } from "@suaveplan/api-plugin-webhook";

const app = defineApp().use(createWebhookPlugin());

Usage: Advanced

import { defineApp } from "@suaveplan/api";
import { createAuthPlugin } from "@suaveplan/api-plugin-auth";
import { createWebhookPlugin } from "@suaveplan/api-plugin-webhook";
import { MemoryEndpointStore } from "@suaveplan/api-plugin-webhook/store/memory";
import { MemoryDeadLetterSink } from "@suaveplan/api-plugin-webhook/dead-letter/memory";

const app = defineApp()
    .use(createAuthPlugin({ betterAuth: {} }))
    .use(
        createWebhookPlugin({
            routePrefix: "/api/v1/webhooks",
            endpointStore: new MemoryEndpointStore(),
            deadLetterSink: new MemoryDeadLetterSink(),
            maxAttempts: 8,
            initialRetryDelayMs: 250,
            maxRetryDelayMs: 60_000,
        })
    );

API Reference

  • createWebhookPlugin(options?) — factory. Returns a PluginDescriptor<WebhookPluginConfig>.
  • WebhookPluginOptions — every field optional; defaults supplied for omitted fields.
  • WebhookPluginConfig — post-default-merge shape carried on the descriptor's defaults.

Implementation Notes

The plugin name webhook is singular (not webhooks) so dependent plugins reference one stable identifier when declaring dependencies: ["webhook"]. The lifecycle is one-shot — there is no onClose hook because the service does not hold network resources (the in-flight dedup map drains naturally as deliveries resolve). The route mount path joins routePrefix + entry path so the generated OpenAPI paths read as /webhooks, /webhooks/{id}, /webhooks/{id}/test; the special-case routePrefix === "/" keeps the root namespace clean for apps that want webhook CRUD at the top level.