@marktiderman/genesis-forms 0.8.0 → 0.9.0

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 (36) hide show
  1. package/README.md +299 -10
  2. package/dist/destinations.cjs +202 -39
  3. package/dist/destinations.cjs.map +1 -1
  4. package/dist/destinations.d.cts +67 -21
  5. package/dist/destinations.d.ts +67 -21
  6. package/dist/destinations.js +202 -40
  7. package/dist/destinations.js.map +1 -1
  8. package/dist/{engine-Bj23YJlB.d.cts → engine-BaHPC2-1.d.cts} +2 -2
  9. package/dist/{engine-CzinTJph.d.ts → engine-Da99Tv-E.d.ts} +2 -2
  10. package/dist/index.cjs +996 -167
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +288 -11
  13. package/dist/index.d.ts +288 -11
  14. package/dist/index.js +975 -168
  15. package/dist/index.js.map +1 -1
  16. package/dist/server.cjs +563 -173
  17. package/dist/server.cjs.map +1 -1
  18. package/dist/server.d.cts +3 -474
  19. package/dist/server.d.ts +3 -474
  20. package/dist/server.js +558 -174
  21. package/dist/server.js.map +1 -1
  22. package/dist/submit-protocol-CFi-0Qd0.d.ts +840 -0
  23. package/dist/submit-protocol-D0cOckmK.d.cts +840 -0
  24. package/dist/testing.cjs +250 -154
  25. package/dist/testing.cjs.map +1 -1
  26. package/dist/testing.d.cts +4 -4
  27. package/dist/testing.d.ts +4 -4
  28. package/dist/testing.js +250 -154
  29. package/dist/testing.js.map +1 -1
  30. package/dist/{types-jqDKcmP4.d.cts → types-C0pUfew3.d.cts} +7 -1
  31. package/dist/{types-jqDKcmP4.d.ts → types-C0pUfew3.d.ts} +7 -1
  32. package/dist/{validate-DvfQHYnu.d.ts → validate-DpmBssFk.d.ts} +258 -140
  33. package/dist/{validate-irIPubxc.d.cts → validate-U5LoW3eR.d.cts} +258 -140
  34. package/package.json +2 -2
  35. package/dist/upload-protocol-BOe018kL.d.cts +0 -122
  36. package/dist/upload-protocol-BUO74WkS.d.ts +0 -122
@@ -1,4 +1,4 @@
1
- import { J as Json, F as FormDefinition, a as FieldBlock, C as Condition } from './types-jqDKcmP4.cjs';
1
+ import { J as Json, F as FormDefinition, a as FieldBlock, C as Condition } from './types-C0pUfew3.cjs';
2
2
 
3
3
  /**
4
4
  * The contract every destination keeps. A destination sends one checked
@@ -103,6 +103,12 @@ interface DeliveryFailure {
103
103
  retryAfterSeconds?: number;
104
104
  /** The HTTP status that refused it, if one did. */
105
105
  status?: number;
106
+ /**
107
+ * The receiver asked to be switched off (a webhook answered 410 Gone, as
108
+ * Standard Webhooks specifies): disable the destination rather than keep
109
+ * sending to it. Always with `retryable: false`.
110
+ */
111
+ disable?: true;
106
112
  /** Safe to store and log: a status and a short reason, never secrets, answers or contact details. */
107
113
  error: string;
108
114
  }
@@ -129,10 +135,13 @@ declare class DeliveryError extends Error {
129
135
  readonly retryable: boolean;
130
136
  readonly retryAfterSeconds: number | undefined;
131
137
  readonly status: number | undefined;
138
+ /** The receiver asked to be switched off (`DeliveryFailure.disable`); never retryable. */
139
+ readonly disable: boolean;
132
140
  constructor(message: string, options?: {
133
141
  retryable?: boolean | undefined;
134
142
  retryAfterSeconds?: number | undefined;
135
143
  status?: number | undefined;
144
+ disable?: boolean | undefined;
136
145
  });
137
146
  }
138
147
  /** Every outbound request gives up after this long, unless the destination is given another `timeoutMs`. */
@@ -467,15 +476,17 @@ interface WebhookConfig {
467
476
  }
