@wildo-ai/external-connectors-models 1.1.11 → 1.1.12

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.
Files changed (109) hide show
  1. package/dist/esm/companion-exports.d.ts.map +1 -1
  2. package/dist/esm/companion-exports.js.map +1 -1
  3. package/dist/esm/core/commons.external-connectors-models.schemas.d.ts +10 -0
  4. package/dist/esm/core/commons.external-connectors-models.schemas.d.ts.map +1 -1
  5. package/dist/esm/core/commons.external-connectors-models.schemas.js +10 -0
  6. package/dist/esm/core/commons.external-connectors-models.schemas.js.map +1 -1
  7. package/dist/esm/core/oauth2.enums.d.ts.map +1 -1
  8. package/dist/esm/core/oauth2.enums.js.map +1 -1
  9. package/dist/esm/core/operation-classification.external-connectors-models.schemas.d.ts.map +1 -1
  10. package/dist/esm/core/operation-classification.external-connectors-models.schemas.js.map +1 -1
  11. package/dist/esm/core/operations.external-connectors-models.schemas.d.ts.map +1 -1
  12. package/dist/esm/core/operations.external-connectors-models.schemas.js.map +1 -1
  13. package/dist/esm/core/security.external-connectors-models.schemas.d.ts.map +1 -1
  14. package/dist/esm/core/security.external-connectors-models.schemas.js.map +1 -1
  15. package/dist/esm/index.d.ts +6 -0
  16. package/dist/esm/index.d.ts.map +1 -1
  17. package/dist/esm/index.js +6 -0
  18. package/dist/esm/index.js.map +1 -1
  19. package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.d.ts +8 -42
  20. package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.d.ts.map +1 -1
  21. package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.js +21 -0
  22. package/dist/esm/protocols/agent-client-protocol.external-connectors-models.schemas.js.map +1 -1
  23. package/dist/esm/protocols/billing.standard-interface.schemas.d.ts +56 -3
  24. package/dist/esm/protocols/billing.standard-interface.schemas.d.ts.map +1 -1
  25. package/dist/esm/protocols/billing.standard-interface.schemas.js +15 -2
  26. package/dist/esm/protocols/billing.standard-interface.schemas.js.map +1 -1
  27. package/dist/esm/protocols/content-safety.external-connectors-models.schemas.d.ts.map +1 -1
  28. package/dist/esm/protocols/content-safety.external-connectors-models.schemas.js.map +1 -1
  29. package/dist/esm/protocols/document-extraction.external-connectors-models.schemas.d.ts.map +1 -1
  30. package/dist/esm/protocols/document-extraction.external-connectors-models.schemas.js.map +1 -1
  31. package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.d.ts +157 -0
  32. package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.d.ts.map +1 -0
  33. package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.js +134 -0
  34. package/dist/esm/protocols/electronic-signature.external-connectors-models.schemas.js.map +1 -0
  35. package/dist/esm/protocols/email-inbound.standard-interface.schemas.d.ts +85 -0
  36. package/dist/esm/protocols/email-inbound.standard-interface.schemas.d.ts.map +1 -1
  37. package/dist/esm/protocols/email-inbound.standard-interface.schemas.js +46 -2
  38. package/dist/esm/protocols/email-inbound.standard-interface.schemas.js.map +1 -1
  39. package/dist/esm/protocols/email.external-connectors-models.schemas.d.ts.map +1 -1
  40. package/dist/esm/protocols/email.external-connectors-models.schemas.js.map +1 -1
  41. package/dist/esm/protocols/email.standard-interface.schemas.d.ts.map +1 -1
  42. package/dist/esm/protocols/email.standard-interface.schemas.js.map +1 -1
  43. package/dist/esm/protocols/embeddings.external-connectors-models.schemas.d.ts +49 -6
  44. package/dist/esm/protocols/embeddings.external-connectors-models.schemas.d.ts.map +1 -1
  45. package/dist/esm/protocols/embeddings.external-connectors-models.schemas.js +89 -6
  46. package/dist/esm/protocols/embeddings.external-connectors-models.schemas.js.map +1 -1
  47. package/dist/esm/protocols/file-storage.standard-interface.d.ts +9 -2
  48. package/dist/esm/protocols/file-storage.standard-interface.d.ts.map +1 -1
  49. package/dist/esm/protocols/file-storage.standard-interface.js +6 -0
  50. package/dist/esm/protocols/file-storage.standard-interface.js.map +1 -1
  51. package/dist/esm/protocols/frontend.external-connectors-models.schemas.d.ts.map +1 -1
  52. package/dist/esm/protocols/frontend.external-connectors-models.schemas.js.map +1 -1
  53. package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.d.ts +254 -0
  54. package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.d.ts.map +1 -0
  55. package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.js +480 -0
  56. package/dist/esm/protocols/graphql-operations.external-connectors-models.schemas.js.map +1 -0
  57. package/dist/esm/protocols/hooks-capability.external-connectors-models.schemas.d.ts.map +1 -1
  58. package/dist/esm/protocols/hooks-capability.external-connectors-models.schemas.js.map +1 -1
  59. package/dist/esm/protocols/hooks.external-connectors-models.schemas.d.ts +95 -1
  60. package/dist/esm/protocols/hooks.external-connectors-models.schemas.d.ts.map +1 -1
  61. package/dist/esm/protocols/hooks.external-connectors-models.schemas.js +110 -0
  62. package/dist/esm/protocols/hooks.external-connectors-models.schemas.js.map +1 -1
  63. package/dist/esm/protocols/image.external-connectors-models.schemas.d.ts.map +1 -1
  64. package/dist/esm/protocols/image.external-connectors-models.schemas.js.map +1 -1
  65. package/dist/esm/protocols/llm.external-connectors-models.schemas.d.ts +95 -3
  66. package/dist/esm/protocols/llm.external-connectors-models.schemas.d.ts.map +1 -1
  67. package/dist/esm/protocols/llm.external-connectors-models.schemas.js +147 -15
  68. package/dist/esm/protocols/llm.external-connectors-models.schemas.js.map +1 -1
  69. package/dist/esm/protocols/oauth2-provider-assurance.definitions.d.ts.map +1 -1
  70. package/dist/esm/protocols/oauth2-provider-assurance.definitions.js.map +1 -1
  71. package/dist/esm/protocols/oauth2-provider-assurance.schemas.d.ts.map +1 -1
  72. package/dist/esm/protocols/oauth2-provider-assurance.schemas.js.map +1 -1
  73. package/dist/esm/protocols/oauth2.external-connectors-models.schemas.d.ts.map +1 -1
  74. package/dist/esm/protocols/oauth2.external-connectors-models.schemas.js.map +1 -1
  75. package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.d.ts +52 -0
  76. package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.d.ts.map +1 -0
  77. package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.js +132 -0
  78. package/dist/esm/protocols/provider-configuration-authoring.external-connectors-models.schemas.js.map +1 -0
  79. package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.d.ts +111 -0
  80. package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.d.ts.map +1 -0
  81. package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.js +203 -0
  82. package/dist/esm/protocols/provider-connection-parameters.external-connectors-models.js.map +1 -0
  83. package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.d.ts +6 -0
  84. package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.d.ts.map +1 -1
  85. package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.js +13 -7
  86. package/dist/esm/protocols/provider-oauth2-token-endpoint-hosts.external-connectors-models.js.map +1 -1
  87. package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.d.ts +50 -0
  88. package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.d.ts.map +1 -0
  89. package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.js +30 -0
  90. package/dist/esm/protocols/provider-vendor-registration.external-connectors-models.js.map +1 -0
  91. package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.d.ts +730 -17
  92. package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.d.ts.map +1 -1
  93. package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.js +822 -20
  94. package/dist/esm/protocols/rest-operations.external-connectors-models.schemas.js.map +1 -1
  95. package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.d.ts +73 -0
  96. package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.d.ts.map +1 -0
  97. package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.js +82 -0
  98. package/dist/esm/protocols/service-account-token.external-connectors-models.schemas.js.map +1 -0
  99. package/dist/esm/protocols/sms.external-connectors-models.schemas.d.ts.map +1 -1
  100. package/dist/esm/protocols/sms.external-connectors-models.schemas.js.map +1 -1
  101. package/dist/esm/protocols/sms.standard-interface.schemas.d.ts +79 -1
  102. package/dist/esm/protocols/sms.standard-interface.schemas.d.ts.map +1 -1
  103. package/dist/esm/protocols/sms.standard-interface.schemas.js +93 -0
  104. package/dist/esm/protocols/sms.standard-interface.schemas.js.map +1 -1
  105. package/dist/esm/protocols/subject-erasure-effect.standard-interface.d.ts.map +1 -1
  106. package/dist/esm/protocols/subject-erasure-effect.standard-interface.js.map +1 -1
  107. package/dist/tsconfig.build.tsbuildinfo +1 -1
  108. package/package.json +5 -5
  109. package/dist/esm/.native.tsbuildinfo +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-capability.external-connectors-models.schemas.js","sourceRoot":"","sources":["../../../../src/protocols/hooks-capability.external-connectors-models.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG","sourcesContent":["/**\n * Hook Protocol Feature Types\n * \n * Standard types for the webhook processing pipeline:\n * - StandardHook_ParsedEvent: Provider-agnostic parsed event\n * - StandardHook_ResolvedScope: Resolved engine scope from event\n * - WebhookCapabilityAdapter: Runtime contract for verify + parse\n * - WebhookCapabilityHandler: Dispatches processed events to business logic\n * - Hook_ScopeResolverStrategy: Escape hatch for custom scope resolution\n */\n\n// ===============================================================\n// Standard Parsed Event (Provider-Agnostic)\n// ===============================================================\n\n/**\n * A webhook event normalized to a provider-agnostic format.\n * Produced by WebhookCapabilityAdapter.parseEvent().\n */\nexport interface StandardHook_ParsedEvent {\n /** Unique event ID from the provider (for idempotency) */\n eventId: string;\n /** Standardized event type (e.g., 'SUBSCRIPTION_CREATED') */\n eventType: string;\n /** Original provider event type (e.g., 'customer.subscription.created') */\n providerEventType: string;\n /** Provider reference (e.g., 'stripe', 'google') */\n providerRef: string;\n /** Endpoint key this event was received on (e.g., 'billing', 'calendar') */\n endpointKey: string;\n /** Parsed event payload (provider-specific structure) */\n payload: unknown;\n /** Raw event payload as received (for scope ID extraction via dot-path) */\n rawPayload: unknown;\n /** Event timestamp */\n timestamp: Date | string;\n}\n\n// ===============================================================\n// Standard Resolved Scope\n// ===============================================================\n\n/**\n * Framework scope resolved from a webhook event.\n * Maps to ExecutionContext initiatorIds fields.\n */\nexport interface StandardHook_ResolvedScope {\n applicationId?: string;\n organizationId?: string;\n userId?: string;\n /** Additional provider-specific scope IDs for audit/debug */\n providerScopeIds?: Record<string, string>;\n}\n\n// ===============================================================\n// Webhook Capability Adapter\n// ===============================================================\n\n/**\n * Adapter that bridges a capability-specific transformer\n * (e.g., StandardBilling_Interface) to the generic webhook pipeline.\n * \n * Each capability implements one adapter. The adapter normalizes\n * capability-specific verify/parse methods into the standard pipeline contract.\n * \n * Example: BillingWebhookAdapter wraps Stripe_BillingTransformer.verifyWebhookSignature()\n * and parseWebhookEvent() into the standard interface.\n */\nexport interface WebhookCapabilityAdapter {\n /**\n * Verify the webhook signature using the capability's verification logic.\n *\n * `headers` is EVERY request header, names lower-cased (#2659): a scheme that signs a timestamp or an id\n * carried in a second header cannot be verified from the signature header alone.\n */\n verifySignature(\n rawBody: string | Uint8Array,\n signatureHeader: string,\n secret: string,\n headers: Readonly<Record<string, string>>,\n ): boolean | Promise<boolean>;\n\n /** \n * Parse the raw webhook body into a StandardHook_ParsedEvent.\n * Returns null if the event type is unknown/unsupported (acknowledged but not processed).\n */\n parseEvent(\n rawBody: string | Uint8Array, \n headers: Record<string, string>\n ): StandardHook_ParsedEvent | null;\n}\n\n// ===============================================================\n// Webhook Capability Handler\n// ===============================================================\n\n/**\n * Handles processed webhook events for a specific capability.\n * Dispatches to business logic (e.g., BillingWebhookEventRouter) with the ExecutionContext.\n * \n * Registered at startup and matched by endpoint capability.\n */\nexport interface WebhookCapabilityHandler {\n /** Which capability this handler serves (e.g., 'billing', 'calendar') */\n readonly capability: string;\n\n /** \n * Handle the processed webhook event with its execution context.\n * The executionContext carries the resolved scope and can be used for all DB operations.\n */\n handleEvent(\n executionContext: unknown, // ExecutionContext<any> — typed as unknown to avoid circular dependency\n parsedEvent: StandardHook_ParsedEvent\n ): Promise<void>;\n}\n\n// ===============================================================\n// Hook Scope Resolver Strategy (Escape Hatch)\n// ===============================================================\n\n/**\n * Optional override for scope resolution when the declarative\n * Hook_EndpointScopeBinding config is insufficient.\n * \n * Register with WebhookHandlerBackendService.registerCustomScopeResolver()\n * to override the generic declarative resolver for a specific endpoint.\n * \n * Use cases:\n * - Different event types within the same endpoint have scope IDs at different payload paths\n * - Complex multi-step scope resolution logic\n * - Provider-specific edge cases\n */\nexport interface Hook_ScopeResolverStrategy {\n /** Provider reference this resolver handles */\n readonly providerRef: string;\n /** Endpoint key this resolver handles */\n readonly endpointKey: string;\n\n /** Resolve the engine scope from a parsed event */\n resolveScope(parsedEvent: StandardHook_ParsedEvent): Promise<StandardHook_ResolvedScope>;\n\n /** Whether scope resolution is required for this event type (affects error handling) */\n isScopeRequired(eventType: string): boolean;\n}\n"]}
