@happyvertical/smrt-webhooks 0.55.20 → 0.55.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { GlobalInterceptors, ObjectRegistry, SmrtRecipe, getChangesSince } from
4
4
  import { requireTenant } from "@happyvertical/smrt-tenancy";
5
5
  import { randomUUID } from "node:crypto";
6
6
  //#region src/__smrt-register__.ts
7
- ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-webhooks","packageVersion":"0.55.20","objects":{"@happyvertical/smrt-webhooks:WebhookSubscription":{"name":"webhooksubscription","className":"WebhookSubscription","qualifiedName":"@happyvertical/smrt-webhooks:WebhookSubscription","collection":"webhooksubscriptions","description":"Server-only subscription. Hosts authorize administration before accessing it.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"url":{"type":"text","required":true,"_meta":{"required":true}},"events":{"type":"json","required":false,"_meta":{}},"models":{"type":"json","required":false,"_meta":{}},"secret":{"type":"text","required":true,"_meta":{"sensitive":true,"required":true},"sensitive":true},"enabled":{"type":"boolean","required":false,"default":true,"_meta":{"default":true}}},"methods":{"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_webhook_subscriptions","api":false,"cli":false,"mcp":false,"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"WebhookSubscription","collectionExportName":"WebhookSubscriptionCollection","validationRules":[{"field":"url","rule":"required","fieldType":"text"},{"field":"secret","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_webhook_subscriptions","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_subscriptions\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"url\\" TEXT NOT NULL,\\n \\"events\\" JSON,\\n \\"models\\" JSON,\\n \\"secret\\" TEXT NOT NULL,\\n \\"enabled\\" BOOLEAN DEFAULT TRUE\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"url":{"type":"TEXT","notNull":true,"unique":false},"events":{"type":"JSON","notNull":false,"unique":false},"models":{"type":"JSON","notNull":false,"unique":false},"secret":{"type":"TEXT","notNull":true,"unique":false},"enabled":{"type":"BOOLEAN","notNull":false,"unique":false,"default":true}},"indexes":[{"name":"_smrt_webhook_subscriptions_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_subscriptions_tenant_id_created_at_idx","columns":["tenant_id","created_at"]}],"version":"4e9ebebe"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection":{"name":"webhooksubscriptioncollection","className":"WebhookSubscriptionCollection","qualifiedName":"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection","collection":"webhooksubscriptions","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_subscriptions","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"WebhookSubscription","exportName":"WebhookSubscriptionCollection","collectionExportName":"WebhookSubscriptionCollectionCollection","schema":{"tableName":"_smrt_webhook_subscriptions","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_subscriptions\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"url\\" TEXT NOT NULL,\\n \\"events\\" JSON,\\n \\"models\\" JSON,\\n \\"secret\\" TEXT NOT NULL,\\n \\"enabled\\" BOOLEAN DEFAULT TRUE\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"url":{"type":"TEXT","notNull":true,"unique":false},"events":{"type":"JSON","notNull":false,"unique":false},"models":{"type":"JSON","notNull":false,"unique":false},"secret":{"type":"TEXT","notNull":true,"unique":false},"enabled":{"type":"BOOLEAN","notNull":false,"unique":false,"default":true}},"indexes":[{"name":"_smrt_webhook_subscriptions_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_subscriptions_tenant_id_created_at_idx","columns":["tenant_id","created_at"]}],"version":"4e9ebebe"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookDelivery":{"name":"webhookdelivery","className":"WebhookDelivery","qualifiedName":"@happyvertical/smrt-webhooks:WebhookDelivery","collection":"webhookdeliveries","description":"Durable outbox and safe outcome metadata; payload never appears in public projections.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"subscriptionId":{"type":"foreignKey","required":false,"related":"WebhookSubscription","_meta":{"onDelete":"RESTRICT","onUpdate":"RESTRICT"}},"eventId":{"type":"text","required":true,"_meta":{"required":true}},"payload":{"type":"text","required":true,"_meta":{"required":true,"sensitive":true},"sensitive":true},"status":{"type":"text","required":false,"default":"pending","_meta":{"default":"pending"}},"generation":{"type":"integer","required":false,"default":0,"_meta":{"default":0}},"attempts":{"type":"integer","required":false,"default":0,"_meta":{"default":0}},"responseStatus":{"type":"integer","required":false,"_meta":{"nullable":true}},"error":{"type":"text","required":false,"_meta":{"nullable":true}},"leaseToken":{"type":"text","required":false,"_meta":{"nullable":true,"sensitive":true},"sensitive":true},"leaseUntil":{"type":"datetime","required":false,"_meta":{"nullable":true}}},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_deliveries","api":false,"cli":false,"mcp":false,"indexes":[{"name":"_smrt_webhook_delivery_identity","columns":["tenantId","subscriptionId","eventId"],"unique":true}],"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"WebhookDelivery","collectionExportName":"WebhookDeliveryCollection","validationRules":[{"field":"eventId","rule":"required","fieldType":"text"},{"field":"payload","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_webhook_deliveries","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_deliveries\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"subscription_id\\" UUID,\\n \\"event_id\\" TEXT NOT NULL,\\n \\"payload\\" TEXT NOT NULL,\\n \\"status\\" TEXT DEFAULT 'pending',\\n \\"generation\\" INTEGER DEFAULT 0,\\n \\"attempts\\" INTEGER DEFAULT 0,\\n \\"response_status\\" INTEGER,\\n \\"error\\" TEXT,\\n \\"lease_token\\" TEXT,\\n \\"lease_until\\" TIMESTAMP\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"subscription_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"_smrt_webhook_subscriptions","column":"id","onDelete":"RESTRICT","onUpdate":"RESTRICT"}},"event_id":{"type":"TEXT","notNull":true,"unique":false},"payload":{"type":"TEXT","notNull":true,"unique":false},"status":{"type":"TEXT","notNull":false,"unique":false,"default":"pending"},"generation":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"attempts":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"response_status":{"type":"INTEGER","notNull":false,"unique":false},"error":{"type":"TEXT","notNull":false,"unique":false},"lease_token":{"type":"TEXT","notNull":false,"unique":false},"lease_until":{"type":"TIMESTAMP","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_webhook_deliveries_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_delivery_identity","columns":["tenant_id","subscription_id","event_id"],"unique":true},{"name":"_smrt_webhook_deliveries_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"_smrt_webhook_deliveries_subscription_id_idx","columns":["subscription_id"]}],"version":"17d7bd27"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookDeliveryCollection":{"name":"webhookdeliverycollection","className":"WebhookDeliveryCollection","qualifiedName":"@happyvertical/smrt-webhooks:WebhookDeliveryCollection","collection":"webhookdeliveries","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_deliveries","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"WebhookDelivery","exportName":"WebhookDeliveryCollection","collectionExportName":"WebhookDeliveryCollectionCollection","schema":{"tableName":"_smrt_webhook_deliveries","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_deliveries\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"subscription_id\\" UUID,\\n \\"event_id\\" TEXT NOT NULL,\\n \\"payload\\" TEXT NOT NULL,\\n \\"status\\" TEXT DEFAULT 'pending',\\n \\"generation\\" INTEGER DEFAULT 0,\\n \\"attempts\\" INTEGER DEFAULT 0,\\n \\"response_status\\" INTEGER,\\n \\"error\\" TEXT,\\n \\"lease_token\\" TEXT,\\n \\"lease_until\\" TIMESTAMP\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"subscription_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"_smrt_webhook_subscriptions","column":"id","onDelete":"RESTRICT","onUpdate":"RESTRICT"}},"event_id":{"type":"TEXT","notNull":true,"unique":false},"payload":{"type":"TEXT","notNull":true,"unique":false},"status":{"type":"TEXT","notNull":false,"unique":false,"default":"pending"},"generation":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"attempts":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"response_status":{"type":"INTEGER","notNull":false,"unique":false},"error":{"type":"TEXT","notNull":false,"unique":false},"lease_token":{"type":"TEXT","notNull":false,"unique":false},"lease_until":{"type":"TIMESTAMP","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_webhook_deliveries_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_delivery_identity","columns":["tenant_id","subscription_id","event_id"],"unique":true},{"name":"_smrt_webhook_deliveries_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"_smrt_webhook_deliveries_subscription_id_idx","columns":["subscription_id"]}],"version":"17d7bd27"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookDeliveryTask":{"name":"webhookdeliverytask","className":"WebhookDeliveryTask","qualifiedName":"@happyvertical/smrt-webhooks:WebhookDeliveryTask","collection":"webhookdeliverytasks","description":"Jobs queue entry point; persisted arguments contain IDs only.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{},"methods":{"deliver":{"name":"deliver","async":true,"parameters":[{"name":"args","type":"Record<string, unknown>","optional":true},{"name":"_context","type":"JobExecutionContext","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_webhook_delivery_tasks","api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"WebhookDeliveryTask","collectionExportName":"WebhookDeliveryTaskCollection","schema":{"tableName":"_smrt_webhook_delivery_tasks","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_delivery_tasks\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"}},"indexes":[{"name":"_smrt_webhook_delivery_tasks_slug_context_idx","columns":["slug","context"],"unique":true},{"name":"_smrt_webhook_delivery_tasks_created_at_idx","columns":["created_at"]}],"version":"17ba7c43"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookCursor":{"name":"webhookcursor","className":"WebhookCursor","qualifiedName":"@happyvertical/smrt-webhooks:WebhookCursor","collection":"webhookcursors","description":"Tenant-bound durable cursor for replayable model change-feed publication.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"runtime":{"type":"text","required":true,"_meta":{"required":true}},"position":{"type":"integer","required":false,"default":0,"_meta":{"default":0}}},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_cursors","api":false,"cli":false,"mcp":false,"indexes":[{"name":"_smrt_webhook_cursor_identity","columns":["tenantId","runtime"],"unique":true}],"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"WebhookCursor","collectionExportName":"WebhookCursorCollection","validationRules":[{"field":"runtime","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_webhook_cursors","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_cursors\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"runtime\\" TEXT NOT NULL,\\n \\"position\\" INTEGER DEFAULT 0\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"runtime":{"type":"TEXT","notNull":true,"unique":false},"position":{"type":"INTEGER","notNull":false,"unique":false,"default":0}},"indexes":[{"name":"_smrt_webhook_cursors_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_cursor_identity","columns":["tenant_id","runtime"],"unique":true},{"name":"_smrt_webhook_cursors_tenant_id_created_at_idx","columns":["tenant_id","created_at"]}],"version":"ba1ea19d"},"importPath":"@happyvertical/smrt-webhooks"}},"moduleType":"smrt","recipes":[{"id":"integrations.webhooks","className":"WebhooksRecipe","label":"Outbound webhooks","summary":"Deliver signed model events and inspect delivery attempts from a server.","synonyms":[],"models":["@happyvertical/smrt-webhooks:WebhookSubscription","@happyvertical/smrt-webhooks:WebhookDelivery","@happyvertical/smrt-webhooks:WebhookDeliveryTask","@happyvertical/smrt-webhooks:WebhookCursor"],"nav":[],"requires":[],"group":{"id":"integrations","label":"Integrations","summary":"Connect your application to external services."},"help":{"markdown":"## Overview\\n\\nSend signed event notifications to an external HTTPS endpoint. Administrators\\ncan pause subscriptions and inspect delivery attempts. This integration requires\\na server and a running background worker.\\n\\n## Tasks\\n\\n- Add a subscription with a public HTTPS endpoint, signing secret, and event/model filters.\\n- Disable a subscription to cancel unsent deliveries.\\n- Inspect the delivery log, then retry failed deliveries after correcting their endpoint.\\n- Ask the endpoint owner to verify signatures and deduplicate delivery IDs.\\n","fieldRefs":[]},"surfaces":[{"kind":"settings-panel","export":"@happyvertical/smrt-webhooks/svelte#WebhookAdmin","label":"Outbound webhooks"}],"runtime":"server","demo":{"mode":"server","reasons":["The recipe declares runtime \\"server\\".","Needs a server because its package does not build for a browser: Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.; and its package depends on @happyvertical/smrt-jobs, @happyvertical/smrt-tenancy, which do not build for a browser (#3615, #3624, #3627, #3717)."]}}],"smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-jobs","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3615","#3624","#3627","#3717"],"reason":"Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.","via":["@happyvertical/smrt-jobs","@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
7
+ ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-webhooks","packageVersion":"0.55.21","objects":{"@happyvertical/smrt-webhooks:WebhookSubscription":{"name":"webhooksubscription","className":"WebhookSubscription","qualifiedName":"@happyvertical/smrt-webhooks:WebhookSubscription","collection":"webhooksubscriptions","description":"Server-only subscription. Hosts authorize administration before accessing it.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"url":{"type":"text","required":true,"_meta":{"required":true}},"events":{"type":"json","required":false,"_meta":{}},"models":{"type":"json","required":false,"_meta":{}},"secret":{"type":"text","required":true,"_meta":{"sensitive":true,"required":true},"sensitive":true},"enabled":{"type":"boolean","required":false,"default":true,"_meta":{"default":true}}},"methods":{"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_webhook_subscriptions","api":false,"cli":false,"mcp":false,"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"WebhookSubscription","collectionExportName":"WebhookSubscriptionCollection","validationRules":[{"field":"url","rule":"required","fieldType":"text"},{"field":"secret","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_webhook_subscriptions","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_subscriptions\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"url\\" TEXT NOT NULL,\\n \\"events\\" JSON,\\n \\"models\\" JSON,\\n \\"secret\\" TEXT NOT NULL,\\n \\"enabled\\" BOOLEAN DEFAULT TRUE\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"url":{"type":"TEXT","notNull":true,"unique":false},"events":{"type":"JSON","notNull":false,"unique":false},"models":{"type":"JSON","notNull":false,"unique":false},"secret":{"type":"TEXT","notNull":true,"unique":false},"enabled":{"type":"BOOLEAN","notNull":false,"unique":false,"default":true}},"indexes":[{"name":"_smrt_webhook_subscriptions_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_subscriptions_tenant_id_created_at_idx","columns":["tenant_id","created_at"]}],"version":"4e9ebebe"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection":{"name":"webhooksubscriptioncollection","className":"WebhookSubscriptionCollection","qualifiedName":"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection","collection":"webhooksubscriptions","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_subscriptions","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"WebhookSubscription","exportName":"WebhookSubscriptionCollection","collectionExportName":"WebhookSubscriptionCollectionCollection","schema":{"tableName":"_smrt_webhook_subscriptions","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_subscriptions\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"url\\" TEXT NOT NULL,\\n \\"events\\" JSON,\\n \\"models\\" JSON,\\n \\"secret\\" TEXT NOT NULL,\\n \\"enabled\\" BOOLEAN DEFAULT TRUE\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"url":{"type":"TEXT","notNull":true,"unique":false},"events":{"type":"JSON","notNull":false,"unique":false},"models":{"type":"JSON","notNull":false,"unique":false},"secret":{"type":"TEXT","notNull":true,"unique":false},"enabled":{"type":"BOOLEAN","notNull":false,"unique":false,"default":true}},"indexes":[{"name":"_smrt_webhook_subscriptions_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_subscriptions_tenant_id_created_at_idx","columns":["tenant_id","created_at"]}],"version":"4e9ebebe"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookDelivery":{"name":"webhookdelivery","className":"WebhookDelivery","qualifiedName":"@happyvertical/smrt-webhooks:WebhookDelivery","collection":"webhookdeliveries","description":"Durable outbox and safe outcome metadata; payload never appears in public projections.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"subscriptionId":{"type":"foreignKey","required":false,"related":"WebhookSubscription","_meta":{"onDelete":"RESTRICT","onUpdate":"RESTRICT"}},"eventId":{"type":"text","required":true,"_meta":{"required":true}},"payload":{"type":"text","required":true,"_meta":{"required":true,"sensitive":true},"sensitive":true},"status":{"type":"text","required":false,"default":"pending","_meta":{"default":"pending"}},"generation":{"type":"integer","required":false,"default":0,"_meta":{"default":0}},"attempts":{"type":"integer","required":false,"default":0,"_meta":{"default":0}},"responseStatus":{"type":"integer","required":false,"_meta":{"nullable":true}},"error":{"type":"text","required":false,"_meta":{"nullable":true}},"leaseToken":{"type":"text","required":false,"_meta":{"nullable":true,"sensitive":true},"sensitive":true},"leaseUntil":{"type":"datetime","required":false,"_meta":{"nullable":true}}},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_deliveries","api":false,"cli":false,"mcp":false,"indexes":[{"name":"_smrt_webhook_delivery_identity","columns":["tenantId","subscriptionId","eventId"],"unique":true}],"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"WebhookDelivery","collectionExportName":"WebhookDeliveryCollection","validationRules":[{"field":"eventId","rule":"required","fieldType":"text"},{"field":"payload","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_webhook_deliveries","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_deliveries\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"subscription_id\\" UUID,\\n \\"event_id\\" TEXT NOT NULL,\\n \\"payload\\" TEXT NOT NULL,\\n \\"status\\" TEXT DEFAULT 'pending',\\n \\"generation\\" INTEGER DEFAULT 0,\\n \\"attempts\\" INTEGER DEFAULT 0,\\n \\"response_status\\" INTEGER,\\n \\"error\\" TEXT,\\n \\"lease_token\\" TEXT,\\n \\"lease_until\\" TIMESTAMP\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"subscription_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"_smrt_webhook_subscriptions","column":"id","onDelete":"RESTRICT","onUpdate":"RESTRICT"}},"event_id":{"type":"TEXT","notNull":true,"unique":false},"payload":{"type":"TEXT","notNull":true,"unique":false},"status":{"type":"TEXT","notNull":false,"unique":false,"default":"pending"},"generation":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"attempts":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"response_status":{"type":"INTEGER","notNull":false,"unique":false},"error":{"type":"TEXT","notNull":false,"unique":false},"lease_token":{"type":"TEXT","notNull":false,"unique":false},"lease_until":{"type":"TIMESTAMP","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_webhook_deliveries_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_delivery_identity","columns":["tenant_id","subscription_id","event_id"],"unique":true},{"name":"_smrt_webhook_deliveries_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"_smrt_webhook_deliveries_subscription_id_idx","columns":["subscription_id"]}],"version":"17d7bd27"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookDeliveryCollection":{"name":"webhookdeliverycollection","className":"WebhookDeliveryCollection","qualifiedName":"@happyvertical/smrt-webhooks:WebhookDeliveryCollection","collection":"webhookdeliveries","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_deliveries","api":false,"mcp":false,"cli":false},"extends":"SmrtCollection","extendsTypeArg":"WebhookDelivery","exportName":"WebhookDeliveryCollection","collectionExportName":"WebhookDeliveryCollectionCollection","schema":{"tableName":"_smrt_webhook_deliveries","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_deliveries\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"subscription_id\\" UUID,\\n \\"event_id\\" TEXT NOT NULL,\\n \\"payload\\" TEXT NOT NULL,\\n \\"status\\" TEXT DEFAULT 'pending',\\n \\"generation\\" INTEGER DEFAULT 0,\\n \\"attempts\\" INTEGER DEFAULT 0,\\n \\"response_status\\" INTEGER,\\n \\"error\\" TEXT,\\n \\"lease_token\\" TEXT,\\n \\"lease_until\\" TIMESTAMP\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"subscription_id":{"type":"UUID","referenceKind":"foreignKey","notNull":false,"unique":false,"foreignKey":{"table":"_smrt_webhook_subscriptions","column":"id","onDelete":"RESTRICT","onUpdate":"RESTRICT"}},"event_id":{"type":"TEXT","notNull":true,"unique":false},"payload":{"type":"TEXT","notNull":true,"unique":false},"status":{"type":"TEXT","notNull":false,"unique":false,"default":"pending"},"generation":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"attempts":{"type":"INTEGER","notNull":false,"unique":false,"default":0},"response_status":{"type":"INTEGER","notNull":false,"unique":false},"error":{"type":"TEXT","notNull":false,"unique":false},"lease_token":{"type":"TEXT","notNull":false,"unique":false},"lease_until":{"type":"TIMESTAMP","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_webhook_deliveries_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_delivery_identity","columns":["tenant_id","subscription_id","event_id"],"unique":true},{"name":"_smrt_webhook_deliveries_tenant_id_created_at_idx","columns":["tenant_id","created_at"]},{"name":"_smrt_webhook_deliveries_subscription_id_idx","columns":["subscription_id"]}],"version":"17d7bd27"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookDeliveryTask":{"name":"webhookdeliverytask","className":"WebhookDeliveryTask","qualifiedName":"@happyvertical/smrt-webhooks:WebhookDeliveryTask","collection":"webhookdeliverytasks","description":"Jobs queue entry point; persisted arguments contain IDs only.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{},"methods":{"deliver":{"name":"deliver","async":true,"parameters":[{"name":"args","type":"Record<string, unknown>","optional":true},{"name":"_context","type":"JobExecutionContext","optional":true}],"returnType":"Promise<void>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_webhook_delivery_tasks","api":false,"cli":false,"mcp":false},"extends":"SmrtObject","exportName":"WebhookDeliveryTask","collectionExportName":"WebhookDeliveryTaskCollection","schema":{"tableName":"_smrt_webhook_delivery_tasks","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_delivery_tasks\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"}},"indexes":[{"name":"_smrt_webhook_delivery_tasks_slug_context_idx","columns":["slug","context"],"unique":true},{"name":"_smrt_webhook_delivery_tasks_created_at_idx","columns":["created_at"]}],"version":"17ba7c43"},"importPath":"@happyvertical/smrt-webhooks"},"@happyvertical/smrt-webhooks:WebhookCursor":{"name":"webhookcursor","className":"WebhookCursor","qualifiedName":"@happyvertical/smrt-webhooks:WebhookCursor","collection":"webhookcursors","description":"Tenant-bound durable cursor for replayable model change-feed publication.","filePath":"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts","packageName":"@happyvertical/smrt-webhooks","fields":{"tenantId":{"type":"text","required":true,"_meta":{"sqlType":"UUID","__tenancy":{"isTenantIdField":true,"autoFilter":true,"required":true,"autoPopulate":true,"nullable":false,"mode":"required","field":"tenantId","allowSuperAdminBypass":false}}},"runtime":{"type":"text","required":true,"_meta":{"required":true}},"position":{"type":"integer","required":false,"default":0,"_meta":{"default":0}}},"methods":{},"decoratorConfig":{"tableName":"_smrt_webhook_cursors","api":false,"cli":false,"mcp":false,"indexes":[{"name":"_smrt_webhook_cursor_identity","columns":["tenantId","runtime"],"unique":true}],"tenantScoped":{"mode":"required"},"conflictColumns":["tenant_id","slug","context"]},"extends":"SmrtObject","exportName":"WebhookCursor","collectionExportName":"WebhookCursorCollection","validationRules":[{"field":"runtime","rule":"required","fieldType":"text"}],"schema":{"tableName":"_smrt_webhook_cursors","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_webhook_cursors\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"tenant_id\\" UUID NOT NULL,\\n \\"runtime\\" TEXT NOT NULL,\\n \\"position\\" INTEGER DEFAULT 0\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"tenant_id":{"type":"UUID","referenceKind":"tenantId","notNull":true,"unique":false},"runtime":{"type":"TEXT","notNull":true,"unique":false},"position":{"type":"INTEGER","notNull":false,"unique":false,"default":0}},"indexes":[{"name":"_smrt_webhook_cursors_slug_context_idx","columns":["tenant_id","slug","context"],"unique":true},{"name":"_smrt_webhook_cursor_identity","columns":["tenant_id","runtime"],"unique":true},{"name":"_smrt_webhook_cursors_tenant_id_created_at_idx","columns":["tenant_id","created_at"]}],"version":"ba1ea19d"},"importPath":"@happyvertical/smrt-webhooks"}},"moduleType":"smrt","recipes":[{"id":"integrations.webhooks","className":"WebhooksRecipe","label":"Outbound webhooks","summary":"Deliver signed model events and inspect delivery attempts from a server.","synonyms":[],"models":["@happyvertical/smrt-webhooks:WebhookSubscription","@happyvertical/smrt-webhooks:WebhookDelivery","@happyvertical/smrt-webhooks:WebhookDeliveryTask","@happyvertical/smrt-webhooks:WebhookCursor"],"nav":[],"requires":[],"group":{"id":"integrations","label":"Integrations","summary":"Connect your application to external services."},"help":{"markdown":"## Overview\\n\\nSend signed event notifications to an external HTTPS endpoint. Administrators\\ncan pause subscriptions and inspect delivery attempts. This integration requires\\na server and a running background worker.\\n\\n## Tasks\\n\\n- Add a subscription with a public HTTPS endpoint, signing secret, and event/model filters.\\n- Disable a subscription to cancel unsent deliveries.\\n- Inspect the delivery log, then retry failed deliveries after correcting their endpoint.\\n- Ask the endpoint owner to verify signatures and deduplicate delivery IDs.\\n","fieldRefs":[]},"surfaces":[{"kind":"settings-panel","export":"@happyvertical/smrt-webhooks/svelte#WebhookAdmin","label":"Outbound webhooks"}],"runtime":"server","demo":{"mode":"server","reasons":["The recipe declares runtime \\"server\\".","Needs a server because its package does not build for a browser: Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.; and its package depends on @happyvertical/smrt-jobs, @happyvertical/smrt-tenancy, which do not build for a browser (#3615, #3624, #3627, #3717)."]}}],"smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-jobs","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3615","#3624","#3627","#3717"],"reason":"Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.","via":["@happyvertical/smrt-jobs","@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
8
8
  //#endregion
9
9
  //#region src/change-feed.ts
10
10
  var WebhookHistoryExpiredError = class extends Error {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/change-feed.ts","../src/events.ts","../src/recipes.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"packageVersion\\\":\\\"0.55.20\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-webhooks:WebhookSubscription\\\":{\\\"name\\\":\\\"webhooksubscription\\\",\\\"className\\\":\\\"WebhookSubscription\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookSubscription\\\",\\\"collection\\\":\\\"webhooksubscriptions\\\",\\\"description\\\":\\\"Server-only subscription. Hosts authorize administration before accessing it.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"url\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"events\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"models\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"secret\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sensitive\\\":true,\\\"required\\\":true},\\\"sensitive\\\":true},\\\"enabled\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":true,\\\"_meta\\\":{\\\"default\\\":true}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookSubscription\\\",\\\"collectionExportName\\\":\\\"WebhookSubscriptionCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"url\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"secret\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_subscriptions\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"url\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"events\\\\\\\" JSON,\\\\n \\\\\\\"models\\\\\\\" JSON,\\\\n \\\\\\\"secret\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"enabled\\\\\\\" BOOLEAN DEFAULT TRUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"events\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"models\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"secret\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"enabled\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_subscriptions_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_subscriptions_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"4e9ebebe\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection\\\":{\\\"name\\\":\\\"webhooksubscriptioncollection\\\",\\\"className\\\":\\\"WebhookSubscriptionCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection\\\",\\\"collection\\\":\\\"webhooksubscriptions\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"WebhookSubscription\\\",\\\"exportName\\\":\\\"WebhookSubscriptionCollection\\\",\\\"collectionExportName\\\":\\\"WebhookSubscriptionCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_subscriptions\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"url\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"events\\\\\\\" JSON,\\\\n \\\\\\\"models\\\\\\\" JSON,\\\\n \\\\\\\"secret\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"enabled\\\\\\\" BOOLEAN DEFAULT TRUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"events\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"models\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"secret\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"enabled\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_subscriptions_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_subscriptions_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"4e9ebebe\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookDelivery\\\":{\\\"name\\\":\\\"webhookdelivery\\\",\\\"className\\\":\\\"WebhookDelivery\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookDelivery\\\",\\\"collection\\\":\\\"webhookdeliveries\\\",\\\"description\\\":\\\"Durable outbox and safe outcome metadata; payload never appears in public projections.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"subscriptionId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"WebhookSubscription\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"RESTRICT\\\"}},\\\"eventId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"payload\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true,\\\"sensitive\\\":true},\\\"sensitive\\\":true},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"pending\\\",\\\"_meta\\\":{\\\"default\\\":\\\"pending\\\"}},\\\"generation\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"_meta\\\":{\\\"default\\\":0}},\\\"attempts\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"_meta\\\":{\\\"default\\\":0}},\\\"responseStatus\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"error\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"leaseToken\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"sensitive\\\":true},\\\"sensitive\\\":true},\\\"leaseUntil\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false,\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_delivery_identity\\\",\\\"columns\\\":[\\\"tenantId\\\",\\\"subscriptionId\\\",\\\"eventId\\\"],\\\"unique\\\":true}],\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookDelivery\\\",\\\"collectionExportName\\\":\\\"WebhookDeliveryCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"eventId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"payload\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_deliveries\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"subscription_id\\\\\\\" UUID,\\\\n \\\\\\\"event_id\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"status\\\\\\\" TEXT DEFAULT 'pending',\\\\n \\\\\\\"generation\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"attempts\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"response_status\\\\\\\" INTEGER,\\\\n \\\\\\\"error\\\\\\\" TEXT,\\\\n \\\\\\\"lease_token\\\\\\\" TEXT,\\\\n \\\\\\\"lease_until\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"subscription_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"RESTRICT\\\"}},\\\"event_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"pending\\\"},\\\"generation\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"attempts\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"response_status\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"error\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_token\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_until\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_deliveries_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_delivery_identity\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"subscription_id\\\",\\\"event_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_deliveries_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_webhook_deliveries_subscription_id_idx\\\",\\\"columns\\\":[\\\"subscription_id\\\"]}],\\\"version\\\":\\\"17d7bd27\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookDeliveryCollection\\\":{\\\"name\\\":\\\"webhookdeliverycollection\\\",\\\"className\\\":\\\"WebhookDeliveryCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookDeliveryCollection\\\",\\\"collection\\\":\\\"webhookdeliveries\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"WebhookDelivery\\\",\\\"exportName\\\":\\\"WebhookDeliveryCollection\\\",\\\"collectionExportName\\\":\\\"WebhookDeliveryCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_deliveries\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"subscription_id\\\\\\\" UUID,\\\\n \\\\\\\"event_id\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"status\\\\\\\" TEXT DEFAULT 'pending',\\\\n \\\\\\\"generation\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"attempts\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"response_status\\\\\\\" INTEGER,\\\\n \\\\\\\"error\\\\\\\" TEXT,\\\\n \\\\\\\"lease_token\\\\\\\" TEXT,\\\\n \\\\\\\"lease_until\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"subscription_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"RESTRICT\\\"}},\\\"event_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"pending\\\"},\\\"generation\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"attempts\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"response_status\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"error\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_token\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_until\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_deliveries_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_delivery_identity\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"subscription_id\\\",\\\"event_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_deliveries_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_webhook_deliveries_subscription_id_idx\\\",\\\"columns\\\":[\\\"subscription_id\\\"]}],\\\"version\\\":\\\"17d7bd27\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookDeliveryTask\\\":{\\\"name\\\":\\\"webhookdeliverytask\\\",\\\"className\\\":\\\"WebhookDeliveryTask\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookDeliveryTask\\\",\\\"collection\\\":\\\"webhookdeliverytasks\\\",\\\"description\\\":\\\"Jobs queue entry point; persisted arguments contain IDs only.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"deliver\\\":{\\\"name\\\":\\\"deliver\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"args\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":true},{\\\"name\\\":\\\"_context\\\",\\\"type\\\":\\\"JobExecutionContext\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_delivery_tasks\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookDeliveryTask\\\",\\\"collectionExportName\\\":\\\"WebhookDeliveryTaskCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_delivery_tasks\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_delivery_tasks\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_delivery_tasks_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_delivery_tasks_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"17ba7c43\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookCursor\\\":{\\\"name\\\":\\\"webhookcursor\\\",\\\"className\\\":\\\"WebhookCursor\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookCursor\\\",\\\"collection\\\":\\\"webhookcursors\\\",\\\"description\\\":\\\"Tenant-bound durable cursor for replayable model change-feed publication.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"runtime\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"position\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"_meta\\\":{\\\"default\\\":0}}},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_cursors\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false,\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_cursor_identity\\\",\\\"columns\\\":[\\\"tenantId\\\",\\\"runtime\\\"],\\\"unique\\\":true}],\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookCursor\\\",\\\"collectionExportName\\\":\\\"WebhookCursorCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"runtime\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_cursors\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_cursors\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"runtime\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"position\\\\\\\" INTEGER DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"runtime\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"position\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_cursors_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_cursor_identity\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"runtime\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_cursors_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"ba1ea19d\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"recipes\\\":[{\\\"id\\\":\\\"integrations.webhooks\\\",\\\"className\\\":\\\"WebhooksRecipe\\\",\\\"label\\\":\\\"Outbound webhooks\\\",\\\"summary\\\":\\\"Deliver signed model events and inspect delivery attempts from a server.\\\",\\\"synonyms\\\":[],\\\"models\\\":[\\\"@happyvertical/smrt-webhooks:WebhookSubscription\\\",\\\"@happyvertical/smrt-webhooks:WebhookDelivery\\\",\\\"@happyvertical/smrt-webhooks:WebhookDeliveryTask\\\",\\\"@happyvertical/smrt-webhooks:WebhookCursor\\\"],\\\"nav\\\":[],\\\"requires\\\":[],\\\"group\\\":{\\\"id\\\":\\\"integrations\\\",\\\"label\\\":\\\"Integrations\\\",\\\"summary\\\":\\\"Connect your application to external services.\\\"},\\\"help\\\":{\\\"markdown\\\":\\\"## Overview\\\\n\\\\nSend signed event notifications to an external HTTPS endpoint. Administrators\\\\ncan pause subscriptions and inspect delivery attempts. This integration requires\\\\na server and a running background worker.\\\\n\\\\n## Tasks\\\\n\\\\n- Add a subscription with a public HTTPS endpoint, signing secret, and event/model filters.\\\\n- Disable a subscription to cancel unsent deliveries.\\\\n- Inspect the delivery log, then retry failed deliveries after correcting their endpoint.\\\\n- Ask the endpoint owner to verify signatures and deduplicate delivery IDs.\\\\n\\\",\\\"fieldRefs\\\":[]},\\\"surfaces\\\":[{\\\"kind\\\":\\\"settings-panel\\\",\\\"export\\\":\\\"@happyvertical/smrt-webhooks/svelte#WebhookAdmin\\\",\\\"label\\\":\\\"Outbound webhooks\\\"}],\\\"runtime\\\":\\\"server\\\",\\\"demo\\\":{\\\"mode\\\":\\\"server\\\",\\\"reasons\\\":[\\\"The recipe declares runtime \\\\\\\"server\\\\\\\".\\\",\\\"Needs a server because its package does not build for a browser: Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.; and its package depends on @happyvertical/smrt-jobs, @happyvertical/smrt-tenancy, which do not build for a browser (#3615, #3624, #3627, #3717).\\\"]}}],\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3615\\\",\\\"#3624\\\",\\\"#3627\\\",\\\"#3717\\\"],\\\"reason\\\":\\\"Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.\\\",\\\"via\\\":[\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-tenancy\\\"]},\\\"stampsConstructors\\\":true}\"));\n","import { randomUUID } from 'node:crypto';\nimport { getChangesSince } from '@happyvertical/smrt-core';\nimport { requireTenant } from '@happyvertical/smrt-tenancy';\nimport type { WebhookDispatcher } from './dispatcher.js';\n\nexport class WebhookHistoryExpiredError extends Error {\n constructor(readonly resumeCursor: number) {\n super(\n 'Webhook change history expired; reconcile source state before resetting the cursor.',\n );\n }\n}\n\n/** Durable, replayable lifecycle publication from SMRT's committed change feed.\n * Host scheduling calls poll() in each authenticated tenant context. The mapping\n * is an explicit physical-table allowlist; shared STI tables represent the base model.\n */\nexport class WebhookChangeFeed {\n constructor(\n private readonly dispatcher: WebhookDispatcher,\n private readonly models: Readonly<Record<string, string>>,\n ) {\n if (\n !Object.keys(models).length ||\n Object.keys(models).some((table) => table.startsWith('_smrt_')) ||\n Object.values(models).some((model) => !model)\n )\n throw new Error('Explicit application model tables are required.');\n }\n /** Cursor only advances after all matched changes have durable outbox/jobs.\n * A crash or partial failure replays the same stable identities on the next poll.\n * History pruning fails loudly: the host must reconcile source state before reset.\n */\n async poll(): Promise<{ cursor: number; published: number }> {\n const tenantId = requireTenant().tenantId;\n const { db, runtime } = this.dispatcher.store;\n const now = new Date().toISOString();\n const id = randomUUID();\n await db.query(\n `INSERT INTO _smrt_webhook_cursors (id, slug, context, tenant_id, runtime, position, created_at, updated_at)\n VALUES (?, ?, '', ?, ?, 0, ?, ?) ON CONFLICT (tenant_id, runtime) DO NOTHING`,\n id,\n id,\n tenantId,\n runtime,\n now,\n now,\n );\n const rows = await db.query(\n 'SELECT position FROM _smrt_webhook_cursors WHERE tenant_id = ? AND runtime = ?',\n tenantId,\n runtime,\n );\n const since = Number((rows.rows[0] as { position: number }).position);\n const page = await getChangesSince(db, {\n since,\n tenantId,\n tables: Object.keys(this.models),\n limit: 500,\n });\n if (page.resyncRequired)\n throw new WebhookHistoryExpiredError(page.resyncCursor ?? page.cursor);\n let published = 0;\n for (const change of page.changes) {\n // Core's tenant feed includes global rows; webhooks deliberately do not.\n if (\n change.tenantId !== tenantId ||\n !change.rowId ||\n !this.models[change.table]\n )\n continue;\n await this.dispatcher.dispatch({\n id: `change:${change.seq}`,\n event: change.operation,\n model: this.models[change.table],\n occurredAt: change.timestamp,\n data: { id: change.rowId },\n });\n published++;\n }\n await db.query(\n 'UPDATE _smrt_webhook_cursors SET position = ?, updated_at = ? WHERE tenant_id = ? AND runtime = ? AND position = ?',\n page.cursor,\n new Date().toISOString(),\n tenantId,\n runtime,\n since,\n );\n return { cursor: page.cursor, published };\n }\n /** Operator-only recovery: call after reconciling retained source state externally. */\n async resumeAfterResync(cursor: number): Promise<void> {\n if (!Number.isSafeInteger(cursor) || cursor < 0)\n throw new Error('Invalid webhook change cursor.');\n const tenantId = requireTenant().tenantId;\n const { db, runtime } = this.dispatcher.store;\n await db.query(\n 'UPDATE _smrt_webhook_cursors SET position = ? WHERE tenant_id = ? AND runtime = ?',\n cursor,\n tenantId,\n runtime,\n );\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n GlobalInterceptors,\n type InterceptorContext,\n type SmrtObject,\n} from '@happyvertical/smrt-core';\nimport { requireTenant } from '@happyvertical/smrt-tenancy';\nimport type { WebhookDispatcher } from './dispatcher.js';\n\n/** Opt-in lifecycle binding. Explicit model allowlist prevents recursive/internal data publication.\n * Payloads contain record identity only; use dispatch() for authorized custom projections.\n */\nexport function registerWebhookModelEvents(\n dispatcher: WebhookDispatcher,\n models: readonly string[],\n): () => void {\n const internal = new Set([\n 'WebhookSubscription',\n 'WebhookDelivery',\n 'WebhookDeliveryTask',\n 'WebhookCursor',\n 'SmrtJob',\n 'SmrtJobEvent',\n 'SmrtWorker',\n ]);\n if (models.some((name) => internal.has(name.split(':').at(-1) ?? name))) {\n throw new Error(\n 'Internal queue and webhook models cannot publish lifecycle webhooks.',\n );\n }\n const allowed = new Set(models);\n const pending = new WeakMap<\n InterceptorContext,\n { event: string; id: string }\n >();\n const matches = (context: InterceptorContext) =>\n allowed.has(context.qualifiedClassName ?? context.className);\n async function emit(\n instance: SmrtObject,\n context: InterceptorContext,\n event: string,\n ) {\n if (!matches(context)) return;\n const tenantId = requireTenant().tenantId;\n if ('tenantId' in instance && instance.tenantId !== tenantId)\n throw new Error('Webhook model tenant mismatch.');\n await dispatcher.dispatch({\n id: pending.get(context)?.id ?? randomUUID(),\n event,\n model: context.qualifiedClassName ?? context.className,\n occurredAt: context.timestamp.toISOString(),\n data: { id: instance.id },\n });\n }\n const interceptor = {\n name: `webhook-model-events:${randomUUID()}`,\n beforeSave(instance: SmrtObject, context: InterceptorContext) {\n if (matches(context))\n pending.set(context, {\n event: instance.isPersisted ? 'update' : 'create',\n id: randomUUID(),\n });\n },\n async afterSave(instance: SmrtObject, context: InterceptorContext) {\n await emit(instance, context, pending.get(context)?.event ?? 'update');\n },\n async afterDelete(instance: SmrtObject, context: InterceptorContext) {\n await emit(instance, context, 'delete');\n },\n };\n GlobalInterceptors.register(interceptor);\n return () => {\n GlobalInterceptors.unregister(interceptor);\n };\n}\n","import { SmrtRecipe } from '@happyvertical/smrt-core';\nimport {\n WebhookCursor,\n WebhookDelivery,\n WebhookDeliveryTask,\n WebhookSubscription,\n} from './models.js';\n/** Server-backed administration through authenticated host callbacks. */\nexport class WebhooksRecipe extends SmrtRecipe {\n static id = 'integrations.webhooks';\n static label = 'Outbound webhooks';\n static summary =\n 'Deliver signed model events and inspect delivery attempts from a server.';\n static models = [\n WebhookSubscription,\n WebhookDelivery,\n WebhookDeliveryTask,\n WebhookCursor,\n ];\n static group = {\n id: 'integrations',\n label: 'Integrations',\n summary: 'Connect your application to external services.',\n };\n static runtime = 'server' as const;\n static surfaces = [\n {\n kind: 'settings-panel',\n export: '@happyvertical/smrt-webhooks/svelte#WebhookAdmin',\n label: 'Outbound webhooks',\n },\n ] as const;\n // Administration uses the authorized service, never generated model CRUD.\n static nav = [];\n static help = './webhooks.recipe.md';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/change-feed.ts","../src/events.ts","../src/recipes.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"packageVersion\\\":\\\"0.55.21\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-webhooks:WebhookSubscription\\\":{\\\"name\\\":\\\"webhooksubscription\\\",\\\"className\\\":\\\"WebhookSubscription\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookSubscription\\\",\\\"collection\\\":\\\"webhooksubscriptions\\\",\\\"description\\\":\\\"Server-only subscription. Hosts authorize administration before accessing it.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"url\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"events\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"models\\\":{\\\"type\\\":\\\"json\\\",\\\"required\\\":false,\\\"_meta\\\":{}},\\\"secret\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sensitive\\\":true,\\\"required\\\":true},\\\"sensitive\\\":true},\\\"enabled\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":false,\\\"default\\\":true,\\\"_meta\\\":{\\\"default\\\":true}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false,\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookSubscription\\\",\\\"collectionExportName\\\":\\\"WebhookSubscriptionCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"url\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"secret\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_subscriptions\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"url\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"events\\\\\\\" JSON,\\\\n \\\\\\\"models\\\\\\\" JSON,\\\\n \\\\\\\"secret\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"enabled\\\\\\\" BOOLEAN DEFAULT TRUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"events\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"models\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"secret\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"enabled\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_subscriptions_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_subscriptions_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"4e9ebebe\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection\\\":{\\\"name\\\":\\\"webhooksubscriptioncollection\\\",\\\"className\\\":\\\"WebhookSubscriptionCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookSubscriptionCollection\\\",\\\"collection\\\":\\\"webhooksubscriptions\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"WebhookSubscription\\\",\\\"exportName\\\":\\\"WebhookSubscriptionCollection\\\",\\\"collectionExportName\\\":\\\"WebhookSubscriptionCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_subscriptions\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"url\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"events\\\\\\\" JSON,\\\\n \\\\\\\"models\\\\\\\" JSON,\\\\n \\\\\\\"secret\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"enabled\\\\\\\" BOOLEAN DEFAULT TRUE\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"url\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"events\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"models\\\":{\\\"type\\\":\\\"JSON\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"secret\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"enabled\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":true}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_subscriptions_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_subscriptions_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"4e9ebebe\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookDelivery\\\":{\\\"name\\\":\\\"webhookdelivery\\\",\\\"className\\\":\\\"WebhookDelivery\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookDelivery\\\",\\\"collection\\\":\\\"webhookdeliveries\\\",\\\"description\\\":\\\"Durable outbox and safe outcome metadata; payload never appears in public projections.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"subscriptionId\\\":{\\\"type\\\":\\\"foreignKey\\\",\\\"required\\\":false,\\\"related\\\":\\\"WebhookSubscription\\\",\\\"_meta\\\":{\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"RESTRICT\\\"}},\\\"eventId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"payload\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true,\\\"sensitive\\\":true},\\\"sensitive\\\":true},\\\"status\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"default\\\":\\\"pending\\\",\\\"_meta\\\":{\\\"default\\\":\\\"pending\\\"}},\\\"generation\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"_meta\\\":{\\\"default\\\":0}},\\\"attempts\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"_meta\\\":{\\\"default\\\":0}},\\\"responseStatus\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"error\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"leaseToken\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true,\\\"sensitive\\\":true},\\\"sensitive\\\":true},\\\"leaseUntil\\\":{\\\"type\\\":\\\"datetime\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false,\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_delivery_identity\\\",\\\"columns\\\":[\\\"tenantId\\\",\\\"subscriptionId\\\",\\\"eventId\\\"],\\\"unique\\\":true}],\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookDelivery\\\",\\\"collectionExportName\\\":\\\"WebhookDeliveryCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"eventId\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"payload\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_deliveries\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"subscription_id\\\\\\\" UUID,\\\\n \\\\\\\"event_id\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"status\\\\\\\" TEXT DEFAULT 'pending',\\\\n \\\\\\\"generation\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"attempts\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"response_status\\\\\\\" INTEGER,\\\\n \\\\\\\"error\\\\\\\" TEXT,\\\\n \\\\\\\"lease_token\\\\\\\" TEXT,\\\\n \\\\\\\"lease_until\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"subscription_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"RESTRICT\\\"}},\\\"event_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"pending\\\"},\\\"generation\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"attempts\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"response_status\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"error\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_token\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_until\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_deliveries_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_delivery_identity\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"subscription_id\\\",\\\"event_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_deliveries_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_webhook_deliveries_subscription_id_idx\\\",\\\"columns\\\":[\\\"subscription_id\\\"]}],\\\"version\\\":\\\"17d7bd27\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookDeliveryCollection\\\":{\\\"name\\\":\\\"webhookdeliverycollection\\\",\\\"className\\\":\\\"WebhookDeliveryCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookDeliveryCollection\\\",\\\"collection\\\":\\\"webhookdeliveries\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"api\\\":false,\\\"mcp\\\":false,\\\"cli\\\":false},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"WebhookDelivery\\\",\\\"exportName\\\":\\\"WebhookDeliveryCollection\\\",\\\"collectionExportName\\\":\\\"WebhookDeliveryCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_deliveries\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_deliveries\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"subscription_id\\\\\\\" UUID,\\\\n \\\\\\\"event_id\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"payload\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"status\\\\\\\" TEXT DEFAULT 'pending',\\\\n \\\\\\\"generation\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"attempts\\\\\\\" INTEGER DEFAULT 0,\\\\n \\\\\\\"response_status\\\\\\\" INTEGER,\\\\n \\\\\\\"error\\\\\\\" TEXT,\\\\n \\\\\\\"lease_token\\\\\\\" TEXT,\\\\n \\\\\\\"lease_until\\\\\\\" TIMESTAMP\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"subscription_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"foreignKey\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"foreignKey\\\":{\\\"table\\\":\\\"_smrt_webhook_subscriptions\\\",\\\"column\\\":\\\"id\\\",\\\"onDelete\\\":\\\"RESTRICT\\\",\\\"onUpdate\\\":\\\"RESTRICT\\\"}},\\\"event_id\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"payload\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"status\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":\\\"pending\\\"},\\\"generation\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"attempts\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0},\\\"response_status\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"error\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_token\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"lease_until\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_deliveries_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_delivery_identity\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"subscription_id\\\",\\\"event_id\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_deliveries_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]},{\\\"name\\\":\\\"_smrt_webhook_deliveries_subscription_id_idx\\\",\\\"columns\\\":[\\\"subscription_id\\\"]}],\\\"version\\\":\\\"17d7bd27\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookDeliveryTask\\\":{\\\"name\\\":\\\"webhookdeliverytask\\\",\\\"className\\\":\\\"WebhookDeliveryTask\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookDeliveryTask\\\",\\\"collection\\\":\\\"webhookdeliverytasks\\\",\\\"description\\\":\\\"Jobs queue entry point; persisted arguments contain IDs only.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"deliver\\\":{\\\"name\\\":\\\"deliver\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"args\\\",\\\"type\\\":\\\"Record<string, unknown>\\\",\\\"optional\\\":true},{\\\"name\\\":\\\"_context\\\",\\\"type\\\":\\\"JobExecutionContext\\\",\\\"optional\\\":true}],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_delivery_tasks\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookDeliveryTask\\\",\\\"collectionExportName\\\":\\\"WebhookDeliveryTaskCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_delivery_tasks\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_delivery_tasks\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_delivery_tasks_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_delivery_tasks_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"17ba7c43\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"},\\\"@happyvertical/smrt-webhooks:WebhookCursor\\\":{\\\"name\\\":\\\"webhookcursor\\\",\\\"className\\\":\\\"WebhookCursor\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-webhooks:WebhookCursor\\\",\\\"collection\\\":\\\"webhookcursors\\\",\\\"description\\\":\\\"Tenant-bound durable cursor for replayable model change-feed publication.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/webhooks/src/models.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-webhooks\\\",\\\"fields\\\":{\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"__tenancy\\\":{\\\"isTenantIdField\\\":true,\\\"autoFilter\\\":true,\\\"required\\\":true,\\\"autoPopulate\\\":true,\\\"nullable\\\":false,\\\"mode\\\":\\\"required\\\",\\\"field\\\":\\\"tenantId\\\",\\\"allowSuperAdminBypass\\\":false}}},\\\"runtime\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"position\\\":{\\\"type\\\":\\\"integer\\\",\\\"required\\\":false,\\\"default\\\":0,\\\"_meta\\\":{\\\"default\\\":0}}},\\\"methods\\\":{},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_webhook_cursors\\\",\\\"api\\\":false,\\\"cli\\\":false,\\\"mcp\\\":false,\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_cursor_identity\\\",\\\"columns\\\":[\\\"tenantId\\\",\\\"runtime\\\"],\\\"unique\\\":true}],\\\"tenantScoped\\\":{\\\"mode\\\":\\\"required\\\"},\\\"conflictColumns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"]},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"WebhookCursor\\\",\\\"collectionExportName\\\":\\\"WebhookCursorCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"runtime\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_webhook_cursors\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_webhook_cursors\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"tenant_id\\\\\\\" UUID NOT NULL,\\\\n \\\\\\\"runtime\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"position\\\\\\\" INTEGER DEFAULT 0\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"referenceKind\\\":\\\"tenantId\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"runtime\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"position\\\":{\\\"type\\\":\\\"INTEGER\\\",\\\"notNull\\\":false,\\\"unique\\\":false,\\\"default\\\":0}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_webhook_cursors_slug_context_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_cursor_identity\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"runtime\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_webhook_cursors_tenant_id_created_at_idx\\\",\\\"columns\\\":[\\\"tenant_id\\\",\\\"created_at\\\"]}],\\\"version\\\":\\\"ba1ea19d\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-webhooks\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"recipes\\\":[{\\\"id\\\":\\\"integrations.webhooks\\\",\\\"className\\\":\\\"WebhooksRecipe\\\",\\\"label\\\":\\\"Outbound webhooks\\\",\\\"summary\\\":\\\"Deliver signed model events and inspect delivery attempts from a server.\\\",\\\"synonyms\\\":[],\\\"models\\\":[\\\"@happyvertical/smrt-webhooks:WebhookSubscription\\\",\\\"@happyvertical/smrt-webhooks:WebhookDelivery\\\",\\\"@happyvertical/smrt-webhooks:WebhookDeliveryTask\\\",\\\"@happyvertical/smrt-webhooks:WebhookCursor\\\"],\\\"nav\\\":[],\\\"requires\\\":[],\\\"group\\\":{\\\"id\\\":\\\"integrations\\\",\\\"label\\\":\\\"Integrations\\\",\\\"summary\\\":\\\"Connect your application to external services.\\\"},\\\"help\\\":{\\\"markdown\\\":\\\"## Overview\\\\n\\\\nSend signed event notifications to an external HTTPS endpoint. Administrators\\\\ncan pause subscriptions and inspect delivery attempts. This integration requires\\\\na server and a running background worker.\\\\n\\\\n## Tasks\\\\n\\\\n- Add a subscription with a public HTTPS endpoint, signing secret, and event/model filters.\\\\n- Disable a subscription to cancel unsent deliveries.\\\\n- Inspect the delivery log, then retry failed deliveries after correcting their endpoint.\\\\n- Ask the endpoint owner to verify signatures and deduplicate delivery IDs.\\\\n\\\",\\\"fieldRefs\\\":[]},\\\"surfaces\\\":[{\\\"kind\\\":\\\"settings-panel\\\",\\\"export\\\":\\\"@happyvertical/smrt-webhooks/svelte#WebhookAdmin\\\",\\\"label\\\":\\\"Outbound webhooks\\\"}],\\\"runtime\\\":\\\"server\\\",\\\"demo\\\":{\\\"mode\\\":\\\"server\\\",\\\"reasons\\\":[\\\"The recipe declares runtime \\\\\\\"server\\\\\\\".\\\",\\\"Needs a server because its package does not build for a browser: Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.; and its package depends on @happyvertical/smrt-jobs, @happyvertical/smrt-tenancy, which do not build for a browser (#3615, #3624, #3627, #3717).\\\"]}}],\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3615\\\",\\\"#3624\\\",\\\"#3627\\\",\\\"#3717\\\"],\\\"reason\\\":\\\"Intentionally server-only outbound delivery: node:crypto HMAC and node:https/dns/net pinned transport enforce signing and SSRF protection. Browser hosts use the separate /svelte admin export with authenticated server callbacks.\\\",\\\"via\\\":[\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-tenancy\\\"]},\\\"stampsConstructors\\\":true}\"));\n","import { randomUUID } from 'node:crypto';\nimport { getChangesSince } from '@happyvertical/smrt-core';\nimport { requireTenant } from '@happyvertical/smrt-tenancy';\nimport type { WebhookDispatcher } from './dispatcher.js';\n\nexport class WebhookHistoryExpiredError extends Error {\n constructor(readonly resumeCursor: number) {\n super(\n 'Webhook change history expired; reconcile source state before resetting the cursor.',\n );\n }\n}\n\n/** Durable, replayable lifecycle publication from SMRT's committed change feed.\n * Host scheduling calls poll() in each authenticated tenant context. The mapping\n * is an explicit physical-table allowlist; shared STI tables represent the base model.\n */\nexport class WebhookChangeFeed {\n constructor(\n private readonly dispatcher: WebhookDispatcher,\n private readonly models: Readonly<Record<string, string>>,\n ) {\n if (\n !Object.keys(models).length ||\n Object.keys(models).some((table) => table.startsWith('_smrt_')) ||\n Object.values(models).some((model) => !model)\n )\n throw new Error('Explicit application model tables are required.');\n }\n /** Cursor only advances after all matched changes have durable outbox/jobs.\n * A crash or partial failure replays the same stable identities on the next poll.\n * History pruning fails loudly: the host must reconcile source state before reset.\n */\n async poll(): Promise<{ cursor: number; published: number }> {\n const tenantId = requireTenant().tenantId;\n const { db, runtime } = this.dispatcher.store;\n const now = new Date().toISOString();\n const id = randomUUID();\n await db.query(\n `INSERT INTO _smrt_webhook_cursors (id, slug, context, tenant_id, runtime, position, created_at, updated_at)\n VALUES (?, ?, '', ?, ?, 0, ?, ?) ON CONFLICT (tenant_id, runtime) DO NOTHING`,\n id,\n id,\n tenantId,\n runtime,\n now,\n now,\n );\n const rows = await db.query(\n 'SELECT position FROM _smrt_webhook_cursors WHERE tenant_id = ? AND runtime = ?',\n tenantId,\n runtime,\n );\n const since = Number((rows.rows[0] as { position: number }).position);\n const page = await getChangesSince(db, {\n since,\n tenantId,\n tables: Object.keys(this.models),\n limit: 500,\n });\n if (page.resyncRequired)\n throw new WebhookHistoryExpiredError(page.resyncCursor ?? page.cursor);\n let published = 0;\n for (const change of page.changes) {\n // Core's tenant feed includes global rows; webhooks deliberately do not.\n if (\n change.tenantId !== tenantId ||\n !change.rowId ||\n !this.models[change.table]\n )\n continue;\n await this.dispatcher.dispatch({\n id: `change:${change.seq}`,\n event: change.operation,\n model: this.models[change.table],\n occurredAt: change.timestamp,\n data: { id: change.rowId },\n });\n published++;\n }\n await db.query(\n 'UPDATE _smrt_webhook_cursors SET position = ?, updated_at = ? WHERE tenant_id = ? AND runtime = ? AND position = ?',\n page.cursor,\n new Date().toISOString(),\n tenantId,\n runtime,\n since,\n );\n return { cursor: page.cursor, published };\n }\n /** Operator-only recovery: call after reconciling retained source state externally. */\n async resumeAfterResync(cursor: number): Promise<void> {\n if (!Number.isSafeInteger(cursor) || cursor < 0)\n throw new Error('Invalid webhook change cursor.');\n const tenantId = requireTenant().tenantId;\n const { db, runtime } = this.dispatcher.store;\n await db.query(\n 'UPDATE _smrt_webhook_cursors SET position = ? WHERE tenant_id = ? AND runtime = ?',\n cursor,\n tenantId,\n runtime,\n );\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n GlobalInterceptors,\n type InterceptorContext,\n type SmrtObject,\n} from '@happyvertical/smrt-core';\nimport { requireTenant } from '@happyvertical/smrt-tenancy';\nimport type { WebhookDispatcher } from './dispatcher.js';\n\n/** Opt-in lifecycle binding. Explicit model allowlist prevents recursive/internal data publication.\n * Payloads contain record identity only; use dispatch() for authorized custom projections.\n */\nexport function registerWebhookModelEvents(\n dispatcher: WebhookDispatcher,\n models: readonly string[],\n): () => void {\n const internal = new Set([\n 'WebhookSubscription',\n 'WebhookDelivery',\n 'WebhookDeliveryTask',\n 'WebhookCursor',\n 'SmrtJob',\n 'SmrtJobEvent',\n 'SmrtWorker',\n ]);\n if (models.some((name) => internal.has(name.split(':').at(-1) ?? name))) {\n throw new Error(\n 'Internal queue and webhook models cannot publish lifecycle webhooks.',\n );\n }\n const allowed = new Set(models);\n const pending = new WeakMap<\n InterceptorContext,\n { event: string; id: string }\n >();\n const matches = (context: InterceptorContext) =>\n allowed.has(context.qualifiedClassName ?? context.className);\n async function emit(\n instance: SmrtObject,\n context: InterceptorContext,\n event: string,\n ) {\n if (!matches(context)) return;\n const tenantId = requireTenant().tenantId;\n if ('tenantId' in instance && instance.tenantId !== tenantId)\n throw new Error('Webhook model tenant mismatch.');\n await dispatcher.dispatch({\n id: pending.get(context)?.id ?? randomUUID(),\n event,\n model: context.qualifiedClassName ?? context.className,\n occurredAt: context.timestamp.toISOString(),\n data: { id: instance.id },\n });\n }\n const interceptor = {\n name: `webhook-model-events:${randomUUID()}`,\n beforeSave(instance: SmrtObject, context: InterceptorContext) {\n if (matches(context))\n pending.set(context, {\n event: instance.isPersisted ? 'update' : 'create',\n id: randomUUID(),\n });\n },\n async afterSave(instance: SmrtObject, context: InterceptorContext) {\n await emit(instance, context, pending.get(context)?.event ?? 'update');\n },\n async afterDelete(instance: SmrtObject, context: InterceptorContext) {\n await emit(instance, context, 'delete');\n },\n };\n GlobalInterceptors.register(interceptor);\n return () => {\n GlobalInterceptors.unregister(interceptor);\n };\n}\n","import { SmrtRecipe } from '@happyvertical/smrt-core';\nimport {\n WebhookCursor,\n WebhookDelivery,\n WebhookDeliveryTask,\n WebhookSubscription,\n} from './models.js';\n/** Server-backed administration through authenticated host callbacks. */\nexport class WebhooksRecipe extends SmrtRecipe {\n static id = 'integrations.webhooks';\n static label = 'Outbound webhooks';\n static summary =\n 'Deliver signed model events and inspect delivery attempts from a server.';\n static models = [\n WebhookSubscription,\n WebhookDelivery,\n WebhookDeliveryTask,\n WebhookCursor,\n ];\n static group = {\n id: 'integrations',\n label: 'Integrations',\n summary: 'Connect your application to external services.',\n };\n static runtime = 'server' as const;\n static surfaces = [\n {\n kind: 'settings-panel',\n export: '@happyvertical/smrt-webhooks/svelte#WebhookAdmin',\n label: 'Outbound webhooks',\n },\n ] as const;\n // Administration uses the authorized service, never generated model CRUD.\n static nav = [];\n static help = './webhooks.recipe.md';\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-webhooks",