468
477
  interface WebhookDestinationOptions extends HttpDeps {
469
478
  /**
470
- * The signing secret: base64 of at least 16 random bytes, usually with
471
- * the `whsec_` prefix Standard Webhooks tools issue (`whsec_` plus base64
472
- * of 24 to 64 bytes is what the spec recommends). The prefix is optional;
473
- * the rest is always base64-decoded, as every Standard Webhooks library
474
- * does, so a receiver verifies with the same string. A secret that is not
475
- * base64 fails permanently. Or a function that finds the one for a
476
- * destination's config. Never put it in config.
479
+ * The signing secret: base64 of at least 24 random bytes (the spec
480
+ * recommends 24 to 64), usually with the `whsec_` prefix Standard Webhooks
481
+ * tools issue. The prefix is optional; the rest is always base64-decoded,
482
+ * as every Standard Webhooks library does, so a receiver verifies with the
483
+ * same string. A secret that is not base64, or is shorter, fails
484
+ * permanently. Several secrets (new and old, during a rotation) sign with
485
+ * each, space-separated in `webhook-signature`, so the receiver verifies
486
+ * with either. Or a function that finds them for a destination's config.
487
+ * Never put it in config.
477
488
  */
478
- secret: string | OptionResolver<string>;
489
+ secret: string | readonly string[] | OptionResolver<string | readonly string[]>;
479
490
  /** Allow `http:` URLs. Default false. */
480
491
  allowInsecureUrls?: boolean | undefined;
481
492
  /** Allow localhost and private, loopback and link-local address literals. Default false. */
@@ -502,7 +513,10 @@ interface WebhookDestinationOptions extends HttpDeps {
502
513
  /** The JSON body a webhook receives. */
503
514
  interface WebhookPayload {
504
515
  type: string;
505
- /** ISO time the delivery was sent. */
516
+ /**
517
+ * ISO time the event happened: the submission's `submittedAt`, or the send
518
+ * time when it has none. The `webhook-timestamp` header is the send time.
519
+ */
506
520
  timestamp: string;
507
521
  data: {
508
522
  form: {
@@ -524,17 +538,26 @@ interface WebhookPayload {
524
538
  row: Record<string, Json>;
525
539
  };
526
540
  }
541
+ /** The shortest signing secret, decoded: Standard Webhooks recommends 24 to 64 bytes. */
542
+ declare const MIN_WEBHOOK_SECRET_BYTES = 24;
527
543
  /**
528
544
  * A new signing secret: `whsec_` and standard base64 of 32 random bytes, the
529
545
  * form Standard Webhooks libraries read. Show it to the receiver once; keep it
530
546
  * out of config.
531
547
  */
532
548
  declare function newWebhookSecret(): string;
533
- /** The `webhook-signature` value for a message: `v1,<base64>`. */
534
- declare function signWebhook(secret: string, id: string, timestamp: number, body: string): Promise<string>;
549
+ /**
550
+ * The `webhook-signature` value for a message: `v1,<base64>`, or one such
551
+ * signature per secret, space-separated, when given several (a rotation).
552
+ */
553
+ declare function signWebhook(secret: string | readonly string[], id: string, timestamp: number, body: string): Promise<string>;
535
554
  interface VerifyWebhookInput {
536
- /** The same secret the sender signs with (base64, optionally `whsec_`-prefixed). */
537
- secret: string;
555
+ /**
556
+ * The same secret the sender signs with (base64, optionally
557
+ * `whsec_`-prefixed), or several (new and old, during a rotation): any one
558
+ * matching signature passes.
559
+ */
560
+ secret: string | readonly string[];
538
561
  /** The request's headers: a `Headers` or a plain object. */
539
562
  headers: Headers | Record<string, string | string[] | undefined>;
540
563
  /** The raw body, exactly as received. */
@@ -682,12 +705,25 @@ declare function googleOAuthAccessToken(client: GoogleOAuthClient, refreshToken:
682
705
  * problem, never the key.
683
706
  */
684
707
  declare function secretKeyBytes(key: string | Uint8Array): Uint8Array<ArrayBuffer>;
708
+ /** Options for `deriveSecretKey`. */
709
+ interface DeriveSecretKeyOptions {
710
+ /**
711
+ * The HKDF salt: bytes, or text taken as its UTF-8 bytes. Default empty,
712
+ * which is what every key derived before this option existed used, so
713
+ * leave it out to open those. For new keys a fixed, app-wide random value
714
+ * (say 32 bytes from `openssl rand -base64 32`, kept as config) is
715
+ * recommended (RFC 5869). It need not be secret, but must never change
716
+ * once anything is sealed with it.
717
+ */
718
+ salt?: string | Uint8Array | undefined;
719
+ }
685
720
  /**
686
721
  * An AES-GCM key for one purpose, derived from the app secret with HKDF-SHA-256
687
- * (empty salt, `info` naming the purpose). Use a different `info` for each
688
- * kind of secret; keep it fixed once anything is sealed with it.
722
+ * (`info` naming the purpose; the salt empty unless `options.salt` is given).
723
+ * Use a different `info` for each kind of secret; keep it, and the salt,
724
+ * fixed once anything is sealed with them.
689
725
  */
690
- declare function deriveSecretKey(key: string | Uint8Array, info: string): Promise<WebCryptoKey>;
726
+ declare function deriveSecretKey(key: string | Uint8Array, info: string, options?: DeriveSecretKeyOptions): Promise<WebCryptoKey>;
691
727
  /** Encrypts `plaintext` bound to `aad` (the row it belongs to): `v1.<iv>.<ciphertext>`. */
692
728
  declare function sealSecret(key: WebCryptoKey, plaintext: string, aad: string): Promise<string>;
693
729
  /**
@@ -713,7 +749,9 @@ declare function openSecret(key: WebCryptoKey, sealed: string, aad: string): Pro
713
749
  * - `retry`: a retryable failure. With the service's own Retry-After it is
714
750
  * deferred without counting an attempt (`counted: false`); otherwise it backs
715
751
  * off by attempt (`counted: true`), until `maxAttempts`.
716
- * - `failed`: permanent, an unknown kind, or out of attempts.
752
+ * - `failed`: permanent, an unknown kind, or out of attempts. With `disable:
753
+ * true` the receiver asked to be switched off (a webhook's 410 Gone): the
754
+ * app should disable the destination rather than keep sending to it.
717
755
  *
718
756
  * It never throws for a delivery's failure, and never logs answers, contact
719
757
  * details or secrets: only ids, kinds and the destinations' safe messages.
@@ -772,6 +810,8 @@ type DeliveryOutcome = {
772
810
  status: "failed";
773
811
  error: string;
774
812
  httpStatus?: number;
813
+ /** The receiver asked to be switched off (a webhook's 410 Gone): disable the destination. */
814
+ disable?: true;
775
815
  };
776
816
  interface ClaimRequest<Filter> {
777
817
  /** Most deliveries to claim. */
@@ -837,8 +877,14 @@ interface DeliveryRunner<Filter = undefined> {
837
877
  declare const DEFAULT_MAX_ATTEMPTS = 8;
838
878
  declare const DEFAULT_MAX_DEFERRALS = 24;
839
879
  declare const DEFAULT_BATCH_SIZE = 25;
840
- /** 1 minute, doubling each attempt, at most 6 hours: 1m, 2m, 4m … 6h. */
841
- declare function defaultBackoff(attempt: number): number;
880
+ /**
881
+ * 5 minutes, quadrupling each attempt, at most 24 hours: 5m, 20m, 80m, 5h20m,
882
+ * 21h20m, then 24h. Across the default 8 attempts that is about 3 days, as
883
+ * Standard Webhooks suggests. Each wait is jittered by up to ±20%, so
884
+ * deliveries that failed together (a receiver's outage) don't all come back
885
+ * at once. `random` (default `Math.random`) is for tests.
886
+ */
887
+ declare function defaultBackoff(attempt: number, random?: () => number): number;
842
888
  /** Turns a destination's result into an outcome for a delivery on its `attempt`. */
843
889
  declare function deliveryOutcome(result: DeliveryResult, attempt: number, options?: {
844
890
  now?: number | undefined;
@@ -850,4 +896,4 @@ declare function deliveryOutcome(result: DeliveryResult, attempt: number, option
850
896
  }): DeliveryOutcome;
851
897
  declare function createDeliveryRunner<Filter = undefined>(options: DeliveryRunnerOptions<Filter>): DeliveryRunner<Filter>;
852
898
 
853
- export { type Cell, type ClaimRequest, type ClaimedDelivery, DEDUPE_WINDOW, DEFAULT_BATCH_SIZE, DEFAULT_MAX_ATTEMPTS, DEFAULT_MAX_DEFERRALS, DEFAULT_SHEET_NAME, DRIVE_FILE_SCOPE, DeliveryError, type DeliveryFailure, type DeliveryItem, type DeliveryOptions, type DeliveryOutcome, type DeliveryReport, type DeliveryResult, type DeliveryRunner, type DeliveryRunnerOptions, type DeliverySubmission, type Destination, type DestinationConfig, type EmailConfig, type EmailContent, type EmailDestinationOptions, type EmailMessage, type EmailProvider, type EmailRenderInput, GOOGLE_TOKEN_URL, type GoogleOAuthClient, type GoogleOAuthTokenOptions, type GoogleServiceAccount, type GoogleTokenOptions, HEADER_SCAN_ROWS, type HookKind, HookUrlError, type HttpDeps, MAX_CONDITION_DEPTH, MAX_HOOK_URL_LENGTH, MAX_RECIPIENTS, type OptionResolver, REQUEST_TIMEOUT_MS, RESEND_API, type RefreshedGoogleToken, type ResendOptions, type ResolveContext, type ResolveHost, type ResponseRow, type RowOptions, type RunOptions, SENSITIVE_MASK, SHEETS_API, SHEETS_SCOPE, SLACK_HOSTS, SLACK_VALUE_LIMIT, type SheetConfig, type SheetState, type SheetsDestinationOptions, type SlackDestinationOptions, type SlackMessageInput, type SlackMessageOptions, type VerifyWebhookInput, type WebCryptoKey, type WebhookConfig, type WebhookDestinationOptions, type WebhookPayload, answerCell, checkHookHost, checkWebhookUrl, clearGoogleOAuthTokenCache, clearGoogleTokenCache, columnLetter, conditionOf, createDeliveryRunner, defaultBackoff, deliveryFailure, deliveryOutcome, deriveSecretKey, emailBody, emailDestination, escapeFormula, escapeHtml, escapeSlack, googleAccessToken, googleOAuthAccessToken, headerSafe, hookHost, httpError, idempotencyKey, isCondition, isPrivateHost, isPublicAddress, isRetryableStatus, isSafeAddress, isSafeFrom, mergeHeader, newWebhookSecret, openSecret, parseHookUrl, passesCondition, refreshGoogleAccessToken, renderEmail, resendProvider, responseRow, retryAfterSeconds, rowFor, sealSecret, secretKeyBytes, sheetsDestination, signJwt, signWebhook, slackDestination, slackMessage, verifyWebhook, visibleInputs, webhookDestination, webhookPayload };
899
+ export { type Cell, type ClaimRequest, type ClaimedDelivery, DEDUPE_WINDOW, DEFAULT_BATCH_SIZE, DEFAULT_MAX_ATTEMPTS, DEFAULT_MAX_DEFERRALS, DEFAULT_SHEET_NAME, DRIVE_FILE_SCOPE, DeliveryError, type DeliveryFailure, type DeliveryItem, type DeliveryOptions, type DeliveryOutcome, type DeliveryReport, type DeliveryResult, type DeliveryRunner, type DeliveryRunnerOptions, type DeliverySubmission, type DeriveSecretKeyOptions, type Destination, type DestinationConfig, type EmailConfig, type EmailContent, type EmailDestinationOptions, type EmailMessage, type EmailProvider, type EmailRenderInput, GOOGLE_TOKEN_URL, type GoogleOAuthClient, type GoogleOAuthTokenOptions, type GoogleServiceAccount, type GoogleTokenOptions, HEADER_SCAN_ROWS, type HookKind, HookUrlError, type HttpDeps, MAX_CONDITION_DEPTH, MAX_HOOK_URL_LENGTH, MAX_RECIPIENTS, MIN_WEBHOOK_SECRET_BYTES, type OptionResolver, REQUEST_TIMEOUT_MS, RESEND_API, type RefreshedGoogleToken, type ResendOptions, type ResolveContext, type ResolveHost, type ResponseRow, type RowOptions, type RunOptions, SENSITIVE_MASK, SHEETS_API, SHEETS_SCOPE, SLACK_HOSTS, SLACK_VALUE_LIMIT, type SheetConfig, type SheetState, type SheetsDestinationOptions, type SlackDestinationOptions, type SlackMessageInput, type SlackMessageOptions, type VerifyWebhookInput, type WebCryptoKey, type WebhookConfig, type WebhookDestinationOptions, type WebhookPayload, answerCell, checkHookHost, checkWebhookUrl, clearGoogleOAuthTokenCache, clearGoogleTokenCache, columnLetter, conditionOf, createDeliveryRunner, defaultBackoff, deliveryFailure, deliveryOutcome, deriveSecretKey, emailBody, emailDestination, escapeFormula, escapeHtml, escapeSlack, googleAccessToken, googleOAuthAccessToken, headerSafe, hookHost, httpError, idempotencyKey, isCondition, isPrivateHost, isPublicAddress, isRetryableStatus, isSafeAddress, isSafeFrom, mergeHeader, newWebhookSecret, openSecret, parseHookUrl, passesCondition, refreshGoogleAccessToken, renderEmail, resendProvider, responseRow, retryAfterSeconds, rowFor, sealSecret, secretKeyBytes, sheetsDestination, signJwt, signWebhook, slackDestination, slackMessage, verifyWebhook, visibleInputs, webhookDestination, webhookPayload };
@@ -1,4 +1,4 @@
1
- import { J as Json, F as FormDefinition, a as FieldBlock, C as Condition } from './types-jqDKcmP4.js';
1
+ import { J as Json, F as FormDefinition, a as FieldBlock, C as Condition } from './types-C0pUfew3.js';
2
2
 
3
3
  /**
4
4
  * The contract every destination keeps. A destination sends one checked
@@ -103,6 +103,12 @@ interface DeliveryFailure {
103
103
  retryAfterSeconds?: number;
104
104
  /** The HTTP status that refused it, if one did. */
105
105
  status?: number;
106
+ /**
107
+ * The receiver asked to be switched off (a webhook answered 410 Gone, as
108
+ * Standard Webhooks specifies): disable the destination rather than keep
109
+ * sending to it. Always with `retryable: false`.
110
+ */
111
+ disable?: true;
106
112
  /** Safe to store and log: a status and a short reason, never secrets, answers or contact details. */
107
113
  error: string;
108
114
  }
@@ -129,10 +135,13 @@ declare class DeliveryError extends Error {
129
135
  readonly retryable: boolean;
130
136
  readonly retryAfterSeconds: number | undefined;
131
137
  readonly status: number | undefined;
138
+ /** The receiver asked to be switched off (`DeliveryFailure.disable`); never retryable. */
139
+ readonly disable: boolean;
132
140
  constructor(message: string, options?: {
133
141
  retryable?: boolean | undefined;
134
142
  retryAfterSeconds?: number | undefined;
135
143
  status?: number | undefined;
144
+ disable?: boolean | undefined;
136
145
  });
137
146
  }
138
147
  /** Every outbound request gives up after this long, unless the destination is given another `timeoutMs`. */
@@ -467,15 +476,17 @@ interface WebhookConfig {
467
476
  }
468
477
  interface WebhookDestinationOptions extends HttpDeps {
469
478
  /**
470
- * The signing secret: base64 of at least 16 random bytes, usually with
471
- * the `whsec_` prefix Standard Webhooks tools issue (`whsec_` plus base64
472
- * of 24 to 64 bytes is what the spec recommends). The prefix is optional;
473
- * the rest is always base64-decoded, as every Standard Webhooks library
474
- * does, so a receiver verifies with the same string. A secret that is not
475
- * base64 fails permanently. Or a function that finds the one for a
476
- * destination's config. Never put it in config.
479
+ * The signing secret: base64 of at least 24 random bytes (the spec
480
+ * recommends 24 to 64), usually with the `whsec_` prefix Standard Webhooks
481
+ * tools issue. The prefix is optional; the rest is always base64-decoded,
482
+ * as every Standard Webhooks library does, so a receiver verifies with the
483
+ * same string. A secret that is not base64, or is shorter, fails
484
+ * permanently. Several secrets (new and old, during a rotation) sign with
485
+ * each, space-separated in `webhook-signature`, so the receiver verifies
486
+ * with either. Or a function that finds them for a destination's config.
487
+ * Never put it in config.
477
488
  */
478
- secret: string | OptionResolver<string>;
489
+ secret: string | readonly string[] | OptionResolver<string | readonly string[]>;
479
490
  /** Allow `http:` URLs. Default false. */
480
491
  allowInsecureUrls?: boolean | undefined;
481
492
  /** Allow localhost and private, loopback and link-local address literals. Default false. */
@@ -502,7 +513,10 @@ interface WebhookDestinationOptions extends HttpDeps {
502
513
  /** The JSON body a webhook receives. */
503
514
  interface WebhookPayload {
504
515
  type: string;
505
- /** ISO time the delivery was sent. */
516
+ /**
517
+ * ISO time the event happened: the submission's `submittedAt`, or the send
518
+ * time when it has none. The `webhook-timestamp` header is the send time.
519
+ */
506
520
  timestamp: string;
507
521
  data: {
508
522
  form: {
@@ -524,17 +538,26 @@ interface WebhookPayload {
524
538
  row: Record<string, Json>;
525
539
  };
526
540
  }
541
+ /** The shortest signing secret, decoded: Standard Webhooks recommends 24 to 64 bytes. */
542
+ declare const MIN_WEBHOOK_SECRET_BYTES = 24;
527
543
  /**
528
544
  * A new signing secret: `whsec_` and standard base64 of 32 random bytes, the
529
545
  * form Standard Webhooks libraries read. Show it to the receiver once; keep it
530
546
  * out of config.
531
547
  */
532
548
  declare function newWebhookSecret(): string;
533
- /** The `webhook-signature` value for a message: `v1,<base64>`. */
534
- declare function signWebhook(secret: string, id: string, timestamp: number, body: string): Promise<string>;
549
+ /**
550
+ * The `webhook-signature` value for a message: `v1,<base64>`, or one such
551
+ * signature per secret, space-separated, when given several (a rotation).
552
+ */
553
+ declare function signWebhook(secret: string | readonly string[], id: string, timestamp: number, body: string): Promise<string>;
535
554
  interface VerifyWebhookInput {
536
- /** The same secret the sender signs with (base64, optionally `whsec_`-prefixed). */
537
- secret: string;
555
+ /**
556
+ * The same secret the sender signs with (base64, optionally
557
+ * `whsec_`-prefixed), or several (new and old, during a rotation): any one
558
+ * matching signature passes.
559
+ */
560
+ secret: string | readonly string[];
538
561
  /** The request's headers: a `Headers` or a plain object. */
539
562
  headers: Headers | Record<string, string | string[] | undefined>;
540
563
  /** The raw body, exactly as received. */
@@ -682,12 +705,25 @@ declare function googleOAuthAccessToken(client: GoogleOAuthClient, refreshToken:
682
705
  * problem, never the key.
683
706
  */
684
707
  declare function secretKeyBytes(key: string | Uint8Array): Uint8Array<ArrayBuffer>;
708
+ /** Options for `deriveSecretKey`. */
709
+ interface DeriveSecretKeyOptions {
710
+ /**
711
+ * The HKDF salt: bytes, or text taken as its UTF-8 bytes. Default empty,
712
+ * which is what every key derived before this option existed used, so
713
+ * leave it out to open those. For new keys a fixed, app-wide random value
714
+ * (say 32 bytes from `openssl rand -base64 32`, kept as config) is
715
+ * recommended (RFC 5869). It need not be secret, but must never change
716
+ * once anything is sealed with it.
717
+ */
718
+ salt?: string | Uint8Array | undefined;
719
+ }
685
720
  /**
686
721
  * An AES-GCM key for one purpose, derived from the app secret with HKDF-SHA-256
687
- * (empty salt, `info` naming the purpose). Use a different `info` for each
688
- * kind of secret; keep it fixed once anything is sealed with it.
722
+ * (`info` naming the purpose; the salt empty unless `options.salt` is given).
723
+ * Use a different `info` for each kind of secret; keep it, and the salt,
724
+ * fixed once anything is sealed with them.
689
725
  */
690
- declare function deriveSecretKey(key: string | Uint8Array, info: string): Promise<WebCryptoKey>;
726
+ declare function deriveSecretKey(key: string | Uint8Array, info: string, options?: DeriveSecretKeyOptions): Promise<WebCryptoKey>;
691
727
  /** Encrypts `plaintext` bound to `aad` (the row it belongs to): `v1.<iv>.<ciphertext>`. */
692
728
  declare function sealSecret(key: WebCryptoKey, plaintext: string, aad: string): Promise<string>;
693
729
  /**
@@ -713,7 +749,9 @@ declare function openSecret(key: WebCryptoKey, sealed: string, aad: string): Pro
713
749
  * - `retry`: a retryable failure. With the service's own Retry-After it is
714
750
  * deferred without counting an attempt (`counted: false`); otherwise it backs
715
751
  * off by attempt (`counted: true`), until `maxAttempts`.
716
- * - `failed`: permanent, an unknown kind, or out of attempts.
752
+ * - `failed`: permanent, an unknown kind, or out of attempts. With `disable:
753
+ * true` the receiver asked to be switched off (a webhook's 410 Gone): the
754
+ * app should disable the destination rather than keep sending to it.
717
755
  *
718
756
  * It never throws for a delivery's failure, and never logs answers, contact
719
757
  * details or secrets: only ids, kinds and the destinations' safe messages.
@@ -772,6 +810,8 @@ type DeliveryOutcome = {
772
810
  status: "failed";
773
811
  error: string;
774
812
  httpStatus?: number;
813
+ /** The receiver asked to be switched off (a webhook's 410 Gone): disable the destination. */
814
+ disable?: true;
775
815
  };
776
816
  interface ClaimRequest<Filter> {
777
817
  /** Most deliveries to claim. */
@@ -837,8 +877,14 @@ interface DeliveryRunner<Filter = undefined> {
837
877
  declare const DEFAULT_MAX_ATTEMPTS = 8;
838
878
  declare const DEFAULT_MAX_DEFERRALS = 24;
839
879
  declare const DEFAULT_BATCH_SIZE = 25;
840
- /** 1 minute, doubling each attempt, at most 6 hours: 1m, 2m, 4m … 6h. */
841
- declare function defaultBackoff(attempt: number): number;
880
+ /**
881
+ * 5 minutes, quadrupling each attempt, at most 24 hours: 5m, 20m, 80m, 5h20m,
882
+ * 21h20m, then 24h. Across the default 8 attempts that is about 3 days, as
883
+ * Standard Webhooks suggests. Each wait is jittered by up to ±20%, so
884
+ * deliveries that failed together (a receiver's outage) don't all come back
885
+ * at once. `random` (default `Math.random`) is for tests.
886
+ */
887
+ declare function defaultBackoff(attempt: number, random?: () => number): number;
842
888
  /** Turns a destination's result into an outcome for a delivery on its `attempt`. */
843
889
  declare function deliveryOutcome(result: DeliveryResult, attempt: number, options?: {
844
890
  now?: number | undefined;
@@ -850,4 +896,4 @@ declare function deliveryOutcome(result: DeliveryResult, attempt: number, option
850
896
  }): DeliveryOutcome;
851
897
  declare function createDeliveryRunner<Filter = undefined>(options: DeliveryRunnerOptions<Filter>): DeliveryRunner<Filter>;
852
898
 
853
- export { type Cell, type ClaimRequest, type ClaimedDelivery, DEDUPE_WINDOW, DEFAULT_BATCH_SIZE, DEFAULT_MAX_ATTEMPTS, DEFAULT_MAX_DEFERRALS, DEFAULT_SHEET_NAME, DRIVE_FILE_SCOPE, DeliveryError, type DeliveryFailure, type DeliveryItem, type DeliveryOptions, type DeliveryOutcome, type DeliveryReport, type DeliveryResult, type DeliveryRunner, type DeliveryRunnerOptions, type DeliverySubmission, type Destination, type DestinationConfig, type EmailConfig, type EmailContent, type EmailDestinationOptions, type EmailMessage, type EmailProvider, type EmailRenderInput, GOOGLE_TOKEN_URL, type GoogleOAuthClient, type GoogleOAuthTokenOptions, type GoogleServiceAccount, type GoogleTokenOptions, HEADER_SCAN_ROWS, type HookKind, HookUrlError, type HttpDeps, MAX_CONDITION_DEPTH, MAX_HOOK_URL_LENGTH, MAX_RECIPIENTS, type OptionResolver, REQUEST_TIMEOUT_MS, RESEND_API, type RefreshedGoogleToken, type ResendOptions, type ResolveContext, type ResolveHost, type ResponseRow, type RowOptions, type RunOptions, SENSITIVE_MASK, SHEETS_API, SHEETS_SCOPE, SLACK_HOSTS, SLACK_VALUE_LIMIT, type SheetConfig, type SheetState, type SheetsDestinationOptions, type SlackDestinationOptions, type SlackMessageInput, type SlackMessageOptions, type VerifyWebhookInput, type WebCryptoKey, type WebhookConfig, type WebhookDestinationOptions, type WebhookPayload, answerCell, checkHookHost, checkWebhookUrl, clearGoogleOAuthTokenCache, clearGoogleTokenCache, columnLetter, conditionOf, createDeliveryRunner, defaultBackoff, deliveryFailure, deliveryOutcome, deriveSecretKey, emailBody, emailDestination, escapeFormula, escapeHtml, escapeSlack, googleAccessToken, googleOAuthAccessToken, headerSafe, hookHost, httpError, idempotencyKey, isCondition, isPrivateHost, isPublicAddress, isRetryableStatus, isSafeAddress, isSafeFrom, mergeHeader, newWebhookSecret, openSecret, parseHookUrl, passesCondition, refreshGoogleAccessToken, renderEmail, resendProvider, responseRow, retryAfterSeconds, rowFor, sealSecret, secretKeyBytes, sheetsDestination, signJwt, signWebhook, slackDestination, slackMessage, verifyWebhook, visibleInputs, webhookDestination, webhookPayload };
899
+ export { type Cell, type ClaimRequest, type ClaimedDelivery, DEDUPE_WINDOW, DEFAULT_BATCH_SIZE, DEFAULT_MAX_ATTEMPTS, DEFAULT_MAX_DEFERRALS, DEFAULT_SHEET_NAME, DRIVE_FILE_SCOPE, DeliveryError, type DeliveryFailure, type DeliveryItem, type DeliveryOptions, type DeliveryOutcome, type DeliveryReport, type DeliveryResult, type DeliveryRunner, type DeliveryRunnerOptions, type DeliverySubmission, type DeriveSecretKeyOptions, type Destination, type DestinationConfig, type EmailConfig, type EmailContent, type EmailDestinationOptions, type EmailMessage, type EmailProvider, type EmailRenderInput, GOOGLE_TOKEN_URL, type GoogleOAuthClient, type GoogleOAuthTokenOptions, type GoogleServiceAccount, type GoogleTokenOptions, HEADER_SCAN_ROWS, type HookKind, HookUrlError, type HttpDeps, MAX_CONDITION_DEPTH, MAX_HOOK_URL_LENGTH, MAX_RECIPIENTS, MIN_WEBHOOK_SECRET_BYTES, type OptionResolver, REQUEST_TIMEOUT_MS, RESEND_API, type RefreshedGoogleToken, type ResendOptions, type ResolveContext, type ResolveHost, type ResponseRow, type RowOptions, type RunOptions, SENSITIVE_MASK, SHEETS_API, SHEETS_SCOPE, SLACK_HOSTS, SLACK_VALUE_LIMIT, type SheetConfig, type SheetState, type SheetsDestinationOptions, type SlackDestinationOptions, type SlackMessageInput, type SlackMessageOptions, type VerifyWebhookInput, type WebCryptoKey, type WebhookConfig, type WebhookDestinationOptions, type WebhookPayload, answerCell, checkHookHost, checkWebhookUrl, clearGoogleOAuthTokenCache, clearGoogleTokenCache, columnLetter, conditionOf, createDeliveryRunner, defaultBackoff, deliveryFailure, deliveryOutcome, deriveSecretKey, emailBody, emailDestination, escapeFormula, escapeHtml, escapeSlack, googleAccessToken, googleOAuthAccessToken, headerSafe, hookHost, httpError, idempotencyKey, isCondition, isPrivateHost, isPublicAddress, isRetryableStatus, isSafeAddress, isSafeFrom, mergeHeader, newWebhookSecret, openSecret, parseHookUrl, passesCondition, refreshGoogleAccessToken, renderEmail, resendProvider, responseRow, retryAfterSeconds, rowFor, sealSecret, secretKeyBytes, sheetsDestination, signJwt, signWebhook, slackDestination, slackMessage, verifyWebhook, visibleInputs, webhookDestination, webhookPayload };