1
+ {"version":3,"file":"hooks-capability.external-connectors-models.schemas.js","sourceRoot":"","sources":["../../../src/protocols/hooks-capability.external-connectors-models.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG","sourcesContent":["/**\n * Hook Protocol Feature Types\n * \n * Standard types for the webhook processing pipeline:\n * - StandardHook_ParsedEvent: Provider-agnostic parsed event\n * - StandardHook_ResolvedScope: Resolved engine scope from event\n * - WebhookCapabilityAdapter: Runtime contract for verify + parse\n * - WebhookCapabilityHandler: Dispatches processed events to business logic\n * - Hook_ScopeResolverStrategy: Escape hatch for custom scope resolution\n */\n\n// ===============================================================\n// Standard Parsed Event (Provider-Agnostic)\n// ===============================================================\n\n/**\n * A webhook event normalized to a provider-agnostic format.\n * Produced by WebhookCapabilityAdapter.parseEvent().\n */\nexport interface StandardHook_ParsedEvent {\n /** Unique event ID from the provider (for idempotency) */\n eventId: string;\n /** Standardized event type (e.g., 'SUBSCRIPTION_CREATED') */\n eventType: string;\n /** Original provider event type (e.g., 'customer.subscription.created') */\n providerEventType: string;\n /** Provider reference (e.g., 'stripe', 'google') */\n providerRef: string;\n /** Endpoint key this event was received on (e.g., 'billing', 'calendar') */\n endpointKey: string;\n /** Parsed event payload (provider-specific structure) */\n payload: unknown;\n /** Raw event payload as received (for scope ID extraction via dot-path) */\n rawPayload: unknown;\n /** Event timestamp */\n timestamp: Date | string;\n}\n\n// ===============================================================\n// Standard Resolved Scope\n// ===============================================================\n\n/**\n * Framework scope resolved from a webhook event.\n * Maps to ExecutionContext initiatorIds fields.\n */\nexport interface StandardHook_ResolvedScope {\n applicationId?: string;\n organizationId?: string;\n userId?: string;\n /** Additional provider-specific scope IDs for audit/debug */\n providerScopeIds?: Record<string, string>;\n}\n\n// ===============================================================\n// Webhook Capability Adapter\n// ===============================================================\n\n/**\n * Adapter that bridges a capability-specific transformer\n * (e.g., StandardBilling_Interface) to the generic webhook pipeline.\n * \n * Each capability implements one adapter. The adapter normalizes\n * capability-specific verify/parse methods into the standard pipeline contract.\n * \n * Example: BillingWebhookAdapter wraps Stripe_BillingTransformer.verifyWebhookSignature()\n * and parseWebhookEvent() into the standard interface.\n */\nexport interface WebhookCapabilityAdapter {\n /**\n * Verify the webhook signature using the capability's verification logic.\n *\n * `headers` is EVERY request header, names lower-cased (#2659): a scheme that signs a timestamp or an id\n * carried in a second header cannot be verified from the signature header alone.\n */\n verifySignature(\n rawBody: string | Uint8Array,\n signatureHeader: string,\n secret: string,\n headers: Readonly<Record<string, string>>,\n ): boolean | Promise<boolean>;\n\n /** \n * Parse the raw webhook body into a StandardHook_ParsedEvent.\n * Returns null if the event type is unknown/unsupported (acknowledged but not processed).\n */\n parseEvent(\n rawBody: string | Uint8Array, \n headers: Record<string, string>\n ): StandardHook_ParsedEvent | null;\n}\n\n// ===============================================================\n// Webhook Capability Handler\n// ===============================================================\n\n/**\n * Handles processed webhook events for a specific capability.\n * Dispatches to business logic (e.g., BillingWebhookEventRouter) with the ExecutionContext.\n * \n * Registered at startup and matched by endpoint capability.\n */\nexport interface WebhookCapabilityHandler {\n /** Which capability this handler serves (e.g., 'billing', 'calendar') */\n readonly capability: string;\n\n /** \n * Handle the processed webhook event with its execution context.\n * The executionContext carries the resolved scope and can be used for all DB operations.\n */\n handleEvent(\n executionContext: unknown, // ExecutionContext<any> — typed as unknown to avoid circular dependency\n parsedEvent: StandardHook_ParsedEvent\n ): Promise<void>;\n}\n\n// ===============================================================\n// Hook Scope Resolver Strategy (Escape Hatch)\n// ===============================================================\n\n/**\n * Optional override for scope resolution when the declarative\n * Hook_EndpointScopeBinding config is insufficient.\n * \n * Register with WebhookHandlerBackendService.registerCustomScopeResolver()\n * to override the generic declarative resolver for a specific endpoint.\n * \n * Use cases:\n * - Different event types within the same endpoint have scope IDs at different payload paths\n * - Complex multi-step scope resolution logic\n * - Provider-specific edge cases\n */\nexport interface Hook_ScopeResolverStrategy {\n /** Provider reference this resolver handles */\n readonly providerRef: string;\n /** Endpoint key this resolver handles */\n readonly endpointKey: string;\n\n /** Resolve the engine scope from a parsed event */\n resolveScope(parsedEvent: StandardHook_ParsedEvent): Promise<StandardHook_ResolvedScope>;\n\n /** Whether scope resolution is required for this event type (affects error handling) */\n isScopeRequired(eventType: string): boolean;\n}\n"]}
@@ -123,7 +123,91 @@ export declare enum Hook_SignatureAlgorithm {
123
123
  * — "Authenticate requests from the Bot Connector service to your bot", steps 2-4 and the seven
124
124
  * numbered token requirements.
125
125
  */
126
- BOT_FRAMEWORK_JWT = "bot-framework-jwt"
126
+ BOT_FRAMEWORK_JWT = "bot-framework-jwt",
127
+ /**
128
+ * An Ed25519 signature over `{timestamp}{signedContentSeparator}{raw body}`, verified by the ENGINE (#3393) against
129
+ * the vendor's PUBLIC key, for vendors that sign asymmetrically: Telnyx and Discord interactions. The endpoint's
130
+ * secret resolves to that public key, which is not a secret (both vendors publish it in their portal), as 32 raw
131
+ * bytes in hex (Discord) or base64 (Telnyx). The signature header carries 64 bytes in hex or base64, told apart by
132
+ * length. The vendors differ in their header names and in the text between the timestamp and the body, so this
133
+ * scheme reads them from the declaration, and refuses one that omits any of them: `headerName` (the signature),
134
+ * `timestampHeader`, and `signedContentSeparator` (`|` for Telnyx, the empty string for Discord). A mis-declared
135
+ * separator or header can only refuse a genuine request, never admit a forged one: the check is the vendor's key.
136
+ * The signed timestamp must fall within five minutes of now. Neither vendor signs a delivery id, so the endpoint
137
+ * names its events with `identifyEvent`.
138
+ *
139
+ * spec-cite: https://www.rubydoc.info/gems/telnyx/Telnyx/Lib/WebhookVerification — Telnyx's own SDK:
140
+ * `telnyx-signature-ed25519` / `telnyx-timestamp` headers, `signed_payload = "#{timestamp}|#{payload}"`, a
141
+ * strict-base64 signature, a "Base64-encoded raw 32-byte Ed25519 public key", `DEFAULT_TOLERANCE = 300` seconds.
142
+ * spec-cite: https://docs.discord.com/developers/interactions/overview — "Security and Authorization":
143
+ * `X-Signature-Ed25519` / `X-Signature-Timestamp`, the examples' `timestamp + body` with no separator, the
144
+ * signature and the public key decoded from hex.
145
+ */
146
+ ED25519 = "ed25519",
147
+ /**
148
+ * HTTP Basic credentials, verified by the ENGINE (#3395), for a vendor that signs nothing and authenticates its
149
+ * webhook only with the credentials an operator writes into the webhook URL: Postmark's inbound webhook. The
150
+ * endpoint's secret resolves to `user-id:password`, and the request must carry `Authorization: Basic <base64 of
151
+ * those bytes>`, compared in constant time. An empty secret, or one that is not `user-id:password` with both parts
152
+ * present, refuses every request, so a delivery is never accepted unauthenticated. The credential travels in every
153
+ * request and signs neither the body nor a timestamp: it proves who sent the request, not what it carries, so it is
154
+ * worth what the TLS protecting it is worth. Nothing names a delivery, so the endpoint names its events with
155
+ * `identifyEvent`.
156
+ *
157
+ * spec-cite: https://postmarkapp.com/developer/user-guide/inbound/configure-an-inbound-server (fetched 2026-11-09)
158
+ * — "we support HTTP Basic authentication", the credentials given in the webhook URL.
159
+ * spec-cite: RFC 7617 §2 — the user-pass is the user-id, a single colon and the password, Base64-encoded
160
+ * (RFC 4648 §4) in the `token68` credentials of the `Basic` scheme; "a user-id containing a colon character is
161
+ * invalid".
162
+ */
163
+ BASIC_CREDENTIAL = "basic-credential",
164
+ /**
165
+ * A Mailgun route's JSON forward, verified by the ENGINE (#3395): a route whose `forward()` URL ends in `json` posts
166
+ * the parsed message as one JSON document and carries the signature in headers. It is the hex HMAC-SHA256, keyed
167
+ * with the account's webhook signing key, of `{X-Mailgun-Timestamp}{raw body}` (Mailgun's `timestamp + token`, with
168
+ * the whole body in place of the token), in `X-Mailgun-Signature`; a subaccount's domain also carries
169
+ * `X-Mailgun-Parent-Signature`, the same HMAC under the primary account's key, and either may match the key in the
170
+ * slot. The signed timestamp may be at most nine hours old, which covers Mailgun's eight hours of retries, and five
171
+ * minutes ahead. The
172
+ * header names are Mailgun's, so the endpoint declares nothing beyond the algorithm. Mailgun signs no delivery id, so
173
+ * the endpoint names its events with `identifyEvent`.
174
+ *
175
+ * A forward URL not ending in `json` posts a form (urlencoded, or multipart with attachments) with the signature in
176
+ * body fields; the engine neither decodes that body nor verifies that signature, so such a route is refused (415).
177
+ *
178
+ * spec-cite: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/receive-http (fetched
179
+ * 2026-11-09) — the destination-URL table, and "JSON Payload Format" › "Signature verification".
180
+ * spec-cite: https://documentation.mailgun.com/docs/mailgun/user-manual/webhooks/securing-webhooks (fetched
181
+ * 2026-11-09) — the signature as hex HMAC-SHA256 of `timestamp + token`, and `parent-signature`.
182
+ */
183
+ MAILGUN_FORWARD_JSON = "mailgun-forward-json",
184
+ /**
185
+ * Twilio's request signature (#3394), verified by the ENGINE: the base64 HMAC-SHA1, keyed with the account's auth
186
+ * token, of the full URL Twilio called (scheme to query string) followed by every POST parameter, sorted by name,
187
+ * each written as its name then its value with no delimiter. A parameter sent more than once contributes each of
188
+ * its distinct values, sorted, after its name. The signature is carried in the declared `headerName`
189
+ * (`x-twilio-signature`).
190
+ *
191
+ * The URL is part of what is signed, so the engine composes it from the application's public API URL
192
+ * (`runtime.endPoints[MAIN_BACKEND_API].publicUrl`) and the path and query string the request arrived on, and tries
193
+ * it with and without an explicit default port, as Twilio's own helper does. No public URL configured, every request
194
+ * is refused. The endpoint's secret resolves to the auth token, or to the `accountId:secret` bundle the SMS arm reads
195
+ * (`SmsProviderCredentialShape.ACCOUNT_ID_AND_SECRET`), whose secret half IS the auth token: one value, never a copy
196
+ * that can drift from it. Form bodies only: Twilio signs a JSON body through a `bodySHA256` query parameter, which
197
+ * this scheme refuses rather than half-checks.
198
+ *
199
+ * Twilio signs no timestamp and no delivery id, so a captured request stays valid: the endpoint names its event
200
+ * (`identifyEvent`), and the inbound ledger stores one delivery per event, so a replay is stored once and runs nothing.
201
+ *
202
+ * spec-cite: https://www.twilio.com/docs/usage/security (fetched 2026-11-09) — "Validating requests are coming from
203
+ * Twilio": the full URL "from the protocol (https...)" through the query string; POST parameters sorted "using
204
+ * Unix-style case-sensitive sorting order"; "append the variable name and value (with no delimiters)"; HMAC-SHA1
205
+ * with the AuthToken; Base64; and SMS over HTTP(S) keeps the port.
206
+ * spec-cite: https://github.com/twilio/twilio-node/blob/main/src/webhooks/webhooks.ts (fetched 2026-11-09) —
207
+ * `getExpectedTwilioSignature` (keys sorted, `toFormUrlEncodedParam` appends each de-duplicated, sorted array value
208
+ * after its name) and `validateRequest` (the URL tried with the port removed and added).
209
+ */
210
+ TWILIO_HMAC_SHA1 = "twilio-hmac-sha1"
127
211
  }
128
212
  /**
129
213
  * The algorithms the ENGINE verifies itself. An endpoint naming one needs no provider adapter, and cannot be
@@ -131,6 +215,14 @@ export declare enum Hook_SignatureAlgorithm {
131
215
  * provider package. Every other algorithm is verified by the adapter its provider registers.
132
216
  */
133
217
  export declare const HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS: ReadonlySet<Hook_SignatureAlgorithm>;
218
+ /**
219
+ * Whether an endpoint's signature declaration names everything its scheme reads from it. `ED25519` reads more
220
+ * than its algorithm (#3393): the signature header, the timestamp header (never optional: an unsigned or absent
221
+ * timestamp leaves a captured request replayable for ever) and the separator. `TWILIO_HMAC_SHA1` reads its signature
222
+ * header (#3394). The engine withholds the route of an incomplete declaration, and refuses a request reaching one,
223
+ * rather than guessing a vendor's construction.
224
+ */
225
+ export declare function hookSignatureDeclarationIsComplete(config: Pick<Hook_SignatureConfig, 'algorithm' | 'headerName' | 'timestampHeader' | 'signedContentSeparator'>): boolean;
134
226
  /** @wildo_source:part:end external-connectors.models.hook-signature-algorithms */
135
227
  export declare enum Hook_DeliveryStatus {
136
228
  PENDING = "pending",
@@ -144,6 +236,7 @@ export declare const Hook_SignatureConfigSchema: z.ZodObject<{
144
236
  timestampHeader: z.ZodOptional<z.ZodString>;
145
237
  prefix: z.ZodOptional<z.ZodString>;
146
238
  organizationAudienceFact: z.ZodOptional<z.ZodString>;
239
+ signedContentSeparator: z.ZodOptional<z.ZodString>;
147
240
  }, z.core.$strip>;
148
241
  export type Hook_SignatureConfig = z.infer<typeof Hook_SignatureConfigSchema>;
149
242
  export declare const Hook_TriggerSpecSchema: z.ZodObject<{
@@ -157,6 +250,7 @@ export declare const Hook_TriggerSpecSchema: z.ZodObject<{
157
250
  timestampHeader: z.ZodOptional<z.ZodString>;
158
251
  prefix: z.ZodOptional<z.ZodString>;
159
252
  organizationAudienceFact: z.ZodOptional<z.ZodString>;
253
+ signedContentSeparator: z.ZodOptional<z.ZodString>;
160
254
  }, z.core.$strip>>;
161
255
  pollingIntervalMs: z.ZodOptional<z.ZodNumber>;
162
256
  deduplicationKey: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.external-connectors-models.schemas.d.ts","sourceRoot":"","sources":["../../../../src/protocols/hooks.external-connectors-models.schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hooks.external-connectors-models.schemas.d.ts","sourceRoot":"","sources":["../../../src/protocols/hooks.external-connectors-models.schemas.ts"],"names":[],"mappings":"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"}
@@ -138,6 +138,90 @@ export var Hook_SignatureAlgorithm;
138
138
  * numbered token requirements.
139
139
  */
140
140
  Hook_SignatureAlgorithm["BOT_FRAMEWORK_JWT"] = "bot-framework-jwt";
141
+ /**
142
+ * An Ed25519 signature over `{timestamp}{signedContentSeparator}{raw body}`, verified by the ENGINE (#3393) against
143
+ * the vendor's PUBLIC key, for vendors that sign asymmetrically: Telnyx and Discord interactions. The endpoint's
144
+ * secret resolves to that public key, which is not a secret (both vendors publish it in their portal), as 32 raw
145
+ * bytes in hex (Discord) or base64 (Telnyx). The signature header carries 64 bytes in hex or base64, told apart by
146
+ * length. The vendors differ in their header names and in the text between the timestamp and the body, so this
147
+ * scheme reads them from the declaration, and refuses one that omits any of them: `headerName` (the signature),
148
+ * `timestampHeader`, and `signedContentSeparator` (`|` for Telnyx, the empty string for Discord). A mis-declared
149
+ * separator or header can only refuse a genuine request, never admit a forged one: the check is the vendor's key.
150
+ * The signed timestamp must fall within five minutes of now. Neither vendor signs a delivery id, so the endpoint
151
+ * names its events with `identifyEvent`.
152
+ *
153
+ * spec-cite: https://www.rubydoc.info/gems/telnyx/Telnyx/Lib/WebhookVerification — Telnyx's own SDK:
154
+ * `telnyx-signature-ed25519` / `telnyx-timestamp` headers, `signed_payload = "#{timestamp}|#{payload}"`, a
155
+ * strict-base64 signature, a "Base64-encoded raw 32-byte Ed25519 public key", `DEFAULT_TOLERANCE = 300` seconds.
156
+ * spec-cite: https://docs.discord.com/developers/interactions/overview — "Security and Authorization":
157
+ * `X-Signature-Ed25519` / `X-Signature-Timestamp`, the examples' `timestamp + body` with no separator, the
158
+ * signature and the public key decoded from hex.
159
+ */
160
+ Hook_SignatureAlgorithm["ED25519"] = "ed25519";
161
+ /**
162
+ * HTTP Basic credentials, verified by the ENGINE (#3395), for a vendor that signs nothing and authenticates its
163
+ * webhook only with the credentials an operator writes into the webhook URL: Postmark's inbound webhook. The
164
+ * endpoint's secret resolves to `user-id:password`, and the request must carry `Authorization: Basic <base64 of
165
+ * those bytes>`, compared in constant time. An empty secret, or one that is not `user-id:password` with both parts
166
+ * present, refuses every request, so a delivery is never accepted unauthenticated. The credential travels in every
167
+ * request and signs neither the body nor a timestamp: it proves who sent the request, not what it carries, so it is
168
+ * worth what the TLS protecting it is worth. Nothing names a delivery, so the endpoint names its events with
169
+ * `identifyEvent`.
170
+ *
171
+ * spec-cite: https://postmarkapp.com/developer/user-guide/inbound/configure-an-inbound-server (fetched 2026-11-09)
172
+ * — "we support HTTP Basic authentication", the credentials given in the webhook URL.
173
+ * spec-cite: RFC 7617 §2 — the user-pass is the user-id, a single colon and the password, Base64-encoded
174
+ * (RFC 4648 §4) in the `token68` credentials of the `Basic` scheme; "a user-id containing a colon character is
175
+ * invalid".
176
+ */
177
+ Hook_SignatureAlgorithm["BASIC_CREDENTIAL"] = "basic-credential";
178
+ /**
179
+ * A Mailgun route's JSON forward, verified by the ENGINE (#3395): a route whose `forward()` URL ends in `json` posts
180
+ * the parsed message as one JSON document and carries the signature in headers. It is the hex HMAC-SHA256, keyed
181
+ * with the account's webhook signing key, of `{X-Mailgun-Timestamp}{raw body}` (Mailgun's `timestamp + token`, with
182
+ * the whole body in place of the token), in `X-Mailgun-Signature`; a subaccount's domain also carries
183
+ * `X-Mailgun-Parent-Signature`, the same HMAC under the primary account's key, and either may match the key in the
184
+ * slot. The signed timestamp may be at most nine hours old, which covers Mailgun's eight hours of retries, and five
185
+ * minutes ahead. The
186
+ * header names are Mailgun's, so the endpoint declares nothing beyond the algorithm. Mailgun signs no delivery id, so
187
+ * the endpoint names its events with `identifyEvent`.
188
+ *
189
+ * A forward URL not ending in `json` posts a form (urlencoded, or multipart with attachments) with the signature in
190
+ * body fields; the engine neither decodes that body nor verifies that signature, so such a route is refused (415).
191
+ *
192
+ * spec-cite: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/receive-http (fetched
193
+ * 2026-11-09) — the destination-URL table, and "JSON Payload Format" › "Signature verification".
194
+ * spec-cite: https://documentation.mailgun.com/docs/mailgun/user-manual/webhooks/securing-webhooks (fetched
195
+ * 2026-11-09) — the signature as hex HMAC-SHA256 of `timestamp + token`, and `parent-signature`.
196
+ */
197
+ Hook_SignatureAlgorithm["MAILGUN_FORWARD_JSON"] = "mailgun-forward-json";
198
+ /**
199
+ * Twilio's request signature (#3394), verified by the ENGINE: the base64 HMAC-SHA1, keyed with the account's auth
200
+ * token, of the full URL Twilio called (scheme to query string) followed by every POST parameter, sorted by name,
201
+ * each written as its name then its value with no delimiter. A parameter sent more than once contributes each of
202
+ * its distinct values, sorted, after its name. The signature is carried in the declared `headerName`
203
+ * (`x-twilio-signature`).
204
+ *
205
+ * The URL is part of what is signed, so the engine composes it from the application's public API URL
206
+ * (`runtime.endPoints[MAIN_BACKEND_API].publicUrl`) and the path and query string the request arrived on, and tries
207
+ * it with and without an explicit default port, as Twilio's own helper does. No public URL configured, every request
208
+ * is refused. The endpoint's secret resolves to the auth token, or to the `accountId:secret` bundle the SMS arm reads
209
+ * (`SmsProviderCredentialShape.ACCOUNT_ID_AND_SECRET`), whose secret half IS the auth token: one value, never a copy
210
+ * that can drift from it. Form bodies only: Twilio signs a JSON body through a `bodySHA256` query parameter, which
211
+ * this scheme refuses rather than half-checks.
212
+ *
213
+ * Twilio signs no timestamp and no delivery id, so a captured request stays valid: the endpoint names its event
214
+ * (`identifyEvent`), and the inbound ledger stores one delivery per event, so a replay is stored once and runs nothing.
215
+ *
216
+ * spec-cite: https://www.twilio.com/docs/usage/security (fetched 2026-11-09) — "Validating requests are coming from
217
+ * Twilio": the full URL "from the protocol (https...)" through the query string; POST parameters sorted "using
218
+ * Unix-style case-sensitive sorting order"; "append the variable name and value (with no delimiters)"; HMAC-SHA1
219
+ * with the AuthToken; Base64; and SMS over HTTP(S) keeps the port.
220
+ * spec-cite: https://github.com/twilio/twilio-node/blob/main/src/webhooks/webhooks.ts (fetched 2026-11-09) —
221
+ * `getExpectedTwilioSignature` (keys sorted, `toFormUrlEncodedParam` appends each de-duplicated, sorted array value
222
+ * after its name) and `validateRequest` (the URL tried with the port removed and added).
223
+ */
224
+ Hook_SignatureAlgorithm["TWILIO_HMAC_SHA1"] = "twilio-hmac-sha1";
141
225
  })(Hook_SignatureAlgorithm || (Hook_SignatureAlgorithm = {}));
142
226
  /**
143
227
  * The algorithms the ENGINE verifies itself. An endpoint naming one needs no provider adapter, and cannot be
@@ -148,7 +232,28 @@ export const HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS = new Set([
148
232
  Hook_SignatureAlgorithm.SVIX_V1,
149
233
  Hook_SignatureAlgorithm.SLACK_V0,
150
234
  Hook_SignatureAlgorithm.BOT_FRAMEWORK_JWT,
235
+ Hook_SignatureAlgorithm.ED25519,
236
+ Hook_SignatureAlgorithm.BASIC_CREDENTIAL,
237
+ Hook_SignatureAlgorithm.MAILGUN_FORWARD_JSON,
238
+ Hook_SignatureAlgorithm.TWILIO_HMAC_SHA1,
151
239
  ]);
240
+ /**
241
+ * Whether an endpoint's signature declaration names everything its scheme reads from it. `ED25519` reads more
242
+ * than its algorithm (#3393): the signature header, the timestamp header (never optional: an unsigned or absent
243
+ * timestamp leaves a captured request replayable for ever) and the separator. `TWILIO_HMAC_SHA1` reads its signature
244
+ * header (#3394). The engine withholds the route of an incomplete declaration, and refuses a request reaching one,
245
+ * rather than guessing a vendor's construction.
246
+ */
247
+ export function hookSignatureDeclarationIsComplete(config) {
248
+ // TWILIO_HMAC_SHA1 (#3394) reads its signature from the declared header, so an empty one could only refuse.
249
+ if (config.algorithm === Hook_SignatureAlgorithm.TWILIO_HMAC_SHA1)
250
+ return typeof config.headerName === 'string' && config.headerName.length > 0;
251
+ if (config.algorithm !== Hook_SignatureAlgorithm.ED25519)
252
+ return true;
253
+ return typeof config.headerName === 'string' && config.headerName.length > 0
254
+ && typeof config.timestampHeader === 'string' && config.timestampHeader.length > 0
255
+ && typeof config.signedContentSeparator === 'string';
256
+ }
152
257
  /** @wildo_source:part:end external-connectors.models.hook-signature-algorithms */
153
258
  export var Hook_DeliveryStatus;
154
259
  (function (Hook_DeliveryStatus) {
@@ -174,6 +279,11 @@ export const Hook_SignatureConfigSchema = z.object({
174
279
  * then carries that organization. Absent: the application's own bot is the only audience.
175
280
  */
176
281
  organizationAudienceFact: z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/).optional(),
282
+ /**
283
+ * `ED25519` only (#3393), and required there: the text the vendor puts between the signed timestamp and the raw
284
+ * body in the content it signs. `'|'` for Telnyx; `''` for Discord, which concatenates the two.
285
+ */
286
+ signedContentSeparator: z.string().max(8).optional(),
177
287
  });
178
288
  // ===============================================================
179
289
  // Webhook Trigger Spec
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.external-connectors-models.schemas.js","sourceRoot":"","sources":["../../../../src/protocols/hooks.external-connectors-models.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { \n API_HttpMethod, \n ExternalProvider_ExchangeProtocol_Configuration_Base, \n ExternalProvider_ExchangeProtocol_Kind \n} from \"../core/commons.external-connectors-models.schemas\";\nimport { ExternalProvider_Auth_Kind } from \"../core/security.external-connectors-models.schemas\";\nimport { ExternalProvider_OperationContextSchema, ExternalProvider_OperationDefinition_Base } from \"../core/operations.external-connectors-models.schemas\";\n\n//===============================================================\n// Webhook/Hooks Provider\n// --------\n// Schema definitions for webhook integrations.\n// Supports event subscriptions, signature verification, and\n// delivery management.\n//===============================================================\n\n// ===============================================================\n// Webhook Enums\n// ===============================================================\n\nexport const Hook_HttpMethods: readonly API_HttpMethod[] = [\n API_HttpMethod.POST,\n API_HttpMethod.PUT,\n API_HttpMethod.PATCH,\n];\n\nexport const Hook_SecurityType: readonly ExternalProvider_Auth_Kind[] = [\n ExternalProvider_Auth_Kind.NONE,\n ExternalProvider_Auth_Kind.HMAC_SIGNATURE,\n ExternalProvider_Auth_Kind.BEARER,\n ExternalProvider_Auth_Kind.BASIC,\n];\n\nexport enum Hook_ContentType {\n JSON = \"application/json\",\n FORM_URLENCODED = \"application/x-www-form-urlencoded\",\n XML = \"application/xml\",\n}\n\n/** @wildo_source:part:start external-connectors.models.hook-trigger-strategy facet:kind:api facet:audience:app-developer */\n/**\n * How a provider endpoint's requests are TRUSTED, and so what the engine does with them. A trust posture, kept apart from\n * {@link Hook_SignatureAlgorithm}, which only says how a signature is checked.\n */\nexport enum Hook_TriggerStrategy {\n /** The vendor pushes events, verified by the endpoint's `signatureConfig`; a verified event is stored and handled. */\n WEBHOOK = \"webhook\",\n POLLING = \"polling\",\n APP_WEBHOOK = \"app_webhook\",\n /**\n * The vendor pushes a NOTIFICATION nobody can verify (#2909): it signs nothing (IgniSign). The request is never\n * trusted. It only names an object (`reReadTrigger.identifyReference`), and the engine:\n * - answers 202 whatever happens, so a sender learns nothing about which references exist;\n * - drops it unless the endpoint's handler resolves the reference to a record of this application;\n * - stores only the reference, under an id derived from the reference and a coalescing window, so one reference\n * causes at most one re-read per window, one at a time, and a notification after that window's re-read is kept for\n * the next window rather than lost;\n * - limits the endpoint's request rate, and charges the re-read to a share of the vendor's declared rate budget, so a\n * flood never spends what polling needs. The provider must therefore DECLARE a budget (`rateBudgets` on its\n * connection, or `maxRequestsPerMinute`); without one the route is withheld.\n * The handler then RE-READS the object from the vendor's authenticated API: what the record becomes is what the\n * vendor answered there, never what the notification said. Its handler resolves the reference to a record in an\n * organization or a person's data, never the application scope. Polling remains the latency floor under attack.\n * Such an endpoint declares no `signatureConfig`.\n */\n WEBHOOK_TRIGGERS_POLL = \"webhook_triggers_poll\",\n}\n\n/**\n * What a {@link Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL} endpoint declares (#2909). Pure functions and numbers only:\n * the request is unverified, so nothing in it is believed beyond the reference it names.\n */\nexport interface Hook_ReReadTrigger {\n /**\n * The vendor's reference to the object the notification is about (a signature request id), read from the decoded,\n * UNVERIFIED body, or `null` when it names none. It is only ever looked up and re-read, never trusted. Pure: no I/O.\n */\n readonly identifyReference: (request: Hook_InboundRequest) => string | null;\n /**\n * The coalescing window, in seconds (default {@link HOOK_REREAD_TRIGGER_DEFAULT_COALESCING_WINDOW_SECONDS}): a reference\n * is re-read at most once per window, the windows aligned on the clock. A notification arriving once its window's\n * re-read is already stored is kept for the NEXT window, due at its start, so the last change a vendor reports is\n * never lost. A positive integer; the route is withheld otherwise.\n */\n readonly coalescingWindowSeconds?: number;\n /**\n * The most requests the endpoint takes per window, from every sender together (default\n * {@link HOOK_REREAD_TRIGGER_DEFAULT_RATE_LIMIT}). Past it a request is dropped, still answered 202. Positive integers.\n */\n readonly rateLimit?: { readonly maxRequests: number; readonly windowSeconds: number };\n}\n\n/** The default coalescing window of a re-read trigger: one re-read per reference per minute. */\nexport const HOOK_REREAD_TRIGGER_DEFAULT_COALESCING_WINDOW_SECONDS = 60;\n/** The default request rate of a re-read trigger endpoint, all senders together. */\nexport const HOOK_REREAD_TRIGGER_DEFAULT_RATE_LIMIT = { maxRequests: 120, windowSeconds: 60 } as const;\n\n/**\n * Whether an endpoint only triggers re-reads (#2909): its requests are never verified, never trusted. Decided by an\n * exhaustive switch, so a strategy added tomorrow must be classified here before anything compiles (review F9).\n */\nexport function isReReadTriggerEndpoint(endpoint: Pick<Hook_Endpoint, 'triggerStrategy'>): boolean {\n switch (endpoint.triggerStrategy) {\n case Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL:\n return true;\n case Hook_TriggerStrategy.WEBHOOK:\n case Hook_TriggerStrategy.POLLING:\n case Hook_TriggerStrategy.APP_WEBHOOK:\n return false;\n default: {\n // Compile-time: a new member must be classified above. At run time, a value outside the vocabulary takes the SIGNED\n // path, which verifies everything it accepts, so a malformed declaration can never be trusted unverified.\n const unclassified: never = endpoint.triggerStrategy;\n void unclassified;\n return false;\n }\n }\n}\n\n/** Whether a re-read trigger's declared numbers can be enforced: every one a positive integer (#2909 review F6). */\nexport function reReadTriggerLimitsAreSound(trigger: Pick<Hook_ReReadTrigger, 'coalescingWindowSeconds' | 'rateLimit'>): boolean {\n const positiveInteger = (value: number | undefined) => value === undefined || (Number.isSafeInteger(value) && value >= 1);\n return positiveInteger(trigger.coalescingWindowSeconds)\n && (trigger.rateLimit === undefined || (positiveInteger(trigger.rateLimit.maxRequests) && positiveInteger(trigger.rateLimit.windowSeconds)));\n}\n/** @wildo_source:part:end external-connectors.models.hook-trigger-strategy */\n\nexport enum Hook_HandshakeType {\n NONE = \"none\",\n CHALLENGE_RESPONSE = \"challenge_response\",\n VERIFICATION_TOKEN = \"verification_token\",\n}\n\n/** @wildo_source:part:start external-connectors.models.hook-signature-algorithms facet:kind:api facet:audience:app-developer */\nexport enum Hook_SignatureAlgorithm {\n HMAC_SHA256 = \"hmac-sha256\",\n HMAC_SHA512 = \"hmac-sha512\",\n HMAC_SHA1 = \"hmac-sha1\",\n /**\n * The Svix / Standard Webhooks v1 construction, verified by the ENGINE (#1600): HMAC-SHA256 over\n * `{svix-id}.{svix-timestamp}.{rawBody}` with the base64 key of a `whsec_` secret, any listed `v1,` signature\n * matching, inside a five-minute window. An endpoint declaring it needs no provider adapter — the provider\n * cannot supply a verifier for it, which is the point: the one fail-closed decision of the inbound path stays\n * in engine code. `svix-id` is the delivery's dedup key.\n *\n * spec-cite: https://docs.svix.com/receiving/verifying-payloads/how-manual — headers, signed content, secret\n * format, versioned signature list and timestamp tolerance.\n */\n SVIX_V1 = \"svix-v1\",\n /**\n * Slack's request signing, verified by the ENGINE (#2659): HMAC-SHA256 with the app's signing secret over\n * `v0:{X-Slack-Request-Timestamp}:{raw body}`, sent as `X-Slack-Signature: v0=<hex>`, inside a five-minute\n * window. It covers JSON events and form-encoded interactions and commands alike, because it signs the bytes.\n * Slack signs no delivery id, so the endpoint names its events with `identifyEvent` (an `event_id` or a\n * `trigger_id` read from the verified body).\n *\n * spec-cite: https://docs.slack.dev/authentication/verifying-requests-from-slack — basestring, header names,\n * `v0=` hex signature, raw body, five-minute window.\n */\n SLACK_V0 = \"slack-v0\",\n /**\n * The Bot Framework Connector's bearer token, verified by the ENGINE (#2659), for Microsoft Teams and every\n * other Azure Bot Service channel. The request carries `Authorization: Bearer <JWT>`; the token must be\n * signed with a key from the Connector's published key set under an algorithm its OpenID metadata names,\n * with issuer `https://api.botframework.com`, audience equal to the bot's Microsoft App ID (the value the\n * endpoint's secret resolves to), inside its validity period (five minutes' skew), a `serviceUrl` claim\n * equal to the activity's `serviceUrl`, and a signing key endorsed for the activity's `channelId`.\n * The activity carries its own `id`, which the endpoint's `identifyEvent` returns.\n *\n * spec-cite: https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-authentication\n * — \"Authenticate requests from the Bot Connector service to your bot\", steps 2-4 and the seven\n * numbered token requirements.\n */\n BOT_FRAMEWORK_JWT = \"bot-framework-jwt\",\n}\n\n/**\n * The algorithms the ENGINE verifies itself. An endpoint naming one needs no provider adapter, and cannot be\n * given one: the scheme is engine code, so the one fail-closed decision of the inbound path never moves into a\n * provider package. Every other algorithm is verified by the adapter its provider registers.\n */\nexport const HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS: ReadonlySet<Hook_SignatureAlgorithm> = new Set([\n Hook_SignatureAlgorithm.SVIX_V1,\n Hook_SignatureAlgorithm.SLACK_V0,\n Hook_SignatureAlgorithm.BOT_FRAMEWORK_JWT,\n]);\n/** @wildo_source:part:end external-connectors.models.hook-signature-algorithms */\n\nexport enum Hook_DeliveryStatus {\n PENDING = \"pending\",\n DELIVERED = \"delivered\",\n FAILED = \"failed\",\n RETRYING = \"retrying\",\n}\n\n// ===============================================================\n// Webhook Signature Config\n// ===============================================================\n\nexport const Hook_SignatureConfigSchema = z.object({\n algorithm: z.enum(Hook_SignatureAlgorithm),\n headerName: z.string(), // e.g., \"X-Hub-Signature-256\"\n timestampHeader: z.string().optional(),\n prefix: z.string().optional(), // e.g., \"sha256=\"\n /**\n * `BOT_FRAMEWORK_JWT` only (#2663): the account fact, on an ORGANIZATION's connection to this provider, that names\n * another bot App ID this endpoint admits as a token's audience, beside the application's own bot (the endpoint's\n * secret). A token is admitted for an organization's bot only when that organization's ENABLED connection holds its\n * audience as vendor evidence (`PROVIDER_CONNECTION_ROUTING_FACT_PROVENANCES`): for a bot, `VERIFIED_BY_VENDOR`, the\n * App ID whose secret the token endpoint accepted at connect. Never as an administrator merely typed it. The delivery\n * then carries that organization. Absent: the application's own bot is the only audience.\n */\n organizationAudienceFact: z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/).optional(),\n});\nexport type Hook_SignatureConfig = z.infer<typeof Hook_SignatureConfigSchema>;\n\n// ===============================================================\n// Webhook Trigger Spec\n// ===============================================================\n//\n// Declared for a future webhook-SUBSCRIPTION operation (a provider operation that registers a trigger at the vendor).\n// No engine code reads it today. In particular its handshake fields are NOT how a receiving endpoint answers a URL\n// challenge: that is `Hook_Endpoint.answerHandshake`, a pure function of the verified request (#2659). The declarative\n// `handshakeType` that `Hook_Endpoint` used to carry was removed then, because nothing read it, so a provider setting\n// it got no answer at all.\n\nexport const Hook_TriggerSpecSchema = z.object({\n strategy: z.enum(Hook_TriggerStrategy),\n \n // Events\n eventTypes: z.array(z.string()).optional(),\n \n // Handshake\n handshakeType: z.enum(Hook_HandshakeType).optional(),\n challengeField: z.string().optional(),\n \n // Signature\n signatureConfig: Hook_SignatureConfigSchema.optional(),\n \n // Polling (for POLLING strategy)\n pollingIntervalMs: z.number().optional(),\n deduplicationKey: z.string().optional(),\n \n // Lifecycle\n hasOnEnable: z.boolean().optional(),\n hasOnDisable: z.boolean().optional(),\n});\nexport type Hook_TriggerSpec = z.infer<typeof Hook_TriggerSpecSchema>;\n\n// ===============================================================\n// Webhook Endpoint Scope Binding (Declarative Scope Resolution)\n// ===============================================================\n\n/**\n * Variant config for polymorphic scope resolution.\n * Each entry represents one variant collection to query during lookup.\n */\nexport interface Hook_PolymorphicVariantBinding {\n /** Variant resource type to query (e.g., 'organizationBillingAccounts') */\n resourceType: string;\n /** Parent resource type (e.g., 'organizations') */\n parentResourceType: string;\n /** Parent field identifier — the scope entity ID field on matched documents (e.g., 'organizationId') */\n parentFieldIdentifier: string;\n /** Whether this variant's parent is a primary scope entity */\n isPrimaryScope: boolean;\n}\n\n/**\n * Declarative scope resolution config for a webhook endpoint.\n * \n * Determines how an incoming webhook event is mapped to a engine scope\n * (organization or user) without writing per-capability code.\n * \n * Three modes:\n * - APPLICATION: Global events, no lookup needed.\n * - Single-scope (ORGANIZATIONS / USER_SELF): Extract an ID from the\n * event payload, look up a single resource type, and resolve the scope entity ID.\n * - Polymorphic: Extract an ID from the event payload, query N variant collections\n * in order, and resolve the scope from whichever variant matches. Used when a\n * resource has been polymorphically expanded across multiple scope types.\n */\nexport type Hook_EndpointScopeBinding =\n | {\n /** Global/application-scoped events — no entity lookup needed */\n primaryScope: 'APPLICATION';\n }\n | {\n /** Scoped events — requires payload extraction + resource lookup */\n primaryScope: 'ORGANIZATIONS' | 'USER_SELF';\n /** Dot-path into the parsed event payload to extract the provider's scope ID (e.g., 'data.object.customer') */\n payloadScopeIdPath: string;\n /** Resource type to query for scope resolution (e.g., 'BILLING_ACCOUNTS') */\n lookupResourceType: string;\n /** Field on the resource to match the extracted ID (e.g., 'providerCustomerId') */\n lookupField: string;\n /** Field on the found resource that gives the scope entity ID (defaults to 'organizationId'/'userId' based on primaryScope) */\n scopeEntityIdField?: string;\n /** Event types that don't carry scope — fall back to APPLICATION scope (e.g., 'product.created', 'price.updated') */\n scopeExemptEventTypes?: string[];\n }\n | {\n /** Polymorphic scope resolution — queries multiple variant collections */\n mode: 'polymorphic';\n /** Dot-path into the parsed event payload to extract the provider's scope ID (e.g., 'data.object.customer') */\n payloadScopeIdPath: string;\n /** Field on each variant resource to match the extracted ID (e.g., 'providerCustomerId') */\n lookupField: string;\n /** Variant collections to query, in order. First match wins. */\n variants: Hook_PolymorphicVariantBinding[];\n /** Event types that don't carry scope — fall back to APPLICATION scope (e.g., 'product.created', 'price.updated') */\n scopeExemptEventTypes?: string[];\n /**\n * Per-event-type overrides for payloadScopeIdPath.\n * Keyed by the provider's native event type (e.g., 'customer.deleted').\n * Use when different event types carry the scope ID at different payload paths.\n */\n eventTypeOverrides?: Record<string, { payloadScopeIdPath: string }>;\n };\n\n// ===============================================================\n// The verified request, and what an endpoint answers to it (#2659)\n// ===============================================================\n\n/** @wildo_source:part:start external-connectors.models.hook-inbound-endpoint facet:kind:api facet:audience:app-developer */\n/**\n * A provider request AFTER the engine verified it, as an endpoint's pure functions read it.\n *\n * Only ever built from a request whose signature or token the engine accepted, so everything in it, the\n * decoded body included, is what the sender signed (or, for a bearer-token scheme, what an authenticated\n * sender sent over TLS).\n */\nexport interface Hook_InboundRequest {\n /** The exact bytes received. */\n readonly rawBody: Uint8Array;\n /** Every request header, names lower-cased as Node delivers them. */\n readonly headers: Readonly<Record<string, string | readonly string[] | undefined>>;\n /** The media type the body was decoded as: one of the endpoint's `contentTypes`. */\n readonly contentType: Hook_ContentType;\n /**\n * The decoded body. JSON: the parsed value. A form: its fields, a field sent more than once becoming an array of\n * its values in order; bracket names (`a[b]`) are kept as written, never expanded into objects.\n */\n readonly body: unknown;\n}\n\n/** What identifies one provider event: the id the store deduplicates on, and the type a handler is chosen by. */\nexport interface Hook_InboundEventIdentity {\n /** Unique per event at the provider, and stable across its retries. */\n readonly eventId: string;\n /** The provider's own name for the event (`app_mention`, `block_actions`, `invoke`, …). */\n readonly providerEventType: string;\n}\n\n/**\n * A person's PERSONAL (one-to-one) conversation with the bot, as a verified request names it (#2664 S5b): who the person\n * is (the same account their chat identity link is keyed on) and where the bot can post to them later.\n */\nexport interface Hook_InboundPersonalConversation {\n /** The vendor's workspace or tenant, exactly as the provider's chat accounts write it (a lower-cased tenant id). */\n readonly workspaceRef: string;\n /** The vendor's id for the person, exactly as the provider's chat accounts write it (a lower-cased Entra object id). */\n readonly chatUserId: string;\n /** The conversation's id at the vendor. */\n readonly conversationId: string;\n /** Where the vendor takes messages for that conversation (the Bot Connector's `serviceUrl`). */\n readonly serviceUrl: string;\n}\n\n/**\n * Who sees a chat conversation at the vendor (#2665 S6), which decides where an answer to it may be posted. The chat\n * door reads it from the verified request (`Hook_InboundChatMessage.audience`) and the chat-conversation ledger records it.\n */\nexport enum ChatConversationAudience {\n /** A one-to-one conversation with the bot (a Slack DM, a Teams personal chat): answered in it. */\n DIRECT = 'direct',\n /**\n * A conversation other people read (a channel, a group chat): answered privately, in the asker's own conversation with\n * the bot, with a content-free pointer in the thread. A turn runs with the asker's authority, so its answer may name\n * what the others in the thread cannot see.\n */\n SHARED = 'shared',\n /** A shared conversation that reaches people outside the organization (Slack Connect, a Teams shared channel): the same. */\n SHARED_WITH_EXTERNAL = 'shared_with_external',\n}\n\n/** Whether a vendor conversation is a thread or a flat stream of messages (#2665 S6, plan B11). */\nexport enum Hook_ChatConversationThreading {\n /** A thread (a Slack thread, a Teams channel's reply chain): one conversation for its whole life. */\n THREADED = 'threaded',\n /**\n * A flat conversation (a top-level Slack DM, a Teams personal or group chat): split after a quiet gap measured on the\n * vendor's clock, so one transcript never grows without bound.\n */\n FLAT = 'flat',\n}\n\n/** The person who wrote a chat message, as the provider's chat accounts write them: what their chat identity link is keyed on. */\nexport const Hook_InboundChatSenderSchema = z.object({\n /** The vendor's workspace or tenant (a Slack team id, a Microsoft tenant id). */\n workspaceRef: z.string().min(1),\n /** The vendor's own id for the person (a Slack user id, a Microsoft Entra object id). */\n chatUserId: z.string().min(1),\n /** How the vendor names the person: shown on the link page only, never matched on. */\n chatUserDisplayName: z.string().optional(),\n /** How the vendor names the workspace: shown on the link page only, never matched on. */\n workspaceDisplayName: z.string().optional(),\n});\nexport type Hook_InboundChatSender = z.infer<typeof Hook_InboundChatSenderSchema>;\n\n/**\n * A message a person wrote to the bot, as a verified request carries it (#2665 S6, plan A14). The chat door reads all of\n * it from the request the engine verified, never from a handler, so a handler decides only WHETHER to converse.\n *\n * One schema, the type derived from it (#2665 S6 review L-B): the engine parses what a provider module's `chatMessageOf`\n * returns with this very schema, so a field added here is checked at the engine's boundary the day it is added, and a\n * value the module built wrong (an empty key, a date that is not one) is read as no message.\n */\nexport const Hook_InboundChatMessageSchema = z.object({\n sender: Hook_InboundChatSenderSchema,\n /** The vendor's conversation: a Slack thread or DM channel, a Teams conversation (a channel's reply chain included). */\n conversationKey: z.string().min(1),\n threading: z.enum(Hook_ChatConversationThreading),\n audience: z.enum(ChatConversationAudience),\n /** The vendor's own id for the message, the same on every retry of its delivery: what makes it one message. */\n messageKey: z.string().min(1),\n /** When the vendor says it was sent (Slack's `ts`, a Teams activity's `timestamp`): the clock a flat conversation's epochs follow. */\n sentAt: z.date(),\n /** What the person wrote, the bot's own mention removed. May be empty: the door answers that the message said nothing. */\n text: z.string(),\n /** Where an answer to this message goes, serialized by the vendor module and parsed back by its chat reply handler. */\n replyTarget: z.string().min(1),\n});\nexport type Hook_InboundChatMessage = z.infer<typeof Hook_InboundChatMessageSchema>;\n\n/**\n * A chat COMMAND a person sent, as a verified request carries it (#2666 S7): a Slack slash command (`/todo add buy milk`)\n * or a Teams message-extension form a person submitted. Read by the engine from the request it verified, so the command\n * door runs what the person sent and never what a handler says they sent. One schema, the type derived from it: what a\n * provider module's `chatCommandOf` returns is parsed with it, and a value built wrong is read as no command.\n */\nexport const Hook_InboundChatCommandSchema = z.object({\n sender: Hook_InboundChatSenderSchema,\n /**\n * The command's verb: the word after a Slack command, a Teams command's id. Null when the person typed none (a bare\n * `/todo`), which the door answers with the list of commands.\n */\n verb: z.string().min(1).nullable(),\n /** Slack: what follows the verb, the bot's mentions made readable. Teams: empty (the form's fields are in `values`). */\n text: z.string(),\n /** Teams: the submitted form, field by field, as the person filled it (strings, converted by the door). Slack: empty. */\n values: z.record(z.string(), z.string()).default({}),\n /** Who can read the conversation it was sent from, which decides where its answer goes. */\n audience: z.enum(ChatConversationAudience),\n /** Where the answer goes, serialized by the vendor module and parsed back by its command result handler. */\n replyTarget: z.string().min(1),\n});\nexport type Hook_InboundChatCommand = z.infer<typeof Hook_InboundChatCommandSchema>;\n\n/**\n * A chat SEARCH a person typed (#2666 S7): a Teams message-extension search, sent as the person types and answered within\n * the vendor's deadline in the same request, never stored. Read by the engine from the request it verified.\n */\nexport const Hook_InboundChatSearchSchema = z.object({\n sender: Hook_InboundChatSenderSchema,\n /** The search command's id, as declared in the vendor package (the operation's verb). */\n verb: z.string().min(1),\n /** What the person typed; empty for the default query. */\n text: z.string(),\n /** The default query a vendor sends when the search opens (Teams `initialRun`), recognised by its marker, never by an empty text. */\n initialRun: z.boolean(),\n /** How many results to skip: the vendor's paging. */\n skip: z.number().int().nonnegative(),\n /** The vendor's own id for this request, the only name an unstored request has (recorded on its audit row). */\n vendorRequestId: z.string().min(1),\n});\nexport type Hook_InboundChatSearch = z.infer<typeof Hook_InboundChatSearchSchema>;\n\n/** What the engine answers a chat search with, before the vendor module writes it in the vendor's own response (#2666 S7). */\nexport enum Hook_ChatSearchAnswerKind {\n /** Records the person may insert, each named and linked. Empty when this page has nothing (a later page of the results). */\n RESULTS = 'results',\n /** One plain sentence in place of results: nothing found, refused, keep typing, try again. Carries no formatting. */\n MESSAGE = 'message',\n /** The person's chat account is linked to no member yet: the page that links it, and the text of the action that opens it. */\n SIGN_IN = 'sign_in',\n}\n\n/** One record a chat search found: its name and its page in the application, nothing else (selecting it shares only these). */\nexport interface Hook_ChatSearchAnswerItem {\n /** The record's id. */\n readonly id: string;\n /** The record's name (its resource's `recordLabelFields`), or the framework's \"open it\" phrase when it has none. */\n readonly title: string;\n /** The record's page in the application, or `null` when its route cannot be built. */\n readonly url: string | null;\n}\n\n/**\n * The engine's answer to a chat search (#2666 S7), in the searcher's language, which the endpoint's\n * {@link Hook_Endpoint.answerChatSearch} turns into the vendor's response (a Teams `composeExtension` of type `result`,\n * `message` or `auth`). Built by the engine from the member's own results; a module only chooses how it looks.\n */\nexport type Hook_ChatSearchAnswer =\n | { readonly kind: Hook_ChatSearchAnswerKind.RESULTS; readonly items: readonly Hook_ChatSearchAnswerItem[] }\n | { readonly kind: Hook_ChatSearchAnswerKind.MESSAGE; readonly text: string }\n | { readonly kind: Hook_ChatSearchAnswerKind.SIGN_IN; readonly text: string; readonly url: string };\n\n/** How an endpoint's synchronous answer writes its body. */\nexport enum Hook_AcknowledgementEncoding {\n /** No body. Slack takes an empty 200 as \"received, nothing to show\"; it closes a submitted modal view. */\n EMPTY = \"empty\",\n /** `application/json`. */\n JSON = \"json\",\n /** `text/plain; charset=utf-8`. */\n TEXT = \"text\",\n}\n\n/**\n * The HTTP answer a provider's contract requires within its deadline, computed from the verified request.\n * Always a 200: it is the answer to a request the engine ACCEPTED (stored, a duplicate, or one no handler takes),\n * so a refusal never takes this path. The work itself still goes through the durable store and the queue.\n */\nexport type Hook_Acknowledgement =\n | { readonly encoding: Hook_AcknowledgementEncoding.EMPTY }\n | { readonly encoding: Hook_AcknowledgementEncoding.JSON; readonly body: unknown }\n | { readonly encoding: Hook_AcknowledgementEncoding.TEXT; readonly body: string };\n\n// ===============================================================\n// Webhook Endpoint\n// ===============================================================\n\n/**\n * A webhook endpoint for a specific domain/capability within a provider.\n * \n * Each endpoint generates a route: POST /webhooks/{providerRef}/{endpointKey}\n * \n * The endpoint is the SINGLE SOURCE OF TRUTH for all webhook metadata:\n * - Signature config (how to verify)\n * - Event types (what this endpoint handles)\n * - Scope binding (how events map to engine scope)\n * \n * Examples:\n * Stripe: { key: 'billing', capability: 'billing', ... }\n * Google: { key: 'calendar', capability: 'calendar', ... }, { key: 'drive', ... }\n * Microsoft: { key: 'graph', ... }, { key: 'teams', ... }\n */\nexport type Hook_Endpoint = {\n /** Unique key within this provider (used in route: /webhooks/stripe/{key}) */\n key: string;\n /**\n * Optional human-readable name. The runtime projection emitted by\n * `getDefaultProviderConfiguration` does not set this (verified\n * 2026-05-06 — no consumer reads `endpoint.displayName` anywhere\n * in the engine or in `external-connectors-public`); requiring it\n * was aspirational. Future admin/UI surfaces that want to display\n * webhook endpoints should treat the field as optional and fall\n * back to `key` when absent.\n */\n displayName?: string;\n /** Which capability this endpoint serves */\n capability: string;\n /**\n * How a request is verified. Required on every endpoint except a\n * {@link Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL} one, which must declare none (nothing it receives is verified, and\n * a signature setting nothing reads would look like a control). The route gate withholds an endpoint that breaks either\n * half.\n */\n signatureConfig?: Hook_SignatureConfig;\n /** How the endpoint's requests are trusted, and so handled. See {@link Hook_TriggerStrategy}. */\n triggerStrategy: Hook_TriggerStrategy;\n /** Required for, and only for, a {@link Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL} endpoint (#2909). */\n reReadTrigger?: Hook_ReReadTrigger;\n /** Event types this endpoint handles (single source of truth) */\n eventTypes: string[];\n /** Declarative scope binding — how events map to engine scope */\n scopeBinding: Hook_EndpointScopeBinding;\n /**\n * The largest body this endpoint accepts, in bytes, when an inbound handler takes its events (#1596).\n * A larger delivery is refused 413 and audited. Per ENDPOINT, not per route prefix: capping the whole\n * `/webhooks/` family would cap every provider at the smallest endpoint's size. Omitted, the server's\n * own body limit applies.\n */\n maxBodyBytes?: number;\n /**\n * The media types this endpoint accepts (#2659). A request in any other is refused 415 and audited. Omitted,\n * the endpoint accepts JSON only. Slack's interactions and slash commands are `FORM_URLENCODED`. The engine\n * decodes JSON and form bodies; it decodes no XML, so an endpoint declaring XML refuses every request.\n */\n contentTypes?: ReadonlyArray<Hook_ContentType>;\n /**\n * The verified request names a PERSON of the vendor's chat: a workspace or tenant and a user id, both carried in\n * bytes the vendor signed (Slack's events, clicks and commands; a Teams activity). Only such an endpoint's handler\n * may act as the member that chat account is linked to (`ctx.chat`, #2664); every other handler is refused.\n *\n * Honored only on an endpoint the ENGINE verifies (`HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS`), read through\n * {@link hookEndpointNamesChatMember}: a person named in bytes the engine did not check could be anyone. An email\n * intake endpoint never declares it, because a From address is not verified by anything.\n */\n namesChatMember?: boolean;\n\n // ── Runtime-only pure functions (#2659). Authored on the provider module's endpoint descriptor; never\n // serialized, so nothing that persists or ships an endpoint carries them. Each runs only on a request\n // the engine has verified, and none may perform I/O: the answer is due within the provider's deadline.\n\n /**\n * Answers a HANDSHAKE: a request that proves the endpoint is reachable rather than delivering an event\n * (Slack's `url_verification`, answered with its `challenge`). Returns the answer for a handshake, `null` for\n * anything else. A handshake is answered and never stored: no handler runs for it.\n */\n answerHandshake?: (request: Hook_InboundRequest) => Hook_Acknowledgement | null;\n /**\n * Names the event in a verified request, for an engine-verified endpoint whose scheme signs no delivery id\n * (`SLACK_V0`, `BOT_FRAMEWORK_JWT`). Returns `null` for a request that carries no event the provider names; it\n * is acknowledged and stored nowhere. `SVIX_V1` needs none: its signed `svix-id` and the body's `type` name it.\n * An engine-verified endpoint whose scheme signs no id is not mounted without one.\n */\n identifyEvent?: (request: Hook_InboundRequest) => Hook_InboundEventIdentity | null;\n /**\n * The synchronous answer the provider requires, replacing the engine's `{ received: true }` on every accepted\n * request (Slack: an empty 200; a Teams `invoke`: an invoke response body). Omitted, the engine's answer stands.\n */\n acknowledge?: (request: Hook_InboundRequest) => Hook_Acknowledgement;\n /**\n * The PERSONAL conversation this request happened in, or `null` when it happened anywhere else (a group chat, a\n * channel) or names no person (#2664 S5b). Only for an endpoint that {@link namesChatMember} and whose scheme names\n * the bot the token was for (`BOT_FRAMEWORK_JWT`). The engine records it on the sender's chat identity link in the\n * delivery's organization, under that bot, so the application can post to the person later without their writing\n * first. A throw is logged and records nothing: the delivery is unaffected.\n */\n personalConversationOf?: (request: Hook_InboundRequest) => Hook_InboundPersonalConversation | null;\n /**\n * The message a person wrote to the bot in this request, or `null` when it carries none: a click, a command, the\n * bot's own message, an edit or a deletion (#2665 S6). Only for an endpoint that {@link namesChatMember}, on a scheme the\n * engine verifies: declared anywhere else, it stops startup (#2666 S7), because a person's words read from it would be\n * stored where READ returns them and nothing empties them. A handler on\n * such an endpoint converses through `ctx.chat.converse()`, which reads the message from here, and the engine orders\n * each sender's messages of one conversation by it (the delivery's ordering key). A throw is treated as `null`.\n * Read the BODY only: the engine calls it at receipt and again from the stored delivery, which keeps no header but\n * `content-type`, and the two reads must name the same message.\n */\n chatMessageOf?: (request: Hook_InboundRequest) => Hook_InboundChatMessage | null;\n /**\n * The chat command a person sent in this request, or `null` when it carries none (#2666 S7): a Slack slash command, or a\n * Teams message-extension form submitted. Only for an endpoint that {@link namesChatMember} on a scheme the engine\n * verifies; declared anywhere else, it stops startup. The engine marks the stored\n * delivery a COMMAND at receipt, so its body has one copy, and a handler runs it through `ctx.chat.runCommand()`, which\n * reads it from here. A throw is treated as `null`. Read the BODY only: the engine calls it at receipt and again from the\n * stored delivery, which keeps no header but `content-type`.\n */\n chatCommandOf?: (request: Hook_InboundRequest) => Hook_InboundChatCommand | null;\n /**\n * The chat SEARCH a person typed in this request, or `null` (#2666 S7): a Teams message-extension search. Only for an\n * endpoint that {@link namesChatMember} on a scheme the engine verifies; declared anywhere else, it stops startup. A search is answered in the request and never stored, so the engine asks this\n * BEFORE it names an event: a request it answers is a search, and nothing else runs for it. A throw is treated as `null`.\n * Declared with {@link answerChatSearch}, or startup refuses the endpoint.\n */\n chatSearchOf?: (request: Hook_InboundRequest) => Hook_InboundChatSearch | null;\n /**\n * The vendor's response to a chat search, from the engine's answer (#2666 S7): the person's results, a sentence, or the\n * page that links their chat account. Pure, because it is written inside the vendor's deadline. Declared exactly when\n * {@link chatSearchOf} is: one without the other stops startup.\n */\n answerChatSearch?: (answer: Hook_ChatSearchAnswer) => Hook_Acknowledgement;\n};\n/** @wildo_source:part:end external-connectors.models.hook-inbound-endpoint */\n\n/**\n * Whether an endpoint's handler may act as the chat member its verified request names (#2664): the endpoint declares\n * {@link Hook_Endpoint.namesChatMember}, AND the engine verifies it. A declaration on an endpoint a provider adapter\n * verifies is not honored, so the decision rests on engine code alone.\n */\nexport function hookEndpointNamesChatMember(endpoint: Pick<Hook_Endpoint, 'namesChatMember' | 'signatureConfig'>): boolean {\n const algorithm = endpoint.signatureConfig?.algorithm;\n return endpoint.namesChatMember === true && algorithm !== undefined && HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS.has(algorithm);\n}\n\n// ===============================================================\n// Webhook Provider Configuration\n// ===============================================================\n\nexport type HookInitiatorProvider_Configuration = ExternalProvider_ExchangeProtocol_Configuration_Base & {\n /** Webhook endpoints — each generates a route: POST /webhooks/{providerRef}/{endpointKey} */\n endpoints: Hook_Endpoint[];\n /** Per-endpoint webhook secrets: endpointKey → secret value */\n endpointSecrets?: Record<string, string>;\n /** Fallback secret if not specified per-endpoint (legacy compat) */\n webhookSecret?: string;\n};\n\n// ===============================================================\n// Webhook Operation Context\n// ===============================================================\n\nexport const Hook_OperationContextSchema = ExternalProvider_OperationContextSchema.extend({\n eventType: z.string(),\n eventId: z.string().optional(),\n deliveryStatus: z.enum(Hook_DeliveryStatus),\n signatureVerified: z.boolean().optional(),\n pollingCursor: z.string().optional(),\n});\nexport type Hook_OperationContext = z.infer<typeof Hook_OperationContextSchema>;\n\n// ===============================================================\n// Webhook Operation Definition\n// ===============================================================\n\nexport type Hook_OperationDefinition = ExternalProvider_OperationDefinition_Base & {\n triggerSpec: Hook_TriggerSpec;\n operationContextSchema: typeof Hook_OperationContextSchema;\n samplePayload?: unknown;\n};\n\n"]}
1
+ {"version":3,"file":"hooks.external-connectors-models.schemas.js","sourceRoot":"","sources":["../../../src/protocols/hooks.external-connectors-models.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { \n API_HttpMethod, \n ExternalProvider_ExchangeProtocol_Configuration_Base, \n ExternalProvider_ExchangeProtocol_Kind \n} from \"../core/commons.external-connectors-models.schemas\";\nimport { ExternalProvider_Auth_Kind } from \"../core/security.external-connectors-models.schemas\";\nimport { ExternalProvider_OperationContextSchema, ExternalProvider_OperationDefinition_Base } from \"../core/operations.external-connectors-models.schemas\";\n\n//===============================================================\n// Webhook/Hooks Provider\n// --------\n// Schema definitions for webhook integrations.\n// Supports event subscriptions, signature verification, and\n// delivery management.\n//===============================================================\n\n// ===============================================================\n// Webhook Enums\n// ===============================================================\n\nexport const Hook_HttpMethods: readonly API_HttpMethod[] = [\n API_HttpMethod.POST,\n API_HttpMethod.PUT,\n API_HttpMethod.PATCH,\n];\n\nexport const Hook_SecurityType: readonly ExternalProvider_Auth_Kind[] = [\n ExternalProvider_Auth_Kind.NONE,\n ExternalProvider_Auth_Kind.HMAC_SIGNATURE,\n ExternalProvider_Auth_Kind.BEARER,\n ExternalProvider_Auth_Kind.BASIC,\n];\n\nexport enum Hook_ContentType {\n JSON = \"application/json\",\n FORM_URLENCODED = \"application/x-www-form-urlencoded\",\n XML = \"application/xml\",\n}\n\n/** @wildo_source:part:start external-connectors.models.hook-trigger-strategy facet:kind:api facet:audience:app-developer */\n/**\n * How a provider endpoint's requests are TRUSTED, and so what the engine does with them. A trust posture, kept apart from\n * {@link Hook_SignatureAlgorithm}, which only says how a signature is checked.\n */\nexport enum Hook_TriggerStrategy {\n /** The vendor pushes events, verified by the endpoint's `signatureConfig`; a verified event is stored and handled. */\n WEBHOOK = \"webhook\",\n POLLING = \"polling\",\n APP_WEBHOOK = \"app_webhook\",\n /**\n * The vendor pushes a NOTIFICATION nobody can verify (#2909): it signs nothing (IgniSign). The request is never\n * trusted. It only names an object (`reReadTrigger.identifyReference`), and the engine:\n * - answers 202 whatever happens, so a sender learns nothing about which references exist;\n * - drops it unless the endpoint's handler resolves the reference to a record of this application;\n * - stores only the reference, under an id derived from the reference and a coalescing window, so one reference\n * causes at most one re-read per window, one at a time, and a notification after that window's re-read is kept for\n * the next window rather than lost;\n * - limits the endpoint's request rate, and charges the re-read to a share of the vendor's declared rate budget, so a\n * flood never spends what polling needs. The provider must therefore DECLARE a budget (`rateBudgets` on its\n * connection, or `maxRequestsPerMinute`); without one the route is withheld.\n * The handler then RE-READS the object from the vendor's authenticated API: what the record becomes is what the\n * vendor answered there, never what the notification said. Its handler resolves the reference to a record in an\n * organization or a person's data, never the application scope. Polling remains the latency floor under attack.\n * Such an endpoint declares no `signatureConfig`.\n */\n WEBHOOK_TRIGGERS_POLL = \"webhook_triggers_poll\",\n}\n\n/**\n * What a {@link Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL} endpoint declares (#2909). Pure functions and numbers only:\n * the request is unverified, so nothing in it is believed beyond the reference it names.\n */\nexport interface Hook_ReReadTrigger {\n /**\n * The vendor's reference to the object the notification is about (a signature request id), read from the decoded,\n * UNVERIFIED body, or `null` when it names none. It is only ever looked up and re-read, never trusted. Pure: no I/O.\n */\n readonly identifyReference: (request: Hook_InboundRequest) => string | null;\n /**\n * The coalescing window, in seconds (default {@link HOOK_REREAD_TRIGGER_DEFAULT_COALESCING_WINDOW_SECONDS}): a reference\n * is re-read at most once per window, the windows aligned on the clock. A notification arriving once its window's\n * re-read is already stored is kept for the NEXT window, due at its start, so the last change a vendor reports is\n * never lost. A positive integer; the route is withheld otherwise.\n */\n readonly coalescingWindowSeconds?: number;\n /**\n * The most requests the endpoint takes per window, from every sender together (default\n * {@link HOOK_REREAD_TRIGGER_DEFAULT_RATE_LIMIT}). Past it a request is dropped, still answered 202. Positive integers.\n */\n readonly rateLimit?: { readonly maxRequests: number; readonly windowSeconds: number };\n}\n\n/** The default coalescing window of a re-read trigger: one re-read per reference per minute. */\nexport const HOOK_REREAD_TRIGGER_DEFAULT_COALESCING_WINDOW_SECONDS = 60;\n/** The default request rate of a re-read trigger endpoint, all senders together. */\nexport const HOOK_REREAD_TRIGGER_DEFAULT_RATE_LIMIT = { maxRequests: 120, windowSeconds: 60 } as const;\n\n/**\n * Whether an endpoint only triggers re-reads (#2909): its requests are never verified, never trusted. Decided by an\n * exhaustive switch, so a strategy added tomorrow must be classified here before anything compiles (review F9).\n */\nexport function isReReadTriggerEndpoint(endpoint: Pick<Hook_Endpoint, 'triggerStrategy'>): boolean {\n switch (endpoint.triggerStrategy) {\n case Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL:\n return true;\n case Hook_TriggerStrategy.WEBHOOK:\n case Hook_TriggerStrategy.POLLING:\n case Hook_TriggerStrategy.APP_WEBHOOK:\n return false;\n default: {\n // Compile-time: a new member must be classified above. At run time, a value outside the vocabulary takes the SIGNED\n // path, which verifies everything it accepts, so a malformed declaration can never be trusted unverified.\n const unclassified: never = endpoint.triggerStrategy;\n void unclassified;\n return false;\n }\n }\n}\n\n/** Whether a re-read trigger's declared numbers can be enforced: every one a positive integer (#2909 review F6). */\nexport function reReadTriggerLimitsAreSound(trigger: Pick<Hook_ReReadTrigger, 'coalescingWindowSeconds' | 'rateLimit'>): boolean {\n const positiveInteger = (value: number | undefined) => value === undefined || (Number.isSafeInteger(value) && value >= 1);\n return positiveInteger(trigger.coalescingWindowSeconds)\n && (trigger.rateLimit === undefined || (positiveInteger(trigger.rateLimit.maxRequests) && positiveInteger(trigger.rateLimit.windowSeconds)));\n}\n/** @wildo_source:part:end external-connectors.models.hook-trigger-strategy */\n\nexport enum Hook_HandshakeType {\n NONE = \"none\",\n CHALLENGE_RESPONSE = \"challenge_response\",\n VERIFICATION_TOKEN = \"verification_token\",\n}\n\n/** @wildo_source:part:start external-connectors.models.hook-signature-algorithms facet:kind:api facet:audience:app-developer */\nexport enum Hook_SignatureAlgorithm {\n HMAC_SHA256 = \"hmac-sha256\",\n HMAC_SHA512 = \"hmac-sha512\",\n HMAC_SHA1 = \"hmac-sha1\",\n /**\n * The Svix / Standard Webhooks v1 construction, verified by the ENGINE (#1600): HMAC-SHA256 over\n * `{svix-id}.{svix-timestamp}.{rawBody}` with the base64 key of a `whsec_` secret, any listed `v1,` signature\n * matching, inside a five-minute window. An endpoint declaring it needs no provider adapter — the provider\n * cannot supply a verifier for it, which is the point: the one fail-closed decision of the inbound path stays\n * in engine code. `svix-id` is the delivery's dedup key.\n *\n * spec-cite: https://docs.svix.com/receiving/verifying-payloads/how-manual — headers, signed content, secret\n * format, versioned signature list and timestamp tolerance.\n */\n SVIX_V1 = \"svix-v1\",\n /**\n * Slack's request signing, verified by the ENGINE (#2659): HMAC-SHA256 with the app's signing secret over\n * `v0:{X-Slack-Request-Timestamp}:{raw body}`, sent as `X-Slack-Signature: v0=<hex>`, inside a five-minute\n * window. It covers JSON events and form-encoded interactions and commands alike, because it signs the bytes.\n * Slack signs no delivery id, so the endpoint names its events with `identifyEvent` (an `event_id` or a\n * `trigger_id` read from the verified body).\n *\n * spec-cite: https://docs.slack.dev/authentication/verifying-requests-from-slack — basestring, header names,\n * `v0=` hex signature, raw body, five-minute window.\n */\n SLACK_V0 = \"slack-v0\",\n /**\n * The Bot Framework Connector's bearer token, verified by the ENGINE (#2659), for Microsoft Teams and every\n * other Azure Bot Service channel. The request carries `Authorization: Bearer <JWT>`; the token must be\n * signed with a key from the Connector's published key set under an algorithm its OpenID metadata names,\n * with issuer `https://api.botframework.com`, audience equal to the bot's Microsoft App ID (the value the\n * endpoint's secret resolves to), inside its validity period (five minutes' skew), a `serviceUrl` claim\n * equal to the activity's `serviceUrl`, and a signing key endorsed for the activity's `channelId`.\n * The activity carries its own `id`, which the endpoint's `identifyEvent` returns.\n *\n * spec-cite: https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-authentication\n * — \"Authenticate requests from the Bot Connector service to your bot\", steps 2-4 and the seven\n * numbered token requirements.\n */\n BOT_FRAMEWORK_JWT = \"bot-framework-jwt\",\n /**\n * An Ed25519 signature over `{timestamp}{signedContentSeparator}{raw body}`, verified by the ENGINE (#3393) against\n * the vendor's PUBLIC key, for vendors that sign asymmetrically: Telnyx and Discord interactions. The endpoint's\n * secret resolves to that public key, which is not a secret (both vendors publish it in their portal), as 32 raw\n * bytes in hex (Discord) or base64 (Telnyx). The signature header carries 64 bytes in hex or base64, told apart by\n * length. The vendors differ in their header names and in the text between the timestamp and the body, so this\n * scheme reads them from the declaration, and refuses one that omits any of them: `headerName` (the signature),\n * `timestampHeader`, and `signedContentSeparator` (`|` for Telnyx, the empty string for Discord). A mis-declared\n * separator or header can only refuse a genuine request, never admit a forged one: the check is the vendor's key.\n * The signed timestamp must fall within five minutes of now. Neither vendor signs a delivery id, so the endpoint\n * names its events with `identifyEvent`.\n *\n * spec-cite: https://www.rubydoc.info/gems/telnyx/Telnyx/Lib/WebhookVerification — Telnyx's own SDK:\n * `telnyx-signature-ed25519` / `telnyx-timestamp` headers, `signed_payload = \"#{timestamp}|#{payload}\"`, a\n * strict-base64 signature, a \"Base64-encoded raw 32-byte Ed25519 public key\", `DEFAULT_TOLERANCE = 300` seconds.\n * spec-cite: https://docs.discord.com/developers/interactions/overview — \"Security and Authorization\":\n * `X-Signature-Ed25519` / `X-Signature-Timestamp`, the examples' `timestamp + body` with no separator, the\n * signature and the public key decoded from hex.\n */\n ED25519 = \"ed25519\",\n /**\n * HTTP Basic credentials, verified by the ENGINE (#3395), for a vendor that signs nothing and authenticates its\n * webhook only with the credentials an operator writes into the webhook URL: Postmark's inbound webhook. The\n * endpoint's secret resolves to `user-id:password`, and the request must carry `Authorization: Basic <base64 of\n * those bytes>`, compared in constant time. An empty secret, or one that is not `user-id:password` with both parts\n * present, refuses every request, so a delivery is never accepted unauthenticated. The credential travels in every\n * request and signs neither the body nor a timestamp: it proves who sent the request, not what it carries, so it is\n * worth what the TLS protecting it is worth. Nothing names a delivery, so the endpoint names its events with\n * `identifyEvent`.\n *\n * spec-cite: https://postmarkapp.com/developer/user-guide/inbound/configure-an-inbound-server (fetched 2026-11-09)\n * — \"we support HTTP Basic authentication\", the credentials given in the webhook URL.\n * spec-cite: RFC 7617 §2 — the user-pass is the user-id, a single colon and the password, Base64-encoded\n * (RFC 4648 §4) in the `token68` credentials of the `Basic` scheme; \"a user-id containing a colon character is\n * invalid\".\n */\n BASIC_CREDENTIAL = \"basic-credential\",\n /**\n * A Mailgun route's JSON forward, verified by the ENGINE (#3395): a route whose `forward()` URL ends in `json` posts\n * the parsed message as one JSON document and carries the signature in headers. It is the hex HMAC-SHA256, keyed\n * with the account's webhook signing key, of `{X-Mailgun-Timestamp}{raw body}` (Mailgun's `timestamp + token`, with\n * the whole body in place of the token), in `X-Mailgun-Signature`; a subaccount's domain also carries\n * `X-Mailgun-Parent-Signature`, the same HMAC under the primary account's key, and either may match the key in the\n * slot. The signed timestamp may be at most nine hours old, which covers Mailgun's eight hours of retries, and five\n * minutes ahead. The\n * header names are Mailgun's, so the endpoint declares nothing beyond the algorithm. Mailgun signs no delivery id, so\n * the endpoint names its events with `identifyEvent`.\n *\n * A forward URL not ending in `json` posts a form (urlencoded, or multipart with attachments) with the signature in\n * body fields; the engine neither decodes that body nor verifies that signature, so such a route is refused (415).\n *\n * spec-cite: https://documentation.mailgun.com/docs/mailgun/user-manual/receive-forward-store/receive-http (fetched\n * 2026-11-09) — the destination-URL table, and \"JSON Payload Format\" › \"Signature verification\".\n * spec-cite: https://documentation.mailgun.com/docs/mailgun/user-manual/webhooks/securing-webhooks (fetched\n * 2026-11-09) — the signature as hex HMAC-SHA256 of `timestamp + token`, and `parent-signature`.\n */\n MAILGUN_FORWARD_JSON = \"mailgun-forward-json\",\n /**\n * Twilio's request signature (#3394), verified by the ENGINE: the base64 HMAC-SHA1, keyed with the account's auth\n * token, of the full URL Twilio called (scheme to query string) followed by every POST parameter, sorted by name,\n * each written as its name then its value with no delimiter. A parameter sent more than once contributes each of\n * its distinct values, sorted, after its name. The signature is carried in the declared `headerName`\n * (`x-twilio-signature`).\n *\n * The URL is part of what is signed, so the engine composes it from the application's public API URL\n * (`runtime.endPoints[MAIN_BACKEND_API].publicUrl`) and the path and query string the request arrived on, and tries\n * it with and without an explicit default port, as Twilio's own helper does. No public URL configured, every request\n * is refused. The endpoint's secret resolves to the auth token, or to the `accountId:secret` bundle the SMS arm reads\n * (`SmsProviderCredentialShape.ACCOUNT_ID_AND_SECRET`), whose secret half IS the auth token: one value, never a copy\n * that can drift from it. Form bodies only: Twilio signs a JSON body through a `bodySHA256` query parameter, which\n * this scheme refuses rather than half-checks.\n *\n * Twilio signs no timestamp and no delivery id, so a captured request stays valid: the endpoint names its event\n * (`identifyEvent`), and the inbound ledger stores one delivery per event, so a replay is stored once and runs nothing.\n *\n * spec-cite: https://www.twilio.com/docs/usage/security (fetched 2026-11-09) — \"Validating requests are coming from\n * Twilio\": the full URL \"from the protocol (https...)\" through the query string; POST parameters sorted \"using\n * Unix-style case-sensitive sorting order\"; \"append the variable name and value (with no delimiters)\"; HMAC-SHA1\n * with the AuthToken; Base64; and SMS over HTTP(S) keeps the port.\n * spec-cite: https://github.com/twilio/twilio-node/blob/main/src/webhooks/webhooks.ts (fetched 2026-11-09) —\n * `getExpectedTwilioSignature` (keys sorted, `toFormUrlEncodedParam` appends each de-duplicated, sorted array value\n * after its name) and `validateRequest` (the URL tried with the port removed and added).\n */\n TWILIO_HMAC_SHA1 = \"twilio-hmac-sha1\",\n}\n\n/**\n * The algorithms the ENGINE verifies itself. An endpoint naming one needs no provider adapter, and cannot be\n * given one: the scheme is engine code, so the one fail-closed decision of the inbound path never moves into a\n * provider package. Every other algorithm is verified by the adapter its provider registers.\n */\nexport const HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS: ReadonlySet<Hook_SignatureAlgorithm> = new Set([\n Hook_SignatureAlgorithm.SVIX_V1,\n Hook_SignatureAlgorithm.SLACK_V0,\n Hook_SignatureAlgorithm.BOT_FRAMEWORK_JWT,\n Hook_SignatureAlgorithm.ED25519,\n Hook_SignatureAlgorithm.BASIC_CREDENTIAL,\n Hook_SignatureAlgorithm.MAILGUN_FORWARD_JSON,\n Hook_SignatureAlgorithm.TWILIO_HMAC_SHA1,\n]);\n\n/**\n * Whether an endpoint's signature declaration names everything its scheme reads from it. `ED25519` reads more\n * than its algorithm (#3393): the signature header, the timestamp header (never optional: an unsigned or absent\n * timestamp leaves a captured request replayable for ever) and the separator. `TWILIO_HMAC_SHA1` reads its signature\n * header (#3394). The engine withholds the route of an incomplete declaration, and refuses a request reaching one,\n * rather than guessing a vendor's construction.\n */\nexport function hookSignatureDeclarationIsComplete(config: Pick<Hook_SignatureConfig, 'algorithm' | 'headerName' | 'timestampHeader' | 'signedContentSeparator'>): boolean {\n // TWILIO_HMAC_SHA1 (#3394) reads its signature from the declared header, so an empty one could only refuse.\n if (config.algorithm === Hook_SignatureAlgorithm.TWILIO_HMAC_SHA1) return typeof config.headerName === 'string' && config.headerName.length > 0;\n if (config.algorithm !== Hook_SignatureAlgorithm.ED25519) return true;\n return typeof config.headerName === 'string' && config.headerName.length > 0\n && typeof config.timestampHeader === 'string' && config.timestampHeader.length > 0\n && typeof config.signedContentSeparator === 'string';\n}\n/** @wildo_source:part:end external-connectors.models.hook-signature-algorithms */\n\nexport enum Hook_DeliveryStatus {\n PENDING = \"pending\",\n DELIVERED = \"delivered\",\n FAILED = \"failed\",\n RETRYING = \"retrying\",\n}\n\n// ===============================================================\n// Webhook Signature Config\n// ===============================================================\n\nexport const Hook_SignatureConfigSchema = z.object({\n algorithm: z.enum(Hook_SignatureAlgorithm),\n headerName: z.string(), // e.g., \"X-Hub-Signature-256\"\n timestampHeader: z.string().optional(),\n prefix: z.string().optional(), // e.g., \"sha256=\"\n /**\n * `BOT_FRAMEWORK_JWT` only (#2663): the account fact, on an ORGANIZATION's connection to this provider, that names\n * another bot App ID this endpoint admits as a token's audience, beside the application's own bot (the endpoint's\n * secret). A token is admitted for an organization's bot only when that organization's ENABLED connection holds its\n * audience as vendor evidence (`PROVIDER_CONNECTION_ROUTING_FACT_PROVENANCES`): for a bot, `VERIFIED_BY_VENDOR`, the\n * App ID whose secret the token endpoint accepted at connect. Never as an administrator merely typed it. The delivery\n * then carries that organization. Absent: the application's own bot is the only audience.\n */\n organizationAudienceFact: z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/).optional(),\n /**\n * `ED25519` only (#3393), and required there: the text the vendor puts between the signed timestamp and the raw\n * body in the content it signs. `'|'` for Telnyx; `''` for Discord, which concatenates the two.\n */\n signedContentSeparator: z.string().max(8).optional(),\n});\nexport type Hook_SignatureConfig = z.infer<typeof Hook_SignatureConfigSchema>;\n\n// ===============================================================\n// Webhook Trigger Spec\n// ===============================================================\n//\n// Declared for a future webhook-SUBSCRIPTION operation (a provider operation that registers a trigger at the vendor).\n// No engine code reads it today. In particular its handshake fields are NOT how a receiving endpoint answers a URL\n// challenge: that is `Hook_Endpoint.answerHandshake`, a pure function of the verified request (#2659). The declarative\n// `handshakeType` that `Hook_Endpoint` used to carry was removed then, because nothing read it, so a provider setting\n// it got no answer at all.\n\nexport const Hook_TriggerSpecSchema = z.object({\n strategy: z.enum(Hook_TriggerStrategy),\n \n // Events\n eventTypes: z.array(z.string()).optional(),\n \n // Handshake\n handshakeType: z.enum(Hook_HandshakeType).optional(),\n challengeField: z.string().optional(),\n \n // Signature\n signatureConfig: Hook_SignatureConfigSchema.optional(),\n \n // Polling (for POLLING strategy)\n pollingIntervalMs: z.number().optional(),\n deduplicationKey: z.string().optional(),\n \n // Lifecycle\n hasOnEnable: z.boolean().optional(),\n hasOnDisable: z.boolean().optional(),\n});\nexport type Hook_TriggerSpec = z.infer<typeof Hook_TriggerSpecSchema>;\n\n// ===============================================================\n// Webhook Endpoint Scope Binding (Declarative Scope Resolution)\n// ===============================================================\n\n/**\n * Variant config for polymorphic scope resolution.\n * Each entry represents one variant collection to query during lookup.\n */\nexport interface Hook_PolymorphicVariantBinding {\n /** Variant resource type to query (e.g., 'organizationBillingAccounts') */\n resourceType: string;\n /** Parent resource type (e.g., 'organizations') */\n parentResourceType: string;\n /** Parent field identifier — the scope entity ID field on matched documents (e.g., 'organizationId') */\n parentFieldIdentifier: string;\n /** Whether this variant's parent is a primary scope entity */\n isPrimaryScope: boolean;\n}\n\n/**\n * Declarative scope resolution config for a webhook endpoint.\n * \n * Determines how an incoming webhook event is mapped to a engine scope\n * (organization or user) without writing per-capability code.\n * \n * Three modes:\n * - APPLICATION: Global events, no lookup needed.\n * - Single-scope (ORGANIZATIONS / USER_SELF): Extract an ID from the\n * event payload, look up a single resource type, and resolve the scope entity ID.\n * - Polymorphic: Extract an ID from the event payload, query N variant collections\n * in order, and resolve the scope from whichever variant matches. Used when a\n * resource has been polymorphically expanded across multiple scope types.\n */\nexport type Hook_EndpointScopeBinding =\n | {\n /** Global/application-scoped events — no entity lookup needed */\n primaryScope: 'APPLICATION';\n }\n | {\n /** Scoped events — requires payload extraction + resource lookup */\n primaryScope: 'ORGANIZATIONS' | 'USER_SELF';\n /** Dot-path into the parsed event payload to extract the provider's scope ID (e.g., 'data.object.customer') */\n payloadScopeIdPath: string;\n /** Resource type to query for scope resolution (e.g., 'BILLING_ACCOUNTS') */\n lookupResourceType: string;\n /** Field on the resource to match the extracted ID (e.g., 'providerCustomerId') */\n lookupField: string;\n /** Field on the found resource that gives the scope entity ID (defaults to 'organizationId'/'userId' based on primaryScope) */\n scopeEntityIdField?: string;\n /** Event types that don't carry scope — fall back to APPLICATION scope (e.g., 'product.created', 'price.updated') */\n scopeExemptEventTypes?: string[];\n }\n | {\n /** Polymorphic scope resolution — queries multiple variant collections */\n mode: 'polymorphic';\n /** Dot-path into the parsed event payload to extract the provider's scope ID (e.g., 'data.object.customer') */\n payloadScopeIdPath: string;\n /** Field on each variant resource to match the extracted ID (e.g., 'providerCustomerId') */\n lookupField: string;\n /** Variant collections to query, in order. First match wins. */\n variants: Hook_PolymorphicVariantBinding[];\n /** Event types that don't carry scope — fall back to APPLICATION scope (e.g., 'product.created', 'price.updated') */\n scopeExemptEventTypes?: string[];\n /**\n * Per-event-type overrides for payloadScopeIdPath.\n * Keyed by the provider's native event type (e.g., 'customer.deleted').\n * Use when different event types carry the scope ID at different payload paths.\n */\n eventTypeOverrides?: Record<string, { payloadScopeIdPath: string }>;\n };\n\n// ===============================================================\n// The verified request, and what an endpoint answers to it (#2659)\n// ===============================================================\n\n/** @wildo_source:part:start external-connectors.models.hook-inbound-endpoint facet:kind:api facet:audience:app-developer */\n/**\n * A provider request AFTER the engine verified it, as an endpoint's pure functions read it.\n *\n * Only ever built from a request whose signature or token the engine accepted, so everything in it, the\n * decoded body included, is what the sender signed (or, for a bearer-token scheme, what an authenticated\n * sender sent over TLS).\n */\nexport interface Hook_InboundRequest {\n /** The exact bytes received. */\n readonly rawBody: Uint8Array;\n /** Every request header, names lower-cased as Node delivers them. */\n readonly headers: Readonly<Record<string, string | readonly string[] | undefined>>;\n /** The media type the body was decoded as: one of the endpoint's `contentTypes`. */\n readonly contentType: Hook_ContentType;\n /**\n * The decoded body. JSON: the parsed value. A form: its fields, a field sent more than once becoming an array of\n * its values in order; bracket names (`a[b]`) are kept as written, never expanded into objects.\n */\n readonly body: unknown;\n}\n\n/** What identifies one provider event: the id the store deduplicates on, and the type a handler is chosen by. */\nexport interface Hook_InboundEventIdentity {\n /** Unique per event at the provider, and stable across its retries. */\n readonly eventId: string;\n /** The provider's own name for the event (`app_mention`, `block_actions`, `invoke`, …). */\n readonly providerEventType: string;\n}\n\n/**\n * A person's PERSONAL (one-to-one) conversation with the bot, as a verified request names it (#2664 S5b): who the person\n * is (the same account their chat identity link is keyed on) and where the bot can post to them later.\n */\nexport interface Hook_InboundPersonalConversation {\n /** The vendor's workspace or tenant, exactly as the provider's chat accounts write it (a lower-cased tenant id). */\n readonly workspaceRef: string;\n /** The vendor's id for the person, exactly as the provider's chat accounts write it (a lower-cased Entra object id). */\n readonly chatUserId: string;\n /** The conversation's id at the vendor. */\n readonly conversationId: string;\n /** Where the vendor takes messages for that conversation (the Bot Connector's `serviceUrl`). */\n readonly serviceUrl: string;\n}\n\n/**\n * Who sees a chat conversation at the vendor (#2665 S6), which decides where an answer to it may be posted. The chat\n * door reads it from the verified request (`Hook_InboundChatMessage.audience`) and the chat-conversation ledger records it.\n */\nexport enum ChatConversationAudience {\n /** A one-to-one conversation with the bot (a Slack DM, a Teams personal chat): answered in it. */\n DIRECT = 'direct',\n /**\n * A conversation other people read (a channel, a group chat): answered privately, in the asker's own conversation with\n * the bot, with a content-free pointer in the thread. A turn runs with the asker's authority, so its answer may name\n * what the others in the thread cannot see.\n */\n SHARED = 'shared',\n /** A shared conversation that reaches people outside the organization (Slack Connect, a Teams shared channel): the same. */\n SHARED_WITH_EXTERNAL = 'shared_with_external',\n}\n\n/** Whether a vendor conversation is a thread or a flat stream of messages (#2665 S6, plan B11). */\nexport enum Hook_ChatConversationThreading {\n /** A thread (a Slack thread, a Teams channel's reply chain): one conversation for its whole life. */\n THREADED = 'threaded',\n /**\n * A flat conversation (a top-level Slack DM, a Teams personal or group chat): split after a quiet gap measured on the\n * vendor's clock, so one transcript never grows without bound.\n */\n FLAT = 'flat',\n}\n\n/** The person who wrote a chat message, as the provider's chat accounts write them: what their chat identity link is keyed on. */\nexport const Hook_InboundChatSenderSchema = z.object({\n /** The vendor's workspace or tenant (a Slack team id, a Microsoft tenant id). */\n workspaceRef: z.string().min(1),\n /** The vendor's own id for the person (a Slack user id, a Microsoft Entra object id). */\n chatUserId: z.string().min(1),\n /** How the vendor names the person: shown on the link page only, never matched on. */\n chatUserDisplayName: z.string().optional(),\n /** How the vendor names the workspace: shown on the link page only, never matched on. */\n workspaceDisplayName: z.string().optional(),\n});\nexport type Hook_InboundChatSender = z.infer<typeof Hook_InboundChatSenderSchema>;\n\n/**\n * A message a person wrote to the bot, as a verified request carries it (#2665 S6, plan A14). The chat door reads all of\n * it from the request the engine verified, never from a handler, so a handler decides only WHETHER to converse.\n *\n * One schema, the type derived from it (#2665 S6 review L-B): the engine parses what a provider module's `chatMessageOf`\n * returns with this very schema, so a field added here is checked at the engine's boundary the day it is added, and a\n * value the module built wrong (an empty key, a date that is not one) is read as no message.\n */\nexport const Hook_InboundChatMessageSchema = z.object({\n sender: Hook_InboundChatSenderSchema,\n /** The vendor's conversation: a Slack thread or DM channel, a Teams conversation (a channel's reply chain included). */\n conversationKey: z.string().min(1),\n threading: z.enum(Hook_ChatConversationThreading),\n audience: z.enum(ChatConversationAudience),\n /** The vendor's own id for the message, the same on every retry of its delivery: what makes it one message. */\n messageKey: z.string().min(1),\n /** When the vendor says it was sent (Slack's `ts`, a Teams activity's `timestamp`): the clock a flat conversation's epochs follow. */\n sentAt: z.date(),\n /** What the person wrote, the bot's own mention removed. May be empty: the door answers that the message said nothing. */\n text: z.string(),\n /** Where an answer to this message goes, serialized by the vendor module and parsed back by its chat reply handler. */\n replyTarget: z.string().min(1),\n});\nexport type Hook_InboundChatMessage = z.infer<typeof Hook_InboundChatMessageSchema>;\n\n/**\n * A chat COMMAND a person sent, as a verified request carries it (#2666 S7): a Slack slash command (`/todo add buy milk`)\n * or a Teams message-extension form a person submitted. Read by the engine from the request it verified, so the command\n * door runs what the person sent and never what a handler says they sent. One schema, the type derived from it: what a\n * provider module's `chatCommandOf` returns is parsed with it, and a value built wrong is read as no command.\n */\nexport const Hook_InboundChatCommandSchema = z.object({\n sender: Hook_InboundChatSenderSchema,\n /**\n * The command's verb: the word after a Slack command, a Teams command's id. Null when the person typed none (a bare\n * `/todo`), which the door answers with the list of commands.\n */\n verb: z.string().min(1).nullable(),\n /** Slack: what follows the verb, the bot's mentions made readable. Teams: empty (the form's fields are in `values`). */\n text: z.string(),\n /** Teams: the submitted form, field by field, as the person filled it (strings, converted by the door). Slack: empty. */\n values: z.record(z.string(), z.string()).default({}),\n /** Who can read the conversation it was sent from, which decides where its answer goes. */\n audience: z.enum(ChatConversationAudience),\n /** Where the answer goes, serialized by the vendor module and parsed back by its command result handler. */\n replyTarget: z.string().min(1),\n});\nexport type Hook_InboundChatCommand = z.infer<typeof Hook_InboundChatCommandSchema>;\n\n/**\n * A chat SEARCH a person typed (#2666 S7): a Teams message-extension search, sent as the person types and answered within\n * the vendor's deadline in the same request, never stored. Read by the engine from the request it verified.\n */\nexport const Hook_InboundChatSearchSchema = z.object({\n sender: Hook_InboundChatSenderSchema,\n /** The search command's id, as declared in the vendor package (the operation's verb). */\n verb: z.string().min(1),\n /** What the person typed; empty for the default query. */\n text: z.string(),\n /** The default query a vendor sends when the search opens (Teams `initialRun`), recognised by its marker, never by an empty text. */\n initialRun: z.boolean(),\n /** How many results to skip: the vendor's paging. */\n skip: z.number().int().nonnegative(),\n /** The vendor's own id for this request, the only name an unstored request has (recorded on its audit row). */\n vendorRequestId: z.string().min(1),\n});\nexport type Hook_InboundChatSearch = z.infer<typeof Hook_InboundChatSearchSchema>;\n\n/** What the engine answers a chat search with, before the vendor module writes it in the vendor's own response (#2666 S7). */\nexport enum Hook_ChatSearchAnswerKind {\n /** Records the person may insert, each named and linked. Empty when this page has nothing (a later page of the results). */\n RESULTS = 'results',\n /** One plain sentence in place of results: nothing found, refused, keep typing, try again. Carries no formatting. */\n MESSAGE = 'message',\n /** The person's chat account is linked to no member yet: the page that links it, and the text of the action that opens it. */\n SIGN_IN = 'sign_in',\n}\n\n/** One record a chat search found: its name and its page in the application, nothing else (selecting it shares only these). */\nexport interface Hook_ChatSearchAnswerItem {\n /** The record's id. */\n readonly id: string;\n /** The record's name (its resource's `recordLabelFields`), or the framework's \"open it\" phrase when it has none. */\n readonly title: string;\n /** The record's page in the application, or `null` when its route cannot be built. */\n readonly url: string | null;\n}\n\n/**\n * The engine's answer to a chat search (#2666 S7), in the searcher's language, which the endpoint's\n * {@link Hook_Endpoint.answerChatSearch} turns into the vendor's response (a Teams `composeExtension` of type `result`,\n * `message` or `auth`). Built by the engine from the member's own results; a module only chooses how it looks.\n */\nexport type Hook_ChatSearchAnswer =\n | { readonly kind: Hook_ChatSearchAnswerKind.RESULTS; readonly items: readonly Hook_ChatSearchAnswerItem[] }\n | { readonly kind: Hook_ChatSearchAnswerKind.MESSAGE; readonly text: string }\n | { readonly kind: Hook_ChatSearchAnswerKind.SIGN_IN; readonly text: string; readonly url: string };\n\n/** How an endpoint's synchronous answer writes its body. */\nexport enum Hook_AcknowledgementEncoding {\n /** No body. Slack takes an empty 200 as \"received, nothing to show\"; it closes a submitted modal view. */\n EMPTY = \"empty\",\n /** `application/json`. */\n JSON = \"json\",\n /** `text/plain; charset=utf-8`. */\n TEXT = \"text\",\n}\n\n/**\n * The HTTP answer a provider's contract requires within its deadline, computed from the verified request.\n * Always a 200: it is the answer to a request the engine ACCEPTED (stored, a duplicate, or one no handler takes),\n * so a refusal never takes this path. The work itself still goes through the durable store and the queue.\n */\nexport type Hook_Acknowledgement =\n | { readonly encoding: Hook_AcknowledgementEncoding.EMPTY }\n | { readonly encoding: Hook_AcknowledgementEncoding.JSON; readonly body: unknown }\n | { readonly encoding: Hook_AcknowledgementEncoding.TEXT; readonly body: string };\n\n// ===============================================================\n// Webhook Endpoint\n// ===============================================================\n\n/**\n * A webhook endpoint for a specific domain/capability within a provider.\n * \n * Each endpoint generates a route: POST /webhooks/{providerRef}/{endpointKey}\n * \n * The endpoint is the SINGLE SOURCE OF TRUTH for all webhook metadata:\n * - Signature config (how to verify)\n * - Event types (what this endpoint handles)\n * - Scope binding (how events map to engine scope)\n * \n * Examples:\n * Stripe: { key: 'billing', capability: 'billing', ... }\n * Google: { key: 'calendar', capability: 'calendar', ... }, { key: 'drive', ... }\n * Microsoft: { key: 'graph', ... }, { key: 'teams', ... }\n */\nexport type Hook_Endpoint = {\n /** Unique key within this provider (used in route: /webhooks/stripe/{key}) */\n key: string;\n /**\n * Optional human-readable name. The runtime projection emitted by\n * `getDefaultProviderConfiguration` does not set this (verified\n * 2026-05-06 — no consumer reads `endpoint.displayName` anywhere\n * in the engine or in `external-connectors-public`); requiring it\n * was aspirational. Future admin/UI surfaces that want to display\n * webhook endpoints should treat the field as optional and fall\n * back to `key` when absent.\n */\n displayName?: string;\n /** Which capability this endpoint serves */\n capability: string;\n /**\n * How a request is verified. Required on every endpoint except a\n * {@link Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL} one, which must declare none (nothing it receives is verified, and\n * a signature setting nothing reads would look like a control). The route gate withholds an endpoint that breaks either\n * half.\n */\n signatureConfig?: Hook_SignatureConfig;\n /** How the endpoint's requests are trusted, and so handled. See {@link Hook_TriggerStrategy}. */\n triggerStrategy: Hook_TriggerStrategy;\n /** Required for, and only for, a {@link Hook_TriggerStrategy.WEBHOOK_TRIGGERS_POLL} endpoint (#2909). */\n reReadTrigger?: Hook_ReReadTrigger;\n /** Event types this endpoint handles (single source of truth) */\n eventTypes: string[];\n /** Declarative scope binding — how events map to engine scope */\n scopeBinding: Hook_EndpointScopeBinding;\n /**\n * The largest body this endpoint accepts, in bytes, when an inbound handler takes its events (#1596).\n * A larger delivery is refused 413 and audited. Per ENDPOINT, not per route prefix: capping the whole\n * `/webhooks/` family would cap every provider at the smallest endpoint's size. Omitted, the server's\n * own body limit applies.\n */\n maxBodyBytes?: number;\n /**\n * The media types this endpoint accepts (#2659). A request in any other is refused 415 and audited. Omitted,\n * the endpoint accepts JSON only. Slack's interactions and slash commands are `FORM_URLENCODED`. The engine\n * decodes JSON and form bodies; it decodes no XML, so an endpoint declaring XML refuses every request.\n */\n contentTypes?: ReadonlyArray<Hook_ContentType>;\n /**\n * The verified request names a PERSON of the vendor's chat: a workspace or tenant and a user id, both carried in\n * bytes the vendor signed (Slack's events, clicks and commands; a Teams activity). Only such an endpoint's handler\n * may act as the member that chat account is linked to (`ctx.chat`, #2664); every other handler is refused.\n *\n * Honored only on an endpoint the ENGINE verifies (`HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS`), read through\n * {@link hookEndpointNamesChatMember}: a person named in bytes the engine did not check could be anyone. An email\n * intake endpoint never declares it, because a From address is not verified by anything.\n */\n namesChatMember?: boolean;\n\n // ── Runtime-only pure functions (#2659). Authored on the provider module's endpoint descriptor; never\n // serialized, so nothing that persists or ships an endpoint carries them. Each runs only on a request\n // the engine has verified, and none may perform I/O: the answer is due within the provider's deadline.\n\n /**\n * Answers a HANDSHAKE: a request that proves the endpoint is reachable rather than delivering an event\n * (Slack's `url_verification`, answered with its `challenge`). Returns the answer for a handshake, `null` for\n * anything else. A handshake is answered and never stored: no handler runs for it.\n */\n answerHandshake?: (request: Hook_InboundRequest) => Hook_Acknowledgement | null;\n /**\n * Names the event in a verified request, for an engine-verified endpoint whose scheme signs no delivery id\n * (`SLACK_V0`, `BOT_FRAMEWORK_JWT`). Returns `null` for a request that carries no event the provider names; it\n * is acknowledged and stored nowhere. `SVIX_V1` needs none: its signed `svix-id` and the body's `type` name it.\n * An engine-verified endpoint whose scheme signs no id is not mounted without one.\n */\n identifyEvent?: (request: Hook_InboundRequest) => Hook_InboundEventIdentity | null;\n /**\n * The synchronous answer the provider requires, replacing the engine's `{ received: true }` on every accepted\n * request (Slack: an empty 200; a Teams `invoke`: an invoke response body). Omitted, the engine's answer stands.\n */\n acknowledge?: (request: Hook_InboundRequest) => Hook_Acknowledgement;\n /**\n * The PERSONAL conversation this request happened in, or `null` when it happened anywhere else (a group chat, a\n * channel) or names no person (#2664 S5b). Only for an endpoint that {@link namesChatMember} and whose scheme names\n * the bot the token was for (`BOT_FRAMEWORK_JWT`). The engine records it on the sender's chat identity link in the\n * delivery's organization, under that bot, so the application can post to the person later without their writing\n * first. A throw is logged and records nothing: the delivery is unaffected.\n */\n personalConversationOf?: (request: Hook_InboundRequest) => Hook_InboundPersonalConversation | null;\n /**\n * The message a person wrote to the bot in this request, or `null` when it carries none: a click, a command, the\n * bot's own message, an edit or a deletion (#2665 S6). Only for an endpoint that {@link namesChatMember}, on a scheme the\n * engine verifies: declared anywhere else, it stops startup (#2666 S7), because a person's words read from it would be\n * stored where READ returns them and nothing empties them. A handler on\n * such an endpoint converses through `ctx.chat.converse()`, which reads the message from here, and the engine orders\n * each sender's messages of one conversation by it (the delivery's ordering key). A throw is treated as `null`.\n * Read the BODY only: the engine calls it at receipt and again from the stored delivery, which keeps no header but\n * `content-type`, and the two reads must name the same message.\n */\n chatMessageOf?: (request: Hook_InboundRequest) => Hook_InboundChatMessage | null;\n /**\n * The chat command a person sent in this request, or `null` when it carries none (#2666 S7): a Slack slash command, or a\n * Teams message-extension form submitted. Only for an endpoint that {@link namesChatMember} on a scheme the engine\n * verifies; declared anywhere else, it stops startup. The engine marks the stored\n * delivery a COMMAND at receipt, so its body has one copy, and a handler runs it through `ctx.chat.runCommand()`, which\n * reads it from here. A throw is treated as `null`. Read the BODY only: the engine calls it at receipt and again from the\n * stored delivery, which keeps no header but `content-type`.\n */\n chatCommandOf?: (request: Hook_InboundRequest) => Hook_InboundChatCommand | null;\n /**\n * The chat SEARCH a person typed in this request, or `null` (#2666 S7): a Teams message-extension search. Only for an\n * endpoint that {@link namesChatMember} on a scheme the engine verifies; declared anywhere else, it stops startup. A search is answered in the request and never stored, so the engine asks this\n * BEFORE it names an event: a request it answers is a search, and nothing else runs for it. A throw is treated as `null`.\n * Declared with {@link answerChatSearch}, or startup refuses the endpoint.\n */\n chatSearchOf?: (request: Hook_InboundRequest) => Hook_InboundChatSearch | null;\n /**\n * The vendor's response to a chat search, from the engine's answer (#2666 S7): the person's results, a sentence, or the\n * page that links their chat account. Pure, because it is written inside the vendor's deadline. Declared exactly when\n * {@link chatSearchOf} is: one without the other stops startup.\n */\n answerChatSearch?: (answer: Hook_ChatSearchAnswer) => Hook_Acknowledgement;\n};\n/** @wildo_source:part:end external-connectors.models.hook-inbound-endpoint */\n\n/**\n * Whether an endpoint's handler may act as the chat member its verified request names (#2664): the endpoint declares\n * {@link Hook_Endpoint.namesChatMember}, AND the engine verifies it. A declaration on an endpoint a provider adapter\n * verifies is not honored, so the decision rests on engine code alone.\n */\nexport function hookEndpointNamesChatMember(endpoint: Pick<Hook_Endpoint, 'namesChatMember' | 'signatureConfig'>): boolean {\n const algorithm = endpoint.signatureConfig?.algorithm;\n return endpoint.namesChatMember === true && algorithm !== undefined && HOOK_ENGINE_VERIFIED_SIGNATURE_ALGORITHMS.has(algorithm);\n}\n\n// ===============================================================\n// Webhook Provider Configuration\n// ===============================================================\n\nexport type HookInitiatorProvider_Configuration = ExternalProvider_ExchangeProtocol_Configuration_Base & {\n /** Webhook endpoints — each generates a route: POST /webhooks/{providerRef}/{endpointKey} */\n endpoints: Hook_Endpoint[];\n /** Per-endpoint webhook secrets: endpointKey → secret value */\n endpointSecrets?: Record<string, string>;\n /** Fallback secret if not specified per-endpoint (legacy compat) */\n webhookSecret?: string;\n};\n\n// ===============================================================\n// Webhook Operation Context\n// ===============================================================\n\nexport const Hook_OperationContextSchema = ExternalProvider_OperationContextSchema.extend({\n eventType: z.string(),\n eventId: z.string().optional(),\n deliveryStatus: z.enum(Hook_DeliveryStatus),\n signatureVerified: z.boolean().optional(),\n pollingCursor: z.string().optional(),\n});\nexport type Hook_OperationContext = z.infer<typeof Hook_OperationContextSchema>;\n\n// ===============================================================\n// Webhook Operation Definition\n// ===============================================================\n\nexport type Hook_OperationDefinition = ExternalProvider_OperationDefinition_Base & {\n triggerSpec: Hook_TriggerSpec;\n operationContextSchema: typeof Hook_OperationContextSchema;\n samplePayload?: unknown;\n};\n\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"image.external-connectors-models.schemas.d.ts","sourceRoot":"","sources":["../../../../src/protocols/image.external-connectors-models.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACL,sCAAsC,EACrC,MAAM,oDAAoD,CAAA;AAC7D,OAAO,EAEL,yCAAyC,EAC1C,MAAM,uDAAuD,CAAA;AAiB9D,oBAAY,mBAAmB;IAE7B;;;;;OAKG;IACH,mBAAmB,gBAAgB;IACnC;;;OAGG;IACH,qBAAqB,kBAAkB;IACvC,+CAA+C;IAC/C,mBAAmB,gBAAgB;IACnC,uBAAuB;IACvB,gBAAgB,aAAa;CAC9B;AAED,oBAAY,0BAA0B;IACpC,yEAAyE;IACzE,cAAc,wBAAwB;CACvC;AAMD;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,WAAW,cAAc;IACzB,kBAAkB,cAAc;IAChC,mBAAmB,cAAc;IACjC,IAAI,SAAS;CACd;AAED,qCAAqC;AACrC,oBAAY,qBAAqB;IAC/B,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED;;;;GAIG;AACH,oBAAY,wBAAwB;IAClC,WAAW,gBAAgB;IAC3B,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED,oBAAY,0BAA0B;IACpC,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,eAAO,MAAM,gDAAgD;;;;;;;;;iBAW3D,CAAC;AACH,MAAM,MAAM,yCAAyC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gDAAgD,CAAC,CAAC;AAMzH,eAAO,MAAM,yBAAyB;;;;iBAOpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,8CAA8C;;;;iBAIzD,CAAC;AACH,MAAM,MAAM,wCAAwC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8CAA8C,CAAC,CAAC;AAEtH,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;iBAKpD,CAAC;AACH,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yCAAyC,CAAC,CAAC;AAE5G,MAAM,MAAM,qCAAqC,GAAG,yCAAyC,GAAG;IAC9F,6BAA6B,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACjD,sBAAsB,EAAE,OAAO,yCAAyC,CAAC;IACzE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAA;AAMD,6EAA6E;AAC7E,eAAO,MAAM,kCAAkC;;iBAK7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAG9F,eAAO,MAAM,sCAAsC;;;;;iBAIjD,CAAC;AACH,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sCAAsC,CAAC,CAAC;AAEtG,8EAA8E;AAC9E,eAAO,MAAM,kCAAkC;;;;;iBAK7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,eAAO,MAAM,uCAAuC;;;;;;;;iBAIlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAC"}
1
+ {"version":3,"file":"image.external-connectors-models.schemas.d.ts","sourceRoot":"","sources":["../../../src/protocols/image.external-connectors-models.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EACL,sCAAsC,EACrC,MAAM,oDAAoD,CAAA;AAC7D,OAAO,EAEL,yCAAyC,EAC1C,MAAM,uDAAuD,CAAA;AAiB9D,oBAAY,mBAAmB;IAE7B;;;;;OAKG;IACH,mBAAmB,gBAAgB;IACnC;;;OAGG;IACH,qBAAqB,kBAAkB;IACvC,+CAA+C;IAC/C,mBAAmB,gBAAgB;IACnC,uBAAuB;IACvB,gBAAgB,aAAa;CAC9B;AAED,oBAAY,0BAA0B;IACpC,yEAAyE;IACzE,cAAc,wBAAwB;CACvC;AAMD;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,WAAW,cAAc;IACzB,kBAAkB,cAAc;IAChC,mBAAmB,cAAc;IACjC,IAAI,SAAS;CACd;AAED,qCAAqC;AACrC,oBAAY,qBAAqB;IAC/B,GAAG,QAAQ;IACX,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED;;;;GAIG;AACH,oBAAY,wBAAwB;IAClC,WAAW,gBAAgB;IAC3B,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED,oBAAY,0BAA0B;IACpC,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,eAAO,MAAM,gDAAgD;;;;;;;;;iBAW3D,CAAC;AACH,MAAM,MAAM,yCAAyC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gDAAgD,CAAC,CAAC;AAMzH,eAAO,MAAM,yBAAyB;;;;iBAOpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,8CAA8C;;;;iBAIzD,CAAC;AACH,MAAM,MAAM,wCAAwC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8CAA8C,CAAC,CAAC;AAEtH,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;iBAKpD,CAAC;AACH,MAAM,MAAM,mCAAmC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yCAAyC,CAAC,CAAC;AAE5G,MAAM,MAAM,qCAAqC,GAAG,yCAAyC,GAAG;IAC9F,6BAA6B,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACjD,sBAAsB,EAAE,OAAO,yCAAyC,CAAC;IACzE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAA;AAMD,6EAA6E;AAC7E,eAAO,MAAM,kCAAkC;;iBAK7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAG9F,eAAO,MAAM,sCAAsC;;;;;iBAIjD,CAAC;AACH,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sCAAsC,CAAC,CAAC;AAEtG,8EAA8E;AAC9E,eAAO,MAAM,kCAAkC;;;;;iBAK7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAE9F,eAAO,MAAM,uCAAuC;;;;;;;;iBAIlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uCAAuC,CAAC,CAAC"}