5
- "packageVersion": "0.55.20",
5
+ "packageVersion": "0.55.21",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-webhooks:WebhookSubscription": {
8
8
  "name": "webhooksubscription",
@@ -3,12 +3,12 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-webhooks",
6
- "packageVersion": "0.55.20",
6
+ "packageVersion": "0.55.21",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "11a5ced75f121ac720451d21d3b684aa59f12080efdef091f9d93e47e1e33b0d",
11
- "packageJson": "ba96d912aec70ebecd44bba6ae3a7342cf888e4ee4ff9aa933957d15ef4df3e2",
10
+ "manifest": "cd64b08ffec152650162a4096c467d531c1ad707bfc9397c38b0cae457fe4ca0",
11
+ "packageJson": "89831e46aff3c9fadf6b04560dd79fad301bff733e22b7f8cfd721fefdbbf942",
12
12
  "agents": "f67b2a340106cf4b4b44c6b2bf918086286236ac3cf34b03b24b1db6e17b40a5"
13
13
  },
14
14
  "exports": [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-webhooks",
3
3
  "author": "HappyVertical",
4
- "version": "0.55.20",
4
+ "version": "0.55.21",
5
5
  "smrtJsdoc": "strict",
6
6
  "description": "Outbound webhook subscriptions, signed delivery, and durable retries",
7
7
  "type": "module",
@@ -30,11 +30,11 @@
30
30
  "./manifest.json": "./dist/manifest.json"
31
31
  },
32
32
  "dependencies": {
33
- "@happyvertical/smrt-core": "0.55.20",
34
- "@happyvertical/smrt-jobs": "0.55.20",
35
- "@happyvertical/smrt-tenancy": "0.55.20",
33
+ "@happyvertical/smrt-core": "0.55.21",
34
+ "@happyvertical/smrt-jobs": "0.55.21",
35
+ "@happyvertical/smrt-tenancy": "0.55.21",
36
36
  "@happyvertical/sql": "^0.103.5",
37
- "@happyvertical/smrt-ui": "0.55.20"
37
+ "@happyvertical/smrt-ui": "0.55.21"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "svelte": "^5.57.0"
@@ -45,7 +45,7 @@
45
45
  }
46
46
  },
47
47
  "devDependencies": {
48
- "@happyvertical/smrt-vitest": "0.55.20",
48
+ "@happyvertical/smrt-vitest": "0.55.21",
49
49
  "@sveltejs/package": "^2.5.8",
50
50
  "@types/node": "24.13.6",
51
51
  "svelte": "^5.57.1",