@marlinjai/mail-contract 0.6.0 → 0.7.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 (5) hide show
  1. package/dist/index.d.mts +16526 -2594
  2. package/dist/index.d.ts +16526 -2594
  3. package/dist/index.js +1044 -763
  4. package/dist/index.mjs +1017 -763
  5. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -145,13 +145,13 @@ var API_VERSION_PREFIX = "/v1";
145
145
  var HEALTH_PATH = "/healthz";
146
146
 
147
147
  // src/workspace.ts
148
- import { z as z9 } from "zod";
148
+ import { z as z10 } from "zod";
149
149
 
150
150
  // src/automations.ts
151
- import { z as z8 } from "zod";
151
+ import { z as z9 } from "zod";
152
152
 
153
153
  // src/templates.ts
154
- import { z as z4 } from "zod";
154
+ import { z as z5 } from "zod";
155
155
 
156
156
  // src/insertions.ts
157
157
  import { z as z3 } from "zod";
@@ -442,22 +442,133 @@ function sampleMergeValue(values) {
442
442
  };
443
443
  }
444
444
 
445
+ // src/template-inputs.ts
446
+ import { z as z4 } from "zod";
447
+ var MAX_TEMPLATE_INPUTS = 50;
448
+ var MAX_TEMPLATE_INPUT_VALUES = 30;
449
+ var MAX_TEMPLATE_INPUT_LABEL_LENGTH = 80;
450
+ var MAX_TEMPLATE_INPUT_NOTE_LENGTH = 300;
451
+ var MAX_TEMPLATE_INPUT_EXAMPLE_LENGTH = 500;
452
+ var MAX_TEMPLATE_INPUTS_APP_LENGTH = 80;
453
+ var MAX_TEMPLATE_INPUTS_SEEN = 200;
454
+ var SERVICE_FILLED_MERGE_FIELDS = ["email", "unsubscribe_url"];
455
+ var line = (max) => z4.string().min(1).max(max).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters").refine((s) => s.trim() !== "", "not blank");
456
+ var label = line(MAX_TEMPLATE_INPUT_LABEL_LENGTH);
457
+ var note = line(MAX_TEMPLATE_INPUT_NOTE_LENGTH);
458
+ var TemplateInputName = InsertionName;
459
+ var TemplateInputSource = z4.discriminatedUnion("kind", [
460
+ z4.object({ kind: z4.literal("form_field"), form: label, field: label, note: note.optional() }),
461
+ z4.object({ kind: z4.literal("derived"), note })
462
+ ]);
463
+ var TemplateInputValue = z4.object({
464
+ /** The key the app sends, in an insertion choice's syntax, so a row "When it is venue" matches it exactly. */
465
+ value: InsertionChoiceKey,
466
+ label
467
+ });
468
+ var HttpUrl = z4.string().max(MAX_TEMPLATE_INPUT_EXAMPLE_LENGTH).url().refine((u) => {
469
+ try {
470
+ const { protocol } = new URL(u);
471
+ return protocol === "https:" || protocol === "http:";
472
+ } catch {
473
+ return false;
474
+ }
475
+ }, "an http or https address");
476
+ var common = {
477
+ /** What an author sees: "Contact reason", "First name". */
478
+ label,
479
+ source: TemplateInputSource,
480
+ /** The app may send it empty or not at all (a name nobody typed). Absent means it is always sent. */
481
+ optional: z4.boolean().optional()
482
+ };
483
+ var TemplateInput = z4.discriminatedUnion("kind", [
484
+ z4.object({ kind: z4.literal("text"), ...common, example: z4.string().max(MAX_TEMPLATE_INPUT_EXAMPLE_LENGTH).optional() }),
485
+ z4.object({ kind: z4.literal("url"), ...common, example: HttpUrl.optional() }),
486
+ z4.object({ kind: z4.literal("boolean"), ...common, example: z4.boolean().optional() }),
487
+ z4.object({
488
+ kind: z4.literal("one_of"),
489
+ ...common,
490
+ values: z4.array(TemplateInputValue).min(1).max(MAX_TEMPLATE_INPUT_VALUES),
491
+ example: InsertionChoiceKey.optional()
492
+ })
493
+ ]);
494
+ var TEMPLATE_INPUT_KINDS = ["text", "url", "boolean", "one_of"];
495
+ var TemplateInputMap = z4.record(TemplateInputName, TemplateInput).refine((m) => Object.keys(m).length <= MAX_TEMPLATE_INPUTS, `at most ${MAX_TEMPLATE_INPUTS} inputs`);
496
+ var TemplateInputsDeclaration = z4.object({
497
+ app: line(MAX_TEMPLATE_INPUTS_APP_LENGTH),
498
+ app_version: line(MAX_TEMPLATE_INPUTS_APP_LENGTH).optional(),
499
+ inputs: TemplateInputMap
500
+ });
501
+ var TemplateInputs = z4.object({
502
+ app: z4.string(),
503
+ app_version: z4.string().nullable(),
504
+ inputs: TemplateInputMap,
505
+ declared_by: z4.object({ api_key_id: Id, api_key_name: z4.string() }),
506
+ declared_at: Timestamp
507
+ });
508
+ var TemplateInputSeen = z4.object({
509
+ count: z4.number().int().min(1),
510
+ first_seen_at: Timestamp,
511
+ last_seen_at: Timestamp
512
+ });
513
+ var TemplateInputsSeen = z4.record(TemplateInputName, TemplateInputSeen);
514
+ var TemplateInputsDeclared = z4.object({
515
+ template_id: Id,
516
+ inputs: TemplateInputs,
517
+ /** False when the stored declaration already said exactly this (a redeploy of the same commit). */
518
+ changed: z4.boolean()
519
+ });
520
+ var TEMPLATE_INPUT_PROBLEM_REASONS = [
521
+ /** `email` or `unsubscribe_url`: the service fills it, a client's value is never read. */
522
+ "input_reserved",
523
+ /** A `one_of` input lists the same value twice. */
524
+ "input_values",
525
+ /** A `one_of` input's example is not one of its values. */
526
+ "input_example"
527
+ ];
528
+ function templateInputProblems(inputs) {
529
+ const problems = [];
530
+ for (const [name, input] of Object.entries(inputs)) {
531
+ if (SERVICE_FILLED_MERGE_FIELDS.includes(name)) {
532
+ problems.push({ reason: "input_reserved", path: name, message: `"${name}" is filled by the service, never by the app; leave it out of the declaration` });
533
+ }
534
+ if (input.kind !== "one_of") continue;
535
+ const seen = /* @__PURE__ */ new Set();
536
+ input.values.forEach((v, i) => {
537
+ if (seen.has(v.value)) {
538
+ problems.push({ reason: "input_values", path: `${name}.values.${i}`, message: `"${v.value}" is listed twice` });
539
+ }
540
+ seen.add(v.value);
541
+ });
542
+ if (input.example !== void 0 && !seen.has(input.example)) {
543
+ problems.push({ reason: "input_example", path: `${name}.example`, message: `the example "${input.example}" is not one of the values` });
544
+ }
545
+ }
546
+ return problems;
547
+ }
548
+ function templateInputDrift(inputs, seen) {
549
+ const declared = inputs ? Object.keys(inputs.inputs) : [];
550
+ return {
551
+ declared_not_seen: declared.filter((name) => ownEntry(seen, name) === void 0).sort(),
552
+ seen_not_declared: Object.keys(seen).filter((name) => ownEntry(inputs?.inputs, name) === void 0).sort()
553
+ };
554
+ }
555
+
445
556
  // src/templates.ts
446
557
  var DOCUMENT_SCHEMA_VERSIONS = ["1.0", "1.1"];
447
- var DocumentSchemaVersion = z4.enum(DOCUMENT_SCHEMA_VERSIONS);
448
- var TemplateDocument = z4.object({
558
+ var DocumentSchemaVersion = z5.enum(DOCUMENT_SCHEMA_VERSIONS);
559
+ var TemplateDocument = z5.object({
449
560
  version: DocumentSchemaVersion,
450
- metadata: z4.record(z4.unknown()),
451
- sections: z4.array(z4.record(z4.unknown()))
561
+ metadata: z5.record(z5.unknown()),
562
+ sections: z5.array(z5.record(z5.unknown()))
452
563
  }).passthrough();
453
564
  var MAX_DOCUMENT_BYTES = 1e6;
454
565
  var MAX_SUBJECT_LENGTH = 998;
455
566
  var MAX_PREHEADER_LENGTH = 500;
456
- var TemplateSubject = z4.string().max(MAX_SUBJECT_LENGTH).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters");
457
- var TemplatePreheader = z4.string().max(MAX_PREHEADER_LENGTH).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters");
567
+ var TemplateSubject = z5.string().max(MAX_SUBJECT_LENGTH).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters");
568
+ var TemplatePreheader = z5.string().max(MAX_PREHEADER_LENGTH).regex(/^[^\x00-\x1f\x7f]*$/, "one line, without control characters");
458
569
  var TEMPLATE_LANGUAGE_STATUSES = ["draft", "ready"];
459
- var TemplateLanguageStatus = z4.enum(TEMPLATE_LANGUAGE_STATUSES);
460
- var TemplateTranslation = z4.object({
570
+ var TemplateLanguageStatus = z5.enum(TEMPLATE_LANGUAGE_STATUSES);
571
+ var TemplateTranslation = z5.object({
461
572
  subject: TemplateSubject.nullable(),
462
573
  preheader: TemplatePreheader.nullable(),
463
574
  document: TemplateDocument,
@@ -475,11 +586,11 @@ var TemplateTranslation = z4.object({
475
586
  insertions: TranslationInsertions.optional()
476
587
  });
477
588
  var MAX_TEMPLATE_TRANSLATIONS = 19;
478
- var TemplateTranslations = z4.record(LocaleTag, TemplateTranslation).refine((t) => Object.keys(t).length <= MAX_TEMPLATE_TRANSLATIONS, `at most ${MAX_TEMPLATE_TRANSLATIONS} language versions`);
479
- var Template = z4.object({
589
+ var TemplateTranslations = z5.record(LocaleTag, TemplateTranslation).refine((t) => Object.keys(t).length <= MAX_TEMPLATE_TRANSLATIONS, `at most ${MAX_TEMPLATE_TRANSLATIONS} language versions`);
590
+ var Template = z5.object({
480
591
  id: Id,
481
- name: z4.string().min(1).max(200),
482
- description: z4.string().max(2e3).nullable(),
592
+ name: z5.string().min(1).max(200),
593
+ description: z5.string().max(2e3).nullable(),
483
594
  /**
484
595
  * The main language: what `subject`, `preheader` and `document` are written
485
596
  * in, and what every recipient without a ready version of their own gets.
@@ -503,21 +614,33 @@ var Template = z4.object({
503
614
  * texts in `translations[tag].insertions`.
504
615
  */
505
616
  insertions: Insertions,
617
+ /**
618
+ * What the sending app declared this template receives
619
+ * (`templates.declareInputs`); null until an app declares. Not part of a
620
+ * version: declaring never changes `version` or `updated_at`.
621
+ */
622
+ inputs: TemplateInputs.nullable(),
623
+ /**
624
+ * The merge names real sends of this template carried, with a count and
625
+ * when first and last seen. Names only, never values. `{}` before the
626
+ * first send.
627
+ */
628
+ inputs_seen: TemplateInputsSeen,
506
629
  /** Increments on every saved change, of any language. */
507
- version: z4.number().int().min(1),
508
- thumbnail_url: z4.string().url().nullable(),
630
+ version: z5.number().int().min(1),
631
+ thumbnail_url: z5.string().url().nullable(),
509
632
  archived_at: Timestamp.nullable(),
510
633
  created_at: Timestamp,
511
634
  updated_at: Timestamp
512
635
  });
513
- var TemplateSummary = Template.omit({ document: true, translations: true, insertions: true }).extend({
514
- languages: z4.record(LocaleTag, TemplateLanguageStatus),
636
+ var TemplateSummary = Template.omit({ document: true, translations: true, insertions: true, inputs: true, inputs_seen: true }).extend({
637
+ languages: z5.record(LocaleTag, TemplateLanguageStatus),
515
638
  /** The names of the template's insertions, sorted alphabetically. */
516
- insertion_names: z4.array(z4.string())
639
+ insertion_names: z5.array(z5.string())
517
640
  });
518
- var TemplateCreate = z4.object({
519
- name: z4.string().min(1).max(200),
520
- description: z4.string().max(2e3).optional(),
641
+ var TemplateCreate = z5.object({
642
+ name: z5.string().min(1).max(200),
643
+ description: z5.string().max(2e3).optional(),
521
644
  locale: LocaleTag.optional(),
522
645
  subject: TemplateSubject.nullable().optional(),
523
646
  preheader: TemplatePreheader.nullable().optional(),
@@ -525,15 +648,15 @@ var TemplateCreate = z4.object({
525
648
  translations: TemplateTranslations.optional(),
526
649
  insertions: Insertions.optional()
527
650
  });
528
- var TemplateUpdate = z4.object({
529
- base_version: z4.number().int().min(1),
530
- name: z4.string().min(1).max(200).optional(),
531
- description: z4.string().max(2e3).nullable().optional(),
651
+ var TemplateUpdate = z5.object({
652
+ base_version: z5.number().int().min(1),
653
+ name: z5.string().min(1).max(200).optional(),
654
+ description: z5.string().max(2e3).nullable().optional(),
532
655
  locale: LocaleTag.optional(),
533
656
  subject: TemplateSubject.nullable().optional(),
534
657
  preheader: TemplatePreheader.nullable().optional(),
535
658
  document: TemplateDocument.optional(),
536
- translations: z4.record(LocaleTag, TemplateTranslation.nullable()).optional(),
659
+ translations: z5.record(LocaleTag, TemplateTranslation.nullable()).optional(),
537
660
  /**
538
661
  * The main language's insertions, whole: what is left out is removed, from
539
662
  * every language in the same save. A rename is a removal and an addition,
@@ -541,87 +664,87 @@ var TemplateUpdate = z4.object({
541
664
  * save (it sends those languages in `translations`).
542
665
  */
543
666
  insertions: Insertions.optional(),
544
- archived: z4.boolean().optional()
667
+ archived: z5.boolean().optional()
545
668
  }).refine(
546
669
  (v) => v.name !== void 0 || v.description !== void 0 || v.locale !== void 0 || v.subject !== void 0 || v.preheader !== void 0 || v.document !== void 0 || v.translations !== void 0 || v.insertions !== void 0 || v.archived !== void 0,
547
670
  "at least one field besides base_version"
548
671
  );
549
- var SavedSectionBody = z4.record(z4.unknown());
672
+ var SavedSectionBody = z5.record(z5.unknown());
550
673
  var MAX_SAVED_SECTIONS = 50;
551
- var SavedSection = z4.object({
674
+ var SavedSection = z5.object({
552
675
  id: Id,
553
- name: z4.string().min(1).max(200),
554
- description: z4.string().max(2e3).nullable(),
676
+ name: z5.string().min(1).max(200),
677
+ description: z5.string().max(2e3).nullable(),
555
678
  section: SavedSectionBody,
556
- created_by: z4.string().nullable(),
679
+ created_by: z5.string().nullable(),
557
680
  created_at: Timestamp,
558
681
  updated_at: Timestamp
559
682
  });
560
- var SavedSectionCreate = z4.object({
561
- name: z4.string().min(1).max(200),
562
- description: z4.string().max(2e3).optional(),
683
+ var SavedSectionCreate = z5.object({
684
+ name: z5.string().min(1).max(200),
685
+ description: z5.string().max(2e3).optional(),
563
686
  section: SavedSectionBody
564
687
  });
565
- var SavedSectionUpdate = z4.object({
566
- name: z4.string().min(1).max(200).optional(),
567
- description: z4.string().max(2e3).nullable().optional(),
688
+ var SavedSectionUpdate = z5.object({
689
+ name: z5.string().min(1).max(200).optional(),
690
+ description: z5.string().max(2e3).nullable().optional(),
568
691
  section: SavedSectionBody.optional()
569
692
  }).refine((v) => v.name !== void 0 || v.description !== void 0 || v.section !== void 0, "at least one field");
570
693
  var TemplateListQuery = PageQuery.extend({
571
- archived: z4.enum(["true", "false"]).optional()
694
+ archived: z5.enum(["true", "false"]).optional()
572
695
  });
573
- var TemplateVersion = z4.object({
696
+ var TemplateVersion = z5.object({
574
697
  template_id: Id,
575
- version: z4.number().int().min(1),
698
+ version: z5.number().int().min(1),
576
699
  locale: LocaleTag,
577
700
  subject: TemplateSubject.nullable(),
578
701
  preheader: TemplatePreheader.nullable(),
579
702
  document: TemplateDocument,
580
703
  translations: TemplateTranslations,
581
704
  insertions: Insertions,
582
- created_by: z4.string().nullable(),
705
+ created_by: z5.string().nullable(),
583
706
  created_at: Timestamp
584
707
  });
585
- var TemplateVersionParams = z4.object({
708
+ var TemplateVersionParams = z5.object({
586
709
  id: Id,
587
- version: z4.coerce.number().int().min(1)
710
+ version: z5.coerce.number().int().min(1)
588
711
  });
589
- var CompileMessage = z4.object({
590
- message: z4.string().min(1),
712
+ var CompileMessage = z5.object({
713
+ message: z5.string().min(1),
591
714
  /** Where in the document or the MJML the message points, when known. */
592
- path: z4.string().optional(),
593
- line: z4.number().int().min(1).optional()
715
+ path: z5.string().optional(),
716
+ line: z5.number().int().min(1).optional()
594
717
  });
595
- var CompileResult = z4.object({
596
- mjml: z4.string(),
597
- html: z4.string(),
598
- warnings: z4.array(CompileMessage),
599
- errors: z4.array(CompileMessage)
718
+ var CompileResult = z5.object({
719
+ mjml: z5.string(),
720
+ html: z5.string(),
721
+ warnings: z5.array(CompileMessage),
722
+ errors: z5.array(CompileMessage)
600
723
  });
601
- var TemplateCompileRequest = z4.object({
602
- version: z4.number().int().min(1).optional(),
724
+ var TemplateCompileRequest = z5.object({
725
+ version: z5.number().int().min(1).optional(),
603
726
  locale: LocaleTag.optional()
604
727
  });
605
- var CompileRequest = z4.object({
728
+ var CompileRequest = z5.object({
606
729
  document: TemplateDocument
607
730
  });
608
731
  var ASSET_CONTENT_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
609
- var AssetContentType = z4.enum(ASSET_CONTENT_TYPES);
732
+ var AssetContentType = z5.enum(ASSET_CONTENT_TYPES);
610
733
  var MAX_ASSET_BYTES = 10 * 1024 * 1024;
611
- var Asset = z4.object({
734
+ var Asset = z5.object({
612
735
  id: Id,
613
- url: z4.string().url(),
736
+ url: z5.string().url(),
614
737
  content_type: AssetContentType,
615
- size_bytes: z4.number().int().min(1).max(MAX_ASSET_BYTES),
616
- width: z4.number().int().min(1).nullable(),
617
- height: z4.number().int().min(1).nullable(),
618
- filename: z4.string().min(1).max(255),
738
+ size_bytes: z5.number().int().min(1).max(MAX_ASSET_BYTES),
739
+ width: z5.number().int().min(1).nullable(),
740
+ height: z5.number().int().min(1).nullable(),
741
+ filename: z5.string().min(1).max(255),
619
742
  created_at: Timestamp
620
743
  });
621
744
  var ASSET_UPLOAD_FIELD = "file";
622
745
  var MAX_IMPORT_URL_LENGTH = 2048;
623
- var AssetImport = z4.object({
624
- url: z4.string().max(MAX_IMPORT_URL_LENGTH).url().refine((u) => {
746
+ var AssetImport = z5.object({
747
+ url: z5.string().max(MAX_IMPORT_URL_LENGTH).url().refine((u) => {
625
748
  try {
626
749
  const url = new URL(u);
627
750
  if (url.protocol === "https:") return true;
@@ -631,7 +754,7 @@ var AssetImport = z4.object({
631
754
  }
632
755
  }, "must be https (http only for localhost)"),
633
756
  /** The stored file name; derived from the address when omitted. */
634
- filename: z4.string().min(1).max(255).optional()
757
+ filename: z5.string().min(1).max(255).optional()
635
758
  });
636
759
  var MAX_MJML_IMPORT_BYTES = 512 * 1024;
637
760
  var MAX_MJML_DEPTH = 32;
@@ -646,56 +769,56 @@ var MJML_IMPORT_REFUSALS = [
646
769
  "too_complex",
647
770
  "invalid_document"
648
771
  ];
649
- var ImportWarning = z4.object({
650
- severity: z4.enum(["info", "warning"]),
772
+ var ImportWarning = z5.object({
773
+ severity: z5.enum(["info", "warning"]),
651
774
  /** Stable kind, e.g. `kept_as_html`, `unknown_component`, `remote_image_not_imported`. */
652
- code: z4.string().min(1).max(64),
775
+ code: z5.string().min(1).max(64),
653
776
  /** Where in the source, e.g. `mj-body > mj-section[2] > mj-column[1] > mj-social[1]`. */
654
- path: z4.string(),
655
- line: z4.number().int().min(1).optional(),
656
- message: z4.string().min(1),
657
- fragment: z4.string().optional()
777
+ path: z5.string(),
778
+ line: z5.number().int().min(1).optional(),
779
+ message: z5.string().min(1),
780
+ fragment: z5.string().optional()
658
781
  });
659
- var RemoteImage = z4.object({
660
- url: z4.string().min(1),
782
+ var RemoteImage = z5.object({
783
+ url: z5.string().min(1),
661
784
  /** The element and attribute it is loaded from, e.g. `<img src>`. */
662
- where: z4.string()
785
+ where: z5.string()
663
786
  });
664
- var ImportedAsset = z4.object({
665
- source_url: z4.string().min(1),
787
+ var ImportedAsset = z5.object({
788
+ source_url: z5.string().min(1),
666
789
  asset_id: Id,
667
- url: z4.string().url()
790
+ url: z5.string().url()
668
791
  });
669
- var mjmlSource = z4.string().min(1, "paste or upload the MJML");
670
- var TemplateImportPreviewRequest = z4.object({ mjml: mjmlSource });
671
- var TemplateImportPreview = z4.object({
792
+ var mjmlSource = z5.string().min(1, "paste or upload the MJML");
793
+ var TemplateImportPreviewRequest = z5.object({ mjml: mjmlSource });
794
+ var TemplateImportPreview = z5.object({
672
795
  document: TemplateDocument,
673
- warnings: z4.array(ImportWarning),
796
+ warnings: z5.array(ImportWarning),
674
797
  /** The document compiled under the workspace's asset policy, exactly as a send would. */
675
798
  compiled: CompileResult,
676
799
  /** Images loaded from outside the service; under `service_only` each is also a compile error. */
677
- remote_images: z4.array(RemoteImage),
678
- asset_policy: z4.enum(["any", "service_only"])
800
+ remote_images: z5.array(RemoteImage),
801
+ asset_policy: z5.enum(["any", "service_only"])
679
802
  });
680
- var TemplateImport = z4.object({
681
- name: z4.string().min(1).max(200),
682
- description: z4.string().max(2e3).optional(),
803
+ var TemplateImport = z5.object({
804
+ name: z5.string().min(1).max(200),
805
+ description: z5.string().max(2e3).optional(),
683
806
  mjml: mjmlSource,
684
- import_remote_assets: z4.boolean().optional()
807
+ import_remote_assets: z5.boolean().optional()
685
808
  });
686
- var TemplateImportResult = z4.object({
809
+ var TemplateImportResult = z5.object({
687
810
  template: Template,
688
- warnings: z4.array(ImportWarning),
689
- imported_assets: z4.array(ImportedAsset)
811
+ warnings: z5.array(ImportWarning),
812
+ imported_assets: z5.array(ImportedAsset)
690
813
  });
691
814
  var EXPORT_FORMATS = ["mjml", "html"];
692
- var ExportFormat = z4.enum(EXPORT_FORMATS);
693
- var TemplateExportQuery = z4.object({
815
+ var ExportFormat = z5.enum(EXPORT_FORMATS);
816
+ var TemplateExportQuery = z5.object({
694
817
  format: ExportFormat,
695
- version: z4.coerce.number().int().min(1).optional(),
818
+ version: z5.coerce.number().int().min(1).optional(),
696
819
  locale: LocaleTag.optional()
697
820
  });
698
- var MailingExportQuery = z4.object({ format: ExportFormat });
821
+ var MailingExportQuery = z5.object({ format: ExportFormat });
699
822
  var EXPORT_CONTENT_TYPES = {
700
823
  mjml: "text/plain; charset=utf-8",
701
824
  html: "text/html; charset=utf-8"
@@ -714,7 +837,7 @@ function formatExportWarningsHeader(messages) {
714
837
  function parseExportWarningsHeader(value) {
715
838
  if (!value) return [];
716
839
  try {
717
- const parsed = z4.array(CompileMessage).safeParse(JSON.parse(decodeURIComponent(value)));
840
+ const parsed = z5.array(CompileMessage).safeParse(JSON.parse(decodeURIComponent(value)));
718
841
  return parsed.success ? parsed.data : [];
719
842
  } catch {
720
843
  return [];
@@ -726,32 +849,32 @@ function exportFilename(name, format) {
726
849
  }
727
850
 
728
851
  // src/platform.ts
729
- import { z as z7 } from "zod";
852
+ import { z as z8 } from "zod";
730
853
 
731
854
  // src/mailings.ts
732
- import { z as z6 } from "zod";
855
+ import { z as z7 } from "zod";
733
856
 
734
857
  // src/ab-test.ts
735
- import { z as z5 } from "zod";
736
- var AbVariant = z5.object({
737
- key: z5.string().regex(/^[a-z]$/, "a single lowercase letter"),
738
- subject: z5.string().min(1).max(998).optional(),
858
+ import { z as z6 } from "zod";
859
+ var AbVariant = z6.object({
860
+ key: z6.string().regex(/^[a-z]$/, "a single lowercase letter"),
861
+ subject: z6.string().min(1).max(998).optional(),
739
862
  /** Replaces the mailing's document for this variant. */
740
- document: z5.record(z5.unknown()).optional(),
863
+ document: z6.record(z6.unknown()).optional(),
741
864
  /**
742
865
  * Keeps the document this variant key already has in the mailing's current
743
866
  * test, so a test can be changed without sending every document again. The
744
867
  * service refuses it (`validation_failed`) when that variant has none.
745
868
  */
746
- keep_document: z5.literal(true).optional()
869
+ keep_document: z6.literal(true).optional()
747
870
  });
748
871
  var AB_WINNER_METRICS = ["opens", "clicks", "manual"];
749
- var AbTestConfig = z5.object({
750
- variants: z5.array(AbVariant).min(2).max(5),
872
+ var AbTestConfig = z6.object({
873
+ variants: z6.array(AbVariant).min(2).max(5),
751
874
  /** Share of recipients in the test group, split evenly across variants; the rest get the winner. */
752
- test_fraction: z5.number().gt(0).lte(1),
753
- winner_metric: z5.enum(AB_WINNER_METRICS),
754
- decide_after_minutes: z5.number().int().min(15).max(10080).optional()
875
+ test_fraction: z6.number().gt(0).lte(1),
876
+ winner_metric: z6.enum(AB_WINNER_METRICS),
877
+ decide_after_minutes: z6.number().int().min(15).max(10080).optional()
755
878
  }).refine((c) => new Set(c.variants.map((v) => v.key)).size === c.variants.length, "variant keys must be unique").refine((c) => c.variants.every((v) => v.subject !== void 0 || v.document !== void 0 || v.keep_document === true), {
756
879
  message: "every variant changes the subject, the document or both",
757
880
  path: ["variants"]
@@ -763,19 +886,19 @@ var AbTestConfig = z5.object({
763
886
  path: ["decide_after_minutes"]
764
887
  });
765
888
  var AB_TEST_STATUSES = ["pending", "testing", "awaiting_pick", "decided"];
766
- var AbTestState = z5.object({
767
- variants: z5.array(z5.object({ key: z5.string(), subject: z5.string().nullable(), has_document: z5.boolean() })),
768
- test_fraction: z5.number(),
769
- winner_metric: z5.enum(AB_WINNER_METRICS),
770
- decide_after_minutes: z5.number().int().nullable(),
771
- status: z5.enum(AB_TEST_STATUSES),
889
+ var AbTestState = z6.object({
890
+ variants: z6.array(z6.object({ key: z6.string(), subject: z6.string().nullable(), has_document: z6.boolean() })),
891
+ test_fraction: z6.number(),
892
+ winner_metric: z6.enum(AB_WINNER_METRICS),
893
+ decide_after_minutes: z6.number().int().nullable(),
894
+ status: z6.enum(AB_TEST_STATUSES),
772
895
  /** When the metric decides; null for manual or before the start. */
773
896
  decide_at: Timestamp.nullable(),
774
- winner: z5.string().nullable(),
775
- decided_by: z5.enum(["metric", "manual"]).nullable(),
897
+ winner: z6.string().nullable(),
898
+ decided_by: z6.enum(["metric", "manual"]).nullable(),
776
899
  decided_at: Timestamp.nullable()
777
900
  });
778
- var AbWinnerRequest = z5.object({ variant: z5.string().regex(/^[a-z]$/) });
901
+ var AbWinnerRequest = z6.object({ variant: z6.string().regex(/^[a-z]$/) });
779
902
  function testGroupSize(total, fraction, variants) {
780
903
  return Math.min(total, Math.max(variants, Math.ceil(total * fraction)));
781
904
  }
@@ -790,9 +913,9 @@ var MAILING_STATUSES = [
790
913
  "partially_failed",
791
914
  "cancelled"
792
915
  ];
793
- var MailingStatus = z6.enum(MAILING_STATUSES);
916
+ var MailingStatus = z7.enum(MAILING_STATUSES);
794
917
  var MAILING_ACTIONS = ["send", "schedule", "unschedule", "pause", "resume", "cancel", "retry-failed"];
795
- var MailingAction = z6.enum(MAILING_ACTIONS);
918
+ var MailingAction = z7.enum(MAILING_ACTIONS);
796
919
  var MAILING_TRANSITIONS = {
797
920
  draft: ["send", "schedule", "cancel"],
798
921
  scheduled: ["send", "schedule", "unschedule", "cancel"],
@@ -807,23 +930,23 @@ function canTransition(status, action) {
807
930
  }
808
931
  var EDITABLE_MAILING_STATUSES = ["draft", "scheduled"];
809
932
  var TERMINAL_MAILING_STATUSES = ["sent", "cancelled"];
810
- var MailingMetadata = z6.record(z6.string().max(500)).refine((v) => Object.keys(v).length <= 20, "at most 20 keys").refine((v) => Object.keys(v).every((k) => k.length >= 1 && k.length <= 64), "keys are 1 to 64 characters");
811
- var MailingCounts = z6.object({
812
- total: z6.number().int().min(0),
813
- queued: z6.number().int().min(0),
814
- sending: z6.number().int().min(0),
815
- sent: z6.number().int().min(0),
816
- failed: z6.number().int().min(0),
817
- skipped: z6.number().int().min(0)
933
+ var MailingMetadata = z7.record(z7.string().max(500)).refine((v) => Object.keys(v).length <= 20, "at most 20 keys").refine((v) => Object.keys(v).every((k) => k.length >= 1 && k.length <= 64), "keys are 1 to 64 characters");
934
+ var MailingCounts = z7.object({
935
+ total: z7.number().int().min(0),
936
+ queued: z7.number().int().min(0),
937
+ sending: z7.number().int().min(0),
938
+ sent: z7.number().int().min(0),
939
+ failed: z7.number().int().min(0),
940
+ skipped: z7.number().int().min(0)
818
941
  });
819
942
  var MAILING_KINDS = ["broadcast", "automation", "notification"];
820
- var MailingKind = z6.enum(MAILING_KINDS);
821
- var Mailing = z6.object({
943
+ var MailingKind = z7.enum(MAILING_KINDS);
944
+ var Mailing = z7.object({
822
945
  id: Id,
823
946
  kind: MailingKind,
824
- name: z6.string().max(200).nullable(),
825
- subject: z6.string().min(1).max(998),
826
- preheader: z6.string().max(500).nullable(),
947
+ name: z7.string().max(200).nullable(),
948
+ subject: z7.string().min(1).max(998),
949
+ preheader: z7.string().max(500).nullable(),
827
950
  /**
828
951
  * The template the document was taken from, if any. The snapshot is what is
829
952
  * sent in the main language; the template's other language versions are
@@ -868,15 +991,15 @@ var Mailing = z6.object({
868
991
  * recipients refused as dead addresses in one run (see the provider's
869
992
  * `rejections.anomaly`). Resuming clears it and starts a new run.
870
993
  */
871
- pause_reason: z6.string().nullable().default(null),
994
+ pause_reason: z7.string().nullable().default(null),
872
995
  created_at: Timestamp,
873
996
  updated_at: Timestamp
874
997
  });
875
998
  var MailingSummary = Mailing.omit({ document: true });
876
999
  var MailingContent = {
877
- name: z6.string().max(200).optional(),
878
- subject: z6.string().min(1).max(998),
879
- preheader: z6.string().max(500).optional(),
1000
+ name: z7.string().max(200).optional(),
1001
+ subject: z7.string().min(1).max(998),
1002
+ preheader: z7.string().max(500).optional(),
880
1003
  /** See `Mailing.send_locale`. */
881
1004
  send_locale: LocaleTag.nullable().optional(),
882
1005
  /**
@@ -889,7 +1012,7 @@ var MailingContent = {
889
1012
  provider_id: Id,
890
1013
  metadata: MailingMetadata.optional()
891
1014
  };
892
- var MailingCreate = z6.object({
1015
+ var MailingCreate = z7.object({
893
1016
  ...MailingContent,
894
1017
  subject: MailingContent.subject.optional(),
895
1018
  document: TemplateDocument.optional(),
@@ -901,10 +1024,10 @@ var MailingCreate = z6.object({
901
1024
  message: "a mailing made from a document needs a subject",
902
1025
  path: ["subject"]
903
1026
  });
904
- var MailingUpdate = z6.object({
905
- name: z6.string().max(200).nullable().optional(),
1027
+ var MailingUpdate = z7.object({
1028
+ name: z7.string().max(200).nullable().optional(),
906
1029
  subject: MailingContent.subject.optional(),
907
- preheader: z6.string().max(500).nullable().optional(),
1030
+ preheader: z7.string().max(500).nullable().optional(),
908
1031
  /** Null turns a draft into a letter, which it can only be with at most one recipient. */
909
1032
  topic: Slug.nullable().optional(),
910
1033
  send_locale: LocaleTag.nullable().optional(),
@@ -918,30 +1041,30 @@ var MailingListQuery = PageQuery.extend({
918
1041
  kind: MailingKind.optional(),
919
1042
  automation_id: Id.optional()
920
1043
  });
921
- var MailingSendRequest = z6.object({}).strict();
922
- var MailingRetryFailedRequest = z6.object({
1044
+ var MailingSendRequest = z7.object({}).strict();
1045
+ var MailingRetryFailedRequest = z7.object({
923
1046
  /**
924
1047
  * Also requeue recipients whose outcome is unknown after a crash. They may
925
1048
  * already have received the message, so this is a human's decision, never a
926
1049
  * default.
927
1050
  */
928
- include_outcome_unknown: z6.boolean().optional()
1051
+ include_outcome_unknown: z7.boolean().optional()
929
1052
  }).strict();
930
- var MailingActionRequest = z6.object({}).strict();
931
- var MailingTestRequest = z6.object({
1053
+ var MailingActionRequest = z7.object({}).strict();
1054
+ var MailingTestRequest = z7.object({
932
1055
  to: Email,
933
1056
  merge: Properties.optional(),
934
1057
  locale: LocaleTag.optional()
935
1058
  });
936
- var MailingTestResult = z6.object({
1059
+ var MailingTestResult = z7.object({
937
1060
  message_id: Id,
938
- provider_message_id: z6.string().nullable()
1061
+ provider_message_id: z7.string().nullable()
939
1062
  });
940
1063
  var RECIPIENT_STATUSES = ["queued", "sending", "sent", "failed", "skipped"];
941
- var RecipientStatus = z6.enum(RECIPIENT_STATUSES);
1064
+ var RecipientStatus = z7.enum(RECIPIENT_STATUSES);
942
1065
  var SKIP_REASONS = ["suppressed", "not_subscribed", "contact_erased", "cancelled", "outcome_unknown"];
943
- var SkipReason = z6.enum(SKIP_REASONS);
944
- var Recipient = z6.object({
1066
+ var SkipReason = z7.enum(SKIP_REASONS);
1067
+ var Recipient = z7.object({
945
1068
  id: Id,
946
1069
  mailing_id: Id,
947
1070
  contact_id: Id.nullable(),
@@ -949,55 +1072,55 @@ var Recipient = z6.object({
949
1072
  merge: Properties,
950
1073
  status: RecipientStatus,
951
1074
  skip_reason: SkipReason.nullable(),
952
- attempts: z6.number().int().min(0),
1075
+ attempts: z7.number().int().min(0),
953
1076
  message_id: Id.nullable(),
954
- last_error: z6.string().nullable(),
1077
+ last_error: z7.string().nullable(),
955
1078
  created_at: Timestamp,
956
1079
  updated_at: Timestamp
957
1080
  });
958
1081
  var MAX_RECIPIENTS_PER_BATCH = 1e3;
959
1082
  var MAX_LETTER_RECIPIENTS = 1;
960
1083
  var LETTER_RECIPIENT_REFUSAL = "letter_has_one_recipient";
961
- var RecipientInput = z6.object({
1084
+ var RecipientInput = z7.object({
962
1085
  contact_id: Id.optional(),
963
- external_id: z6.string().min(1).max(255).optional(),
1086
+ external_id: z7.string().min(1).max(255).optional(),
964
1087
  email: Email.optional(),
965
1088
  merge: Properties.optional()
966
1089
  }).refine((v) => v.contact_id !== void 0 || v.external_id !== void 0 || v.email !== void 0, {
967
1090
  message: "contact_id, external_id or email is required",
968
1091
  path: ["email"]
969
1092
  });
970
- var RecipientBatch = z6.object({
971
- recipients: z6.array(RecipientInput).min(1).max(MAX_RECIPIENTS_PER_BATCH)
1093
+ var RecipientBatch = z7.object({
1094
+ recipients: z7.array(RecipientInput).min(1).max(MAX_RECIPIENTS_PER_BATCH)
972
1095
  });
973
1096
  var RECIPIENT_REJECTIONS = ["unknown_contact", "duplicate_in_batch"];
974
- var RecipientBatchResult = z6.object({
1097
+ var RecipientBatchResult = z7.object({
975
1098
  /** Newly queued. */
976
- added: z6.number().int().min(0),
1099
+ added: z7.number().int().min(0),
977
1100
  /** Already on the mailing from an earlier batch: left unchanged. */
978
- already_present: z6.number().int().min(0),
1101
+ already_present: z7.number().int().min(0),
979
1102
  /** Items not added, by their index in the request. */
980
- rejected: z6.array(z6.object({ index: z6.number().int().min(0), reason: z6.enum(RECIPIENT_REJECTIONS) }))
1103
+ rejected: z7.array(z7.object({ index: z7.number().int().min(0), reason: z7.enum(RECIPIENT_REJECTIONS) }))
981
1104
  });
982
1105
  var RecipientListQuery = PageQuery.extend({
983
1106
  status: RecipientStatus.optional(),
984
1107
  skip_reason: SkipReason.optional()
985
1108
  });
986
1109
  var MESSAGE_OUTCOMES = ["sent", "failed"];
987
- var MessageOutcome = z6.enum(MESSAGE_OUTCOMES);
988
- var MessageSummary = z6.object({
1110
+ var MessageOutcome = z7.enum(MESSAGE_OUTCOMES);
1111
+ var MessageSummary = z7.object({
989
1112
  id: Id,
990
1113
  mailing_id: Id.nullable(),
991
1114
  recipient_id: Id.nullable(),
992
1115
  contact_id: Id.nullable(),
993
1116
  to: Email,
994
- subject: z6.string(),
1117
+ subject: z7.string(),
995
1118
  provider_id: Id,
996
- provider_message_id: z6.string().nullable(),
1119
+ provider_message_id: z7.string().nullable(),
997
1120
  outcome: MessageOutcome,
998
- error: z6.string().nullable(),
999
- is_test: z6.boolean(),
1000
- recipient_count: z6.number().int().min(1),
1121
+ error: z7.string().nullable(),
1122
+ is_test: z7.boolean(),
1123
+ recipient_count: z7.number().int().min(1),
1001
1124
  /** The language version the message was sent in; null for messages archived before languages existed. */
1002
1125
  locale: LocaleTag.nullable(),
1003
1126
  /**
@@ -1009,22 +1132,22 @@ var MessageSummary = z6.object({
1009
1132
  insertions: InsertionChoices.nullable(),
1010
1133
  created_at: Timestamp
1011
1134
  });
1012
- var Message = MessageSummary.extend({ html: z6.string() });
1013
- var MailingLanguageStatus = z6.enum(["main", "ready", "draft", "not_a_workspace_language"]);
1014
- var MailingLanguage = z6.object({
1135
+ var Message = MessageSummary.extend({ html: z7.string() });
1136
+ var MailingLanguageStatus = z7.enum(["main", "ready", "draft", "not_a_workspace_language"]);
1137
+ var MailingLanguage = z7.object({
1015
1138
  locale: LocaleTag,
1016
1139
  status: MailingLanguageStatus,
1017
1140
  /** Queued recipients who will get this version. */
1018
- planned: z6.number().int().min(0),
1141
+ planned: z7.number().int().min(0),
1019
1142
  /** Messages already sent in this language (tests excluded). */
1020
- sent: z6.number().int().min(0)
1143
+ sent: z7.number().int().min(0)
1021
1144
  });
1022
- var MailingLanguageReport = z6.object({
1145
+ var MailingLanguageReport = z7.object({
1023
1146
  main_locale: LocaleTag,
1024
1147
  send_locale: LocaleTag.nullable(),
1025
- languages: z6.array(MailingLanguage),
1026
- fallback: z6.array(z6.object({ wanted: z6.string(), planned: z6.number().int().min(1) })),
1027
- no_language: z6.number().int().min(0),
1148
+ languages: z7.array(MailingLanguage),
1149
+ fallback: z7.array(z7.object({ wanted: z7.string(), planned: z7.number().int().min(1) })),
1150
+ no_language: z7.number().int().min(0),
1028
1151
  /**
1029
1152
  * Values that no choice of an insertion takes, so the "otherwise" text goes
1030
1153
  * out (docs/plans/2026-09-25-translated-insertions.md, decision 3): per
@@ -1033,12 +1156,12 @@ var MailingLanguageReport = z6.object({
1033
1156
  * template's keys never produces one; a non-empty list means the client and
1034
1157
  * the template have drifted apart.
1035
1158
  */
1036
- insertion_misses: z6.array(
1037
- z6.object({
1038
- insertion: z6.string(),
1039
- value: z6.string(),
1040
- planned: z6.number().int().min(0),
1041
- sent: z6.number().int().min(0)
1159
+ insertion_misses: z7.array(
1160
+ z7.object({
1161
+ insertion: z7.string(),
1162
+ value: z7.string(),
1163
+ planned: z7.number().int().min(0),
1164
+ sent: z7.number().int().min(0)
1042
1165
  })
1043
1166
  )
1044
1167
  });
@@ -1048,26 +1171,26 @@ var MessageListQuery = PageQuery.extend({
1048
1171
  });
1049
1172
 
1050
1173
  // src/platform.ts
1051
- var Tag = z7.object({
1174
+ var Tag = z8.object({
1052
1175
  id: Id,
1053
1176
  slug: Slug,
1054
- name: z7.string().min(1).max(120),
1055
- contact_count: z7.number().int().min(0),
1177
+ name: z8.string().min(1).max(120),
1178
+ contact_count: z8.number().int().min(0),
1056
1179
  created_at: Timestamp
1057
1180
  });
1058
- var TagCreate = z7.object({ slug: Slug, name: z7.string().min(1).max(120) });
1059
- var TagAssignment = z7.object({
1060
- contact_ids: z7.array(Id).min(1).max(1e3)
1181
+ var TagCreate = z8.object({ slug: Slug, name: z8.string().min(1).max(120) });
1182
+ var TagAssignment = z8.object({
1183
+ contact_ids: z8.array(Id).min(1).max(1e3)
1061
1184
  });
1062
1185
  var CONTACT_PROPERTY_TYPES = ["string", "number", "boolean", "date"];
1063
- var ContactPropertyType = z7.enum(CONTACT_PROPERTY_TYPES);
1064
- var ContactPropertyKey = z7.string().regex(/^[A-Za-z0-9_.-]{1,64}$/, "letters, digits, dot, underscore and hyphen, 1 to 64");
1065
- var ContactPropertyDefinition = z7.object({
1186
+ var ContactPropertyType = z8.enum(CONTACT_PROPERTY_TYPES);
1187
+ var ContactPropertyKey = z8.string().regex(/^[A-Za-z0-9_.-]{1,64}$/, "letters, digits, dot, underscore and hyphen, 1 to 64");
1188
+ var ContactPropertyDefinition = z8.object({
1066
1189
  key: ContactPropertyKey,
1067
- label: z7.string().min(1).max(120),
1190
+ label: z8.string().min(1).max(120),
1068
1191
  type: ContactPropertyType
1069
1192
  });
1070
- var ContactPropertyParams = z7.object({ key: ContactPropertyKey });
1193
+ var ContactPropertyParams = z8.object({ key: ContactPropertyKey });
1071
1194
  var FILTER_OPERATORS = [
1072
1195
  "eq",
1073
1196
  "neq",
@@ -1083,8 +1206,8 @@ var FILTER_OPERATORS = [
1083
1206
  "in",
1084
1207
  "not_in"
1085
1208
  ];
1086
- var FilterOperator = z7.enum(FILTER_OPERATORS);
1087
- var FilterField = z7.string().regex(
1209
+ var FilterOperator = z8.enum(FILTER_OPERATORS);
1210
+ var FilterField = z8.string().regex(
1088
1211
  /^(email|first_name|last_name|locale|created_at|tag|topic|engagement:(opened|clicked)|property:[A-Za-z0-9_.-]{1,64})$/,
1089
1212
  "unknown filter field"
1090
1213
  );
@@ -1100,18 +1223,18 @@ var FILTER_FIELD_OPERATORS = {
1100
1223
  property: FILTER_OPERATORS
1101
1224
  };
1102
1225
  var MAX_FILTER_DEPTH = 5;
1103
- var FilterCondition = z7.object({ field: FilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1226
+ var FilterCondition = z8.object({ field: FilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1104
1227
  message: "exists and not_exists take no value; every other operator needs one",
1105
1228
  path: ["value"]
1106
1229
  }).refine((c) => c.op !== "in" && c.op !== "not_in" || Array.isArray(c.value), {
1107
1230
  message: "in and not_in take an array",
1108
1231
  path: ["value"]
1109
1232
  });
1110
- var SegmentFilter = z7.lazy(
1111
- () => z7.union([
1112
- z7.object({ and: z7.array(SegmentFilter).min(1).max(50) }).strict(),
1113
- z7.object({ or: z7.array(SegmentFilter).min(1).max(50) }).strict(),
1114
- z7.object({ not: SegmentFilter }).strict(),
1233
+ var SegmentFilter = z8.lazy(
1234
+ () => z8.union([
1235
+ z8.object({ and: z8.array(SegmentFilter).min(1).max(50) }).strict(),
1236
+ z8.object({ or: z8.array(SegmentFilter).min(1).max(50) }).strict(),
1237
+ z8.object({ not: SegmentFilter }).strict(),
1115
1238
  FilterCondition
1116
1239
  ])
1117
1240
  );
@@ -1199,42 +1322,42 @@ function untypedValueProblem(c, every) {
1199
1322
  if (orderOp) return every(isFilterNumber, "numbers (define the property to compare dates)");
1200
1323
  return every((v) => isScalar(v) || v === null, "strings, numbers, booleans or null");
1201
1324
  }
1202
- var Segment = z7.object({
1325
+ var Segment = z8.object({
1203
1326
  id: Id,
1204
- name: z7.string().min(1).max(120),
1327
+ name: z8.string().min(1).max(120),
1205
1328
  filter: SegmentFilter,
1206
1329
  /** Computed on read. */
1207
- contact_count: z7.number().int().min(0),
1330
+ contact_count: z8.number().int().min(0),
1208
1331
  created_at: Timestamp,
1209
1332
  updated_at: Timestamp
1210
1333
  });
1211
- var SegmentCreate = z7.object({ name: z7.string().min(1).max(120), filter: BoundedSegmentFilter });
1212
- var SegmentPreviewRequest = z7.object({ filter: BoundedSegmentFilter });
1213
- var SegmentPreview = z7.object({
1214
- contact_count: z7.number().int().min(0),
1334
+ var SegmentCreate = z8.object({ name: z8.string().min(1).max(120), filter: BoundedSegmentFilter });
1335
+ var SegmentPreviewRequest = z8.object({ filter: BoundedSegmentFilter });
1336
+ var SegmentPreview = z8.object({
1337
+ contact_count: z8.number().int().min(0),
1215
1338
  /** Up to five matching contacts, for a human to sanity-check the filter. */
1216
- sample: z7.array(z7.object({ id: Id, email: Email })).max(5)
1339
+ sample: z8.array(z8.object({ id: Id, email: Email })).max(5)
1217
1340
  });
1218
- var MailingAudienceFromSegment = z7.object({ segment_id: Id });
1341
+ var MailingAudienceFromSegment = z8.object({ segment_id: Id });
1219
1342
  var SIGNUP_FORM_FIELDS = ["first_name", "last_name"];
1220
1343
  var HOSTED_PAGE_LOCALES = ["en", "de", "it", "fr", "es"];
1221
- var SignupFormTranslation = z7.object({
1222
- title: z7.string().min(1).max(120),
1223
- consent_text: z7.string().min(1).max(2e3)
1344
+ var SignupFormTranslation = z8.object({
1345
+ title: z8.string().min(1).max(120),
1346
+ consent_text: z8.string().min(1).max(2e3)
1224
1347
  });
1225
- var SignupForm = z7.object({
1348
+ var SignupForm = z8.object({
1226
1349
  id: Id,
1227
- name: z7.string().min(1).max(120),
1350
+ name: z8.string().min(1).max(120),
1228
1351
  /** The heading of the hosted page. */
1229
- title: z7.string().min(1).max(120),
1352
+ title: z8.string().min(1).max(120),
1230
1353
  /** What the person agrees to, shown above the button and recorded with the confirmation. */
1231
- consent_text: z7.string().min(1).max(2e3),
1232
- translations: z7.record(SignupFormTranslation),
1233
- topics: z7.array(Slug).min(1),
1234
- tags: z7.array(Slug),
1354
+ consent_text: z8.string().min(1).max(2e3),
1355
+ translations: z8.record(SignupFormTranslation),
1356
+ topics: z8.array(Slug).min(1),
1357
+ tags: z8.array(Slug),
1235
1358
  /** Fields shown besides email. */
1236
- fields: z7.array(z7.enum(SIGNUP_FORM_FIELDS)),
1237
- double_opt_in: z7.literal(true),
1359
+ fields: z8.array(z8.enum(SIGNUP_FORM_FIELDS)),
1360
+ double_opt_in: z8.literal(true),
1238
1361
  /** The provider the confirmation mail is sent through. */
1239
1362
  provider_id: Id,
1240
1363
  /**
@@ -1243,11 +1366,11 @@ var SignupForm = z7.object({
1243
1366
  */
1244
1367
  confirmation_template_id: Id.nullable(),
1245
1368
  /** Where the person lands after confirming. Null shows the hosted confirmation page. */
1246
- redirect_url: z7.string().url().nullable(),
1369
+ redirect_url: z8.string().url().nullable(),
1247
1370
  /** Origins allowed to embed the form and call the submission route from a browser. */
1248
- allowed_origins: z7.array(z7.string().url()).max(20),
1371
+ allowed_origins: z8.array(z8.string().url()).max(20),
1249
1372
  /** Bumped on every change; recorded with each confirmation. */
1250
- version: z7.number().int().min(1),
1373
+ version: z8.number().int().min(1),
1251
1374
  created_at: Timestamp,
1252
1375
  updated_at: Timestamp
1253
1376
  });
@@ -1262,56 +1385,56 @@ var SignupFormCreate = SignupForm.omit({
1262
1385
  tags: SignupForm.shape.tags.optional(),
1263
1386
  fields: SignupForm.shape.fields.optional(),
1264
1387
  confirmation_template_id: Id.nullable().optional(),
1265
- redirect_url: z7.string().url().nullable().optional(),
1388
+ redirect_url: z8.string().url().nullable().optional(),
1266
1389
  allowed_origins: SignupForm.shape.allowed_origins.optional()
1267
1390
  });
1268
- var SignupFormEmbed = z7.object({
1269
- hosted_url: z7.string().url(),
1391
+ var SignupFormEmbed = z8.object({
1392
+ hosted_url: z8.string().url(),
1270
1393
  /** A plain HTML form posting to the hosted page; works without JavaScript. */
1271
- html: z7.string(),
1394
+ html: z8.string(),
1272
1395
  /** A small optional script that adds the time check and submits in place. */
1273
- script_url: z7.string().url(),
1396
+ script_url: z8.string().url(),
1274
1397
  /** Where a browser fetches a fresh `form_token` from (GET, public, CORS for `allowed_origins`). */
1275
- token_url: z7.string().url()
1398
+ token_url: z8.string().url()
1276
1399
  });
1277
- var SignupSubmission = z7.object({
1400
+ var SignupSubmission = z8.object({
1278
1401
  email: Email,
1279
- first_name: z7.string().max(200).optional(),
1280
- last_name: z7.string().max(200).optional(),
1281
- locale: z7.string().min(2).max(35).optional(),
1402
+ first_name: z8.string().max(200).optional(),
1403
+ last_name: z8.string().max(200).optional(),
1404
+ locale: z8.string().min(2).max(35).optional(),
1282
1405
  /** Honeypot: must be empty. */
1283
- website: z7.string().max(0).optional(),
1406
+ website: z8.string().max(0).optional(),
1284
1407
  /**
1285
1408
  * The signed render time from the form's token URL: a submission sooner than a
1286
1409
  * human could fill the form, or long after, is refused.
1287
1410
  */
1288
- form_token: z7.string().min(1).max(512)
1411
+ form_token: z8.string().min(1).max(512)
1289
1412
  });
1290
1413
  var IMPORT_STATUSES = ["uploaded", "validating", "validated", "committing", "completed", "failed", "cancelled"];
1291
- var ImportStatus = z7.enum(IMPORT_STATUSES);
1414
+ var ImportStatus = z8.enum(IMPORT_STATUSES);
1292
1415
  var IMPORT_TERMINAL_STATUSES = ["completed", "failed", "cancelled"];
1293
- var ImportColumnMapping = z7.record(
1294
- z7.string().regex(/^(email|external_id|first_name|last_name|locale|property:[A-Za-z0-9_.-]{1,64}|ignore)$/)
1416
+ var ImportColumnMapping = z8.record(
1417
+ z8.string().regex(/^(email|external_id|first_name|last_name|locale|property:[A-Za-z0-9_.-]{1,64}|ignore)$/)
1295
1418
  );
1296
1419
  var IMPORT_FILE_FIELD = "file";
1297
1420
  var MAX_IMPORT_BYTES = 50 * 1024 * 1024;
1298
1421
  var MAX_IMPORT_ROWS = 2e5;
1299
- var ImportMappingRequest = z7.object({
1422
+ var ImportMappingRequest = z8.object({
1300
1423
  /** CSV header -> contact field. Exactly one column maps to `email`. */
1301
1424
  mapping: ImportColumnMapping.refine(
1302
1425
  (m) => Object.values(m).filter((v) => v === "email").length === 1,
1303
1426
  "exactly one column maps to email"
1304
1427
  ),
1305
- topics: z7.array(Slug).max(100),
1306
- tags: z7.array(Slug).max(100),
1428
+ topics: z8.array(Slug).max(100),
1429
+ tags: z8.array(Slug).max(100),
1307
1430
  /** Existing contacts get the mapped fields overwritten; false only adds topics, tags and missing fields. */
1308
- update_existing: z7.boolean().optional(),
1431
+ update_existing: z8.boolean().optional(),
1309
1432
  /** The importer states the people consented; the service records who said so and when. */
1310
- consent_confirmed: z7.literal(true)
1433
+ consent_confirmed: z8.literal(true)
1311
1434
  });
1312
- var ImportCommitRequest = z7.object({ mapping_version: z7.number().int().min(1) });
1435
+ var ImportCommitRequest = z8.object({ mapping_version: z8.number().int().min(1) });
1313
1436
  var IMPORT_ROW_OUTCOMES = ["created", "updated", "unchanged", "suppressed", "skipped"];
1314
- var ImportRowOutcome = z7.enum(IMPORT_ROW_OUTCOMES);
1437
+ var ImportRowOutcome = z8.enum(IMPORT_ROW_OUTCOMES);
1315
1438
  var IMPORT_SKIP_REASONS = [
1316
1439
  "missing_email",
1317
1440
  "invalid_email",
@@ -1320,90 +1443,90 @@ var IMPORT_SKIP_REASONS = [
1320
1443
  "external_id_conflict",
1321
1444
  "wrong_column_count"
1322
1445
  ];
1323
- var ImportSkipReason = z7.enum(IMPORT_SKIP_REASONS);
1324
- var ImportReport = z7.object({
1325
- created: z7.number().int().min(0),
1326
- updated: z7.number().int().min(0),
1327
- unchanged: z7.number().int().min(0),
1328
- suppressed: z7.number().int().min(0),
1329
- skipped: z7.number().int().min(0),
1330
- skipped_by_reason: z7.record(ImportSkipReason, z7.number().int().min(0)),
1446
+ var ImportSkipReason = z8.enum(IMPORT_SKIP_REASONS);
1447
+ var ImportReport = z8.object({
1448
+ created: z8.number().int().min(0),
1449
+ updated: z8.number().int().min(0),
1450
+ unchanged: z8.number().int().min(0),
1451
+ suppressed: z8.number().int().min(0),
1452
+ skipped: z8.number().int().min(0),
1453
+ skipped_by_reason: z8.record(ImportSkipReason, z8.number().int().min(0)),
1331
1454
  /** Rows whose contact was subscribed without some topic, because the address is blocked for it. */
1332
- topics_withheld: z7.number().int().min(0)
1455
+ topics_withheld: z8.number().int().min(0)
1333
1456
  });
1334
- var ImportJob = z7.object({
1457
+ var ImportJob = z8.object({
1335
1458
  id: Id,
1336
1459
  status: ImportStatus,
1337
- file_name: z7.string().max(255).nullable(),
1338
- file_bytes: z7.number().int().min(0),
1339
- total_rows: z7.number().int().min(0),
1460
+ file_name: z8.string().max(255).nullable(),
1461
+ file_bytes: z8.number().int().min(0),
1462
+ total_rows: z8.number().int().min(0),
1340
1463
  /** The header row, as in the file. */
1341
- columns: z7.array(z7.string()),
1464
+ columns: z8.array(z8.string()),
1342
1465
  /** The first rows, for the mapping screen. */
1343
- sample: z7.array(z7.array(z7.string())).max(5),
1466
+ sample: z8.array(z8.array(z8.string())).max(5),
1344
1467
  /** A mapping guessed from the headers, for the mapping screen to start from. */
1345
1468
  suggested_mapping: ImportColumnMapping,
1346
1469
  mapping: ImportColumnMapping.nullable(),
1347
- mapping_version: z7.number().int().min(0),
1348
- topics: z7.array(Slug),
1349
- tags: z7.array(Slug),
1350
- update_existing: z7.boolean(),
1470
+ mapping_version: z8.number().int().min(0),
1471
+ topics: z8.array(Slug),
1472
+ tags: z8.array(Slug),
1473
+ update_existing: z8.boolean(),
1351
1474
  /** The dry run of the current mapping; null before one finished. */
1352
1475
  dry_run: ImportReport.nullable(),
1353
1476
  /** What the commit has written so far; null before it started. */
1354
1477
  result: ImportReport.nullable(),
1355
1478
  /** Rows the current phase (dry run or commit) has processed. */
1356
- processed_rows: z7.number().int().min(0),
1479
+ processed_rows: z8.number().int().min(0),
1357
1480
  /** Why a `failed` import failed. */
1358
- error: z7.string().nullable(),
1481
+ error: z8.string().nullable(),
1359
1482
  created_at: Timestamp,
1360
1483
  updated_at: Timestamp,
1361
1484
  finished_at: Timestamp.nullable()
1362
1485
  });
1363
- var ImportRow = z7.object({
1486
+ var ImportRow = z8.object({
1364
1487
  /** The line in the file, 1 being the first line after the header. */
1365
- row: z7.number().int().min(1),
1366
- email: z7.string().nullable(),
1488
+ row: z8.number().int().min(1),
1489
+ email: z8.string().nullable(),
1367
1490
  outcome: ImportRowOutcome,
1368
1491
  reason: ImportSkipReason.nullable(),
1369
1492
  /** A human explanation for a skipped row (which value, which column). */
1370
- message: z7.string().nullable(),
1493
+ message: z8.string().nullable(),
1371
1494
  contact_id: Id.nullable()
1372
1495
  });
1373
1496
  var ImportRowListQuery = PageQuery.extend({ outcome: ImportRowOutcome.optional() });
1374
- var MailingScheduleRequest = z7.object({ send_at: Timestamp });
1375
- var TrackingSettings = z7.object({ opens: z7.boolean(), clicks: z7.boolean() });
1376
- var VariantAnalytics = z7.object({
1377
- key: z7.string(),
1378
- sent: z7.number().int().min(0),
1379
- unique_opens: z7.number().int().min(0).nullable(),
1380
- unique_clicks: z7.number().int().min(0).nullable()
1381
- });
1382
- var MailingAnalytics = z7.object({
1497
+ var MailingScheduleRequest = z8.object({ send_at: Timestamp });
1498
+ var TrackingSettings = z8.object({ opens: z8.boolean(), clicks: z8.boolean() });
1499
+ var VariantAnalytics = z8.object({
1500
+ key: z8.string(),
1501
+ sent: z8.number().int().min(0),
1502
+ unique_opens: z8.number().int().min(0).nullable(),
1503
+ unique_clicks: z8.number().int().min(0).nullable()
1504
+ });
1505
+ var MailingAnalytics = z8.object({
1383
1506
  mailing_id: Id,
1384
1507
  counts: MailingCounts,
1385
1508
  /** What was tracked for this mailing, fixed when it started; null before it started. */
1386
1509
  tracking: TrackingSettings.nullable(),
1387
1510
  /** Unique recipients with a human open. Null when opens were not tracked. */
1388
- unique_opens: z7.number().int().min(0).nullable(),
1511
+ unique_opens: z8.number().int().min(0).nullable(),
1389
1512
  /**
1390
1513
  * Recipients whose only opens came from Apple Mail Privacy Protection, which
1391
1514
  * loads every image on delivery: counted apart, never as human opens.
1392
1515
  */
1393
- apple_mpp_opens: z7.number().int().min(0).nullable(),
1516
+ apple_mpp_opens: z8.number().int().min(0).nullable(),
1394
1517
  /** Opens and clicks from security scanners and prefetchers, filtered out of the unique counts. */
1395
- machine_events: z7.number().int().min(0).nullable(),
1396
- unique_clicks: z7.number().int().min(0).nullable(),
1397
- unsubscribes: z7.number().int().min(0),
1398
- bounces: z7.number().int().min(0),
1399
- complaints: z7.number().int().min(0),
1400
- links: z7.array(z7.object({ url: z7.string(), unique_clicks: z7.number().int().min(0) })).nullable(),
1401
- variants: z7.array(VariantAnalytics).nullable()
1518
+ machine_events: z8.number().int().min(0).nullable(),
1519
+ unique_clicks: z8.number().int().min(0).nullable(),
1520
+ unsubscribes: z8.number().int().min(0),
1521
+ bounces: z8.number().int().min(0),
1522
+ complaints: z8.number().int().min(0),
1523
+ links: z8.array(z8.object({ url: z8.string(), unique_clicks: z8.number().int().min(0) })).nullable(),
1524
+ variants: z8.array(VariantAnalytics).nullable()
1402
1525
  });
1403
1526
 
1404
1527
  // src/automations.ts
1405
1528
  var AUTOMATION_FILTER_FIELD_PATTERN = /^(email|first_name|last_name|locale|created_at|tag|topic|segment|engagement:(opened|clicked)|step:(opened|clicked)|property:[A-Za-z0-9_.-]{1,64}|event:[A-Za-z0-9_.-]{1,64})$/;
1406
- var AutomationFilterField = z8.string().regex(AUTOMATION_FILTER_FIELD_PATTERN, "unknown filter field");
1529
+ var AutomationFilterField = z9.string().regex(AUTOMATION_FILTER_FIELD_PATTERN, "unknown filter field");
1407
1530
  var AUTOMATION_FILTER_FIELD_OPERATORS = {
1408
1531
  ...FILTER_FIELD_OPERATORS,
1409
1532
  segment: ["eq", "neq", "in", "not_in"],
@@ -1413,18 +1536,18 @@ var AUTOMATION_FILTER_FIELD_OPERATORS = {
1413
1536
  step: ["eq", "neq"]
1414
1537
  };
1415
1538
  var automationFilterFamily = filterFieldFamily;
1416
- var AutomationFilterCondition = z8.object({ field: AutomationFilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1539
+ var AutomationFilterCondition = z9.object({ field: AutomationFilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1417
1540
  message: "exists and not_exists take no value; every other operator needs one",
1418
1541
  path: ["value"]
1419
1542
  }).refine((c) => c.op !== "in" && c.op !== "not_in" || Array.isArray(c.value), {
1420
1543
  message: "in and not_in take an array",
1421
1544
  path: ["value"]
1422
1545
  });
1423
- var AutomationFilter = z8.lazy(
1424
- () => z8.union([
1425
- z8.object({ and: z8.array(AutomationFilter).min(1).max(50) }).strict(),
1426
- z8.object({ or: z8.array(AutomationFilter).min(1).max(50) }).strict(),
1427
- z8.object({ not: AutomationFilter }).strict(),
1546
+ var AutomationFilter = z9.lazy(
1547
+ () => z9.union([
1548
+ z9.object({ and: z9.array(AutomationFilter).min(1).max(50) }).strict(),
1549
+ z9.object({ or: z9.array(AutomationFilter).min(1).max(50) }).strict(),
1550
+ z9.object({ not: AutomationFilter }).strict(),
1428
1551
  AutomationFilterCondition
1429
1552
  ])
1430
1553
  );
@@ -1437,20 +1560,20 @@ function filterConditions(filter) {
1437
1560
  if ("not" in filter) return filterConditions(filter.not);
1438
1561
  return [filter];
1439
1562
  }
1440
- var StepId = z8.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "letters, digits, underscore and hyphen, 1 to 64");
1441
- var TimeOfDay = z8.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "HH:MM in 24 hours");
1442
- var Weekday = z8.number().int().min(0).max(6);
1443
- var TimezoneName = z8.string().min(1).max(64).regex(/^(UTC|[A-Za-z][A-Za-z0-9_+-]*(?:\/[A-Za-z0-9_+-]+)+)$/, "an IANA time zone name such as Europe/Berlin");
1563
+ var StepId = z9.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "letters, digits, underscore and hyphen, 1 to 64");
1564
+ var TimeOfDay = z9.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "HH:MM in 24 hours");
1565
+ var Weekday = z9.number().int().min(0).max(6);
1566
+ var TimezoneName = z9.string().min(1).max(64).regex(/^(UTC|[A-Za-z][A-Za-z0-9_+-]*(?:\/[A-Za-z0-9_+-]+)+)$/, "an IANA time zone name such as Europe/Berlin");
1444
1567
  var MAX_DELAY_SECONDS = 365 * 24 * 60 * 60;
1445
- var DateOnly = z8.string().regex(/^\d{4}-\d{2}-\d{2}$/, "a calendar date such as 2026-09-20").refine((v) => {
1568
+ var DateOnly = z9.string().regex(/^\d{4}-\d{2}-\d{2}$/, "a calendar date such as 2026-09-20").refine((v) => {
1446
1569
  const [y, m, d] = v.split("-").map(Number);
1447
1570
  const t = new Date(Date.UTC(y, m - 1, d));
1448
1571
  return t.getUTCFullYear() === y && t.getUTCMonth() + 1 === m && t.getUTCDate() === d;
1449
1572
  }, "a real calendar date");
1450
- var OffsetDays = z8.number().int().min(-365).max(365);
1573
+ var OffsetDays = z9.number().int().min(-365).max(365);
1451
1574
  var DATE_PASSED_ANSWERS = ["skip", "stop", "continue"];
1452
- var DatePassedAnswer = z8.enum(DATE_PASSED_ANSWERS);
1453
- var EventName = z8.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,79}$/, "letters, digits, dot, colon, underscore and hyphen, 1 to 80");
1575
+ var DatePassedAnswer = z9.enum(DATE_PASSED_ANSWERS);
1576
+ var EventName = z9.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,79}$/, "letters, digits, dot, colon, underscore and hyphen, 1 to 80");
1454
1577
  var AUTOMATION_TRIGGER_KINDS = [
1455
1578
  "topic_subscribed",
1456
1579
  "form_confirmed",
@@ -1463,17 +1586,17 @@ var AUTOMATION_TRIGGER_KINDS = [
1463
1586
  "segment_entered",
1464
1587
  "link_clicked"
1465
1588
  ];
1466
- var AutomationTriggerKind = z8.enum(AUTOMATION_TRIGGER_KINDS);
1589
+ var AutomationTriggerKind = z9.enum(AUTOMATION_TRIGGER_KINDS);
1467
1590
  var exclude = { exclude: BoundedAutomationFilter.nullish() };
1468
- var AutomationTrigger = z8.discriminatedUnion("kind", [
1469
- z8.object({ kind: z8.literal("topic_subscribed"), topic: Slug, ...exclude }).strict(),
1470
- z8.object({ kind: z8.literal("form_confirmed"), form_id: Id, ...exclude }).strict(),
1471
- z8.object({ kind: z8.literal("tag_added"), tag: Slug, ...exclude }).strict(),
1591
+ var AutomationTrigger = z9.discriminatedUnion("kind", [
1592
+ z9.object({ kind: z9.literal("topic_subscribed"), topic: Slug, ...exclude }).strict(),
1593
+ z9.object({ kind: z9.literal("form_confirmed"), form_id: Id, ...exclude }).strict(),
1594
+ z9.object({ kind: z9.literal("tag_added"), tag: Slug, ...exclude }).strict(),
1472
1595
  /** `to` given: only a change that lands on this value fires. Absent: any change of the key. */
1473
- z8.object({ kind: z8.literal("property_changed"), key: ContactPropertyKey, to: JsonValue.optional(), ...exclude }).strict(),
1596
+ z9.object({ kind: z9.literal("property_changed"), key: ContactPropertyKey, to: JsonValue.optional(), ...exclude }).strict(),
1474
1597
  /** `where` filters the event's own data, so only `event:<key>` leaves belong in it. */
1475
- z8.object({ kind: z8.literal("event"), name: EventName, where: BoundedAutomationFilter.nullish(), ...exclude }).strict(),
1476
- z8.object({ kind: z8.literal("manual"), ...exclude }).strict(),
1598
+ z9.object({ kind: z9.literal("event"), name: EventName, where: BoundedAutomationFilter.nullish(), ...exclude }).strict(),
1599
+ z9.object({ kind: z9.literal("manual"), ...exclude }).strict(),
1477
1600
  /**
1478
1601
  * Every year on a date the contact carries: a birthday, a joining date, a
1479
1602
  * renewal. `offset_days` moves it ("three days before"), `at` is the wall
@@ -1483,8 +1606,8 @@ var AutomationTrigger = z8.discriminatedUnion("kind", [
1483
1606
  * A 29 February date fires on 1 March in a year that has no 29 February, so
1484
1607
  * nobody is skipped every fourth year.
1485
1608
  */
1486
- z8.object({
1487
- kind: z8.literal("date_anniversary"),
1609
+ z9.object({
1610
+ kind: z9.literal("date_anniversary"),
1488
1611
  key: ContactPropertyKey,
1489
1612
  offset_days: OffsetDays,
1490
1613
  at: TimeOfDay,
@@ -1496,8 +1619,8 @@ var AutomationTrigger = z8.discriminatedUnion("kind", [
1496
1619
  * not ask about a segment or about an event's data: there is no event, and a
1497
1620
  * segment is its own trigger kind.
1498
1621
  */
1499
- z8.object({
1500
- kind: z8.literal("exact_date"),
1622
+ z9.object({
1623
+ kind: z9.literal("exact_date"),
1501
1624
  on: DateOnly,
1502
1625
  at: TimeOfDay,
1503
1626
  where: BoundedAutomationFilter.nullish(),
@@ -1516,7 +1639,7 @@ var AutomationTrigger = z8.discriminatedUnion("kind", [
1516
1639
  * already exists. Entering those people as well is the publish dialog's
1517
1640
  * backfill question, answered by a person rather than by the sweep.
1518
1641
  */
1519
- z8.object({ kind: z8.literal("segment_entered"), segment_id: Id, ...exclude }).strict(),
1642
+ z9.object({ kind: z9.literal("segment_entered"), segment_id: Id, ...exclude }).strict(),
1520
1643
  /**
1521
1644
  * S4. When somebody clicks a link in a mailing that has already gone out.
1522
1645
  *
@@ -1526,7 +1649,7 @@ var AutomationTrigger = z8.discriminatedUnion("kind", [
1526
1649
  * tracking off there is no click to hear about, so the validator refuses it
1527
1650
  * rather than leaving an automation that can never fire.
1528
1651
  */
1529
- z8.object({ kind: z8.literal("link_clicked"), mailing_id: Id, url: z8.string().min(1).max(2048).optional(), ...exclude }).strict()
1652
+ z9.object({ kind: z9.literal("link_clicked"), mailing_id: Id, url: z9.string().min(1).max(2048).optional(), ...exclude }).strict()
1530
1653
  ]);
1531
1654
  var AUTOMATION_DATE_TRIGGER_KINDS = ["date_anniversary", "exact_date"];
1532
1655
  var MAX_TRIGGERS = 10;
@@ -1545,45 +1668,45 @@ var AUTOMATION_STEP_KINDS = [
1545
1668
  "webhook",
1546
1669
  "notify"
1547
1670
  ];
1548
- var AutomationStepKind = z8.enum(AUTOMATION_STEP_KINDS);
1671
+ var AutomationStepKind = z9.enum(AUTOMATION_STEP_KINDS);
1549
1672
  var next = { next: StepId.nullable() };
1550
- var Unchosen = z8.literal("");
1551
- var DraftSlug = z8.union([Slug, Unchosen]);
1552
- var DraftPropertyKey = z8.union([ContactPropertyKey, Unchosen]);
1553
- var label = { label: z8.string().max(120).nullish() };
1554
- var EmailStepLanguage = z8.object({
1555
- subject: z8.string().min(1).max(998),
1556
- preheader: z8.string().max(500).nullable(),
1673
+ var Unchosen = z9.literal("");
1674
+ var DraftSlug = z9.union([Slug, Unchosen]);
1675
+ var DraftPropertyKey = z9.union([ContactPropertyKey, Unchosen]);
1676
+ var label2 = { label: z9.string().max(120).nullish() };
1677
+ var EmailStepLanguage = z9.object({
1678
+ subject: z9.string().min(1).max(998),
1679
+ preheader: z9.string().max(500).nullable(),
1557
1680
  document: TemplateDocument,
1558
1681
  /** This language's insertions, its texts over the template's structure (every text present). */
1559
1682
  insertions: Insertions.nullish()
1560
1683
  }).strict();
1561
- var EmailStep = z8.object({
1562
- kind: z8.literal("email"),
1563
- ...label,
1684
+ var EmailStep = z9.object({
1685
+ kind: z9.literal("email"),
1686
+ ...label2,
1564
1687
  ...next,
1565
1688
  template_id: Id.nullish(),
1566
1689
  document: TemplateDocument.nullish(),
1567
1690
  /** Empty while the step is being written, or when its template has a subject; else `not_chosen` refuses to publish it. */
1568
- subject: z8.string().max(998),
1569
- preheader: z8.string().max(500).nullish(),
1691
+ subject: z9.string().max(998),
1692
+ preheader: z9.string().max(500).nullish(),
1570
1693
  locale: LocaleTag.nullish(),
1571
- languages: z8.record(LocaleTag, EmailStepLanguage).nullish(),
1694
+ languages: z9.record(LocaleTag, EmailStepLanguage).nullish(),
1572
1695
  /** The main language's insertions, snapshot from the template when the automation is published. */
1573
1696
  insertions: Insertions.nullish()
1574
1697
  }).strict();
1575
- var DelayStep = z8.object({
1576
- kind: z8.literal("delay"),
1577
- ...label,
1698
+ var DelayStep = z9.object({
1699
+ kind: z9.literal("delay"),
1700
+ ...label2,
1578
1701
  ...next,
1579
- wait: z8.discriminatedUnion("mode", [
1580
- z8.object({ mode: z8.literal("duration"), seconds: z8.number().int().min(1).max(MAX_DELAY_SECONDS) }).strict(),
1581
- z8.object({ mode: z8.literal("time_of_day"), at: TimeOfDay }).strict(),
1582
- z8.object({ mode: z8.literal("weekday"), weekday: Weekday, at: TimeOfDay }).strict(),
1702
+ wait: z9.discriminatedUnion("mode", [
1703
+ z9.object({ mode: z9.literal("duration"), seconds: z9.number().int().min(1).max(MAX_DELAY_SECONDS) }).strict(),
1704
+ z9.object({ mode: z9.literal("time_of_day"), at: TimeOfDay }).strict(),
1705
+ z9.object({ mode: z9.literal("weekday"), weekday: Weekday, at: TimeOfDay }).strict(),
1583
1706
  /** A fixed day has no next occurrence, so `continue` is not one of its answers. */
1584
- z8.object({ mode: z8.literal("date"), on: DateOnly, at: TimeOfDay, passed: z8.enum(["skip", "stop"]) }).strict(),
1585
- z8.object({
1586
- mode: z8.literal("date_property"),
1707
+ z9.object({ mode: z9.literal("date"), on: DateOnly, at: TimeOfDay, passed: z9.enum(["skip", "stop"]) }).strict(),
1708
+ z9.object({
1709
+ mode: z9.literal("date_property"),
1587
1710
  key: ContactPropertyKey,
1588
1711
  offset_days: OffsetDays,
1589
1712
  at: TimeOfDay,
@@ -1591,9 +1714,9 @@ var DelayStep = z8.object({
1591
1714
  }).strict()
1592
1715
  ])
1593
1716
  }).strict();
1594
- var ConditionStep = z8.object({
1595
- kind: z8.literal("condition"),
1596
- ...label,
1717
+ var ConditionStep = z9.object({
1718
+ kind: z9.literal("condition"),
1719
+ ...label2,
1597
1720
  filter: BoundedAutomationFilter,
1598
1721
  yes: StepId.nullable(),
1599
1722
  no: StepId.nullable(),
@@ -1603,49 +1726,49 @@ var ConditionStep = z8.object({
1603
1726
  * neither half means anything without the other: a window with no answer
1604
1727
  * for the end of it would be a silent decision.
1605
1728
  */
1606
- wait_for: z8.object({ up_to_s: z8.number().int().min(1).max(MAX_DELAY_SECONDS), on_timeout: z8.enum(["yes", "no"]) }).strict().nullish()
1729
+ wait_for: z9.object({ up_to_s: z9.number().int().min(1).max(MAX_DELAY_SECONDS), on_timeout: z9.enum(["yes", "no"]) }).strict().nullish()
1607
1730
  }).strict();
1608
- var SplitBranchKey = z8.string().regex(/^[A-Za-z0-9_-]{1,32}$/, "letters, digits, underscore and hyphen, 1 to 32");
1731
+ var SplitBranchKey = z9.string().regex(/^[A-Za-z0-9_-]{1,32}$/, "letters, digits, underscore and hyphen, 1 to 32");
1609
1732
  var MIN_SPLIT_BRANCHES = 2;
1610
1733
  var MAX_SPLIT_BRANCHES = 4;
1611
- var SplitStep = z8.object({
1612
- kind: z8.literal("split"),
1613
- ...label,
1614
- branches: z8.array(
1615
- z8.object({
1734
+ var SplitStep = z9.object({
1735
+ kind: z9.literal("split"),
1736
+ ...label2,
1737
+ branches: z9.array(
1738
+ z9.object({
1616
1739
  key: SplitBranchKey,
1617
1740
  /** A whole percentage. Zero is allowed: a branch kept in the flow but switched off. */
1618
- weight: z8.number().int().min(0).max(100),
1741
+ weight: z9.number().int().min(0).max(100),
1619
1742
  next: StepId.nullable()
1620
1743
  }).strict()
1621
1744
  ).min(MIN_SPLIT_BRANCHES).max(MAX_SPLIT_BRANCHES).refine((bs) => new Set(bs.map((b) => b.key)).size === bs.length, "each branch needs its own key").refine((bs) => bs.reduce((sum, b) => sum + b.weight, 0) === 100, "the weights have to come to 100")
1622
1745
  }).strict();
1623
- var GotoStep = z8.object({ kind: z8.literal("goto"), ...label, target: StepId.nullable() }).strict();
1746
+ var GotoStep = z9.object({ kind: z9.literal("goto"), ...label2, target: StepId.nullable() }).strict();
1624
1747
  var MAX_STEP_VISITS = 20;
1625
- var WebhookStep = z8.object({ kind: z8.literal("webhook"), ...label, ...next, endpoint_id: Id.nullable(), payload: JsonValue.nullish() }).strict();
1626
- var NotifyRecipients = z8.union([z8.literal("owner"), z8.literal("admins"), z8.object({ member_id: Id }).strict()]);
1627
- var NotifyStep = z8.object({
1628
- kind: z8.literal("notify"),
1629
- ...label,
1748
+ var WebhookStep = z9.object({ kind: z9.literal("webhook"), ...label2, ...next, endpoint_id: Id.nullable(), payload: JsonValue.nullish() }).strict();
1749
+ var NotifyRecipients = z9.union([z9.literal("owner"), z9.literal("admins"), z9.object({ member_id: Id }).strict()]);
1750
+ var NotifyStep = z9.object({
1751
+ kind: z9.literal("notify"),
1752
+ ...label2,
1630
1753
  ...next,
1631
1754
  to: NotifyRecipients,
1632
1755
  /** Empty while the step is being written; `not_chosen` refuses to publish it. */
1633
- subject: z8.string().max(998),
1634
- body: z8.string().max(1e4)
1756
+ subject: z9.string().max(998),
1757
+ body: z9.string().max(1e4)
1635
1758
  }).strict();
1636
- var AutomationStep = z8.discriminatedUnion("kind", [
1759
+ var AutomationStep = z9.discriminatedUnion("kind", [
1637
1760
  EmailStep,
1638
1761
  DelayStep,
1639
1762
  ConditionStep,
1640
- z8.object({ kind: z8.literal("add_tag"), ...label, ...next, tag: DraftSlug }).strict(),
1641
- z8.object({ kind: z8.literal("remove_tag"), ...label, ...next, tag: DraftSlug }).strict(),
1763
+ z9.object({ kind: z9.literal("add_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
1764
+ z9.object({ kind: z9.literal("remove_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
1642
1765
  /** `value` null clears the property, as a contact upsert does. */
1643
- z8.object({ kind: z8.literal("set_property"), ...label, ...next, key: DraftPropertyKey, value: JsonValue }).strict(),
1766
+ z9.object({ kind: z9.literal("set_property"), ...label2, ...next, key: DraftPropertyKey, value: JsonValue }).strict(),
1644
1767
  /** Subscribing never lifts a suppression: the service checks that, not the flow. */
1645
- z8.object({ kind: z8.literal("subscribe_topic"), ...label, ...next, topic: DraftSlug }).strict(),
1768
+ z9.object({ kind: z9.literal("subscribe_topic"), ...label2, ...next, topic: DraftSlug }).strict(),
1646
1769
  /** `topic` unsubscribes from the automation's own topic, `all` from every topic. */
1647
- z8.object({ kind: z8.literal("unsubscribe"), ...label, ...next, scope: z8.enum(["topic", "all"]) }).strict(),
1648
- z8.object({ kind: z8.literal("exit"), ...label }).strict(),
1770
+ z9.object({ kind: z9.literal("unsubscribe"), ...label2, ...next, scope: z9.enum(["topic", "all"]) }).strict(),
1771
+ z9.object({ kind: z9.literal("exit"), ...label2 }).strict(),
1649
1772
  SplitStep,
1650
1773
  GotoStep,
1651
1774
  WebhookStep,
@@ -1669,25 +1792,25 @@ function stepTargets(step) {
1669
1792
  }
1670
1793
  }
1671
1794
  var MAX_STEPS = 200;
1672
- var AutomationFlow = z8.object({
1673
- triggers: z8.array(AutomationTrigger).max(MAX_TRIGGERS),
1795
+ var AutomationFlow = z9.object({
1796
+ triggers: z9.array(AutomationTrigger).max(MAX_TRIGGERS),
1674
1797
  /** The first step. `null` is an empty flow. */
1675
1798
  entry: StepId.nullable(),
1676
- steps: z8.record(StepId, AutomationStep)
1799
+ steps: z9.record(StepId, AutomationStep)
1677
1800
  }).strict();
1678
1801
  var emptyFlow = () => ({ triggers: [], entry: null, steps: {} });
1679
- var QuietHours = z8.object({
1802
+ var QuietHours = z9.object({
1680
1803
  start: TimeOfDay,
1681
1804
  end: TimeOfDay,
1682
- weekdays: z8.array(Weekday).min(1).max(7).nullish()
1805
+ weekdays: z9.array(Weekday).min(1).max(7).nullish()
1683
1806
  }).strict();
1684
1807
  var RE_ENTRY_MODES = ["off", "after_exit"];
1685
- var ReEntryMode = z8.enum(RE_ENTRY_MODES);
1808
+ var ReEntryMode = z9.enum(RE_ENTRY_MODES);
1686
1809
  var MAX_RE_ENTRY_COOLDOWN_SECONDS = 365 * 24 * 60 * 60;
1687
- var AutomationSettings = z8.object({
1810
+ var AutomationSettings = z9.object({
1688
1811
  re_entry: ReEntryMode,
1689
1812
  /** Seconds a person must wait after leaving before entering again. Only with `after_exit`. */
1690
- re_entry_cooldown_s: z8.number().int().min(0).max(MAX_RE_ENTRY_COOLDOWN_SECONDS).nullish(),
1813
+ re_entry_cooldown_s: z9.number().int().min(0).max(MAX_RE_ENTRY_COOLDOWN_SECONDS).nullish(),
1691
1814
  quiet_hours: QuietHours.nullish(),
1692
1815
  /** Checked before every step; when it matches, the run ends. */
1693
1816
  exit_filter: BoundedAutomationFilter.nullish()
@@ -1745,18 +1868,18 @@ var AUTOMATION_ISSUE_CODES = [
1745
1868
  /** A one-off date that is already over everywhere on earth, so it would fire for nobody. */
1746
1869
  "date_in_the_past"
1747
1870
  ];
1748
- var AutomationIssueCode = z8.enum(AUTOMATION_ISSUE_CODES);
1749
- var AutomationIssue = z8.object({
1871
+ var AutomationIssueCode = z9.enum(AUTOMATION_ISSUE_CODES);
1872
+ var AutomationIssue = z9.object({
1750
1873
  code: AutomationIssueCode,
1751
1874
  /** The step the issue is about, when it is about one. */
1752
1875
  step_id: StepId.nullable(),
1753
1876
  /** Where inside the document, for the canvas to point at a field. */
1754
- path: z8.array(z8.union([z8.string(), z8.number()])),
1755
- message: z8.string()
1877
+ path: z9.array(z9.union([z9.string(), z9.number()])),
1878
+ message: z9.string()
1756
1879
  });
1757
- var AutomationValidation = z8.object({
1758
- ok: z8.boolean(),
1759
- issues: z8.array(AutomationIssue)
1880
+ var AutomationValidation = z9.object({
1881
+ ok: z9.boolean(),
1882
+ issues: z9.array(AutomationIssue)
1760
1883
  });
1761
1884
  function validateAutomation(flow, settings, ctx) {
1762
1885
  const issues = [];
@@ -2147,7 +2270,7 @@ function cycles(flow) {
2147
2270
  return out.sort();
2148
2271
  }
2149
2272
  var AUTOMATION_STATUSES = ["draft", "active", "paused", "archived"];
2150
- var AutomationStatus = z8.enum(AUTOMATION_STATUSES);
2273
+ var AutomationStatus = z9.enum(AUTOMATION_STATUSES);
2151
2274
  var AUTOMATION_END_REASONS = [
2152
2275
  "completed",
2153
2276
  "exit_filter",
@@ -2166,9 +2289,9 @@ var AUTOMATION_END_REASONS = [
2166
2289
  "ended_by_hand",
2167
2290
  "failed"
2168
2291
  ];
2169
- var AutomationEndReason = z8.enum(AUTOMATION_END_REASONS);
2292
+ var AutomationEndReason = z9.enum(AUTOMATION_END_REASONS);
2170
2293
  var AUTOMATION_WAIT_REASONS = ["delay", "quiet_hours", "plan_limit", "sending", "condition"];
2171
- var AutomationWaitReason = z8.enum(AUTOMATION_WAIT_REASONS);
2294
+ var AutomationWaitReason = z9.enum(AUTOMATION_WAIT_REASONS);
2172
2295
  var AUTOMATION_ENTRY_REFUSALS = [
2173
2296
  "already_inside",
2174
2297
  "re_entry_off",
@@ -2179,26 +2302,26 @@ var AUTOMATION_ENTRY_REFUSALS = [
2179
2302
  "not_active",
2180
2303
  "unknown_contact"
2181
2304
  ];
2182
- var AutomationEntryRefusal = z8.enum(AUTOMATION_ENTRY_REFUSALS);
2183
- var AutomationCounts = z8.object({
2184
- started: z8.number().int().min(0),
2185
- in_progress: z8.number().int().min(0),
2186
- completed: z8.number().int().min(0),
2187
- exited: z8.number().int().min(0),
2188
- failed: z8.number().int().min(0)
2189
- });
2190
- var Automation = z8.object({
2305
+ var AutomationEntryRefusal = z9.enum(AUTOMATION_ENTRY_REFUSALS);
2306
+ var AutomationCounts = z9.object({
2307
+ started: z9.number().int().min(0),
2308
+ in_progress: z9.number().int().min(0),
2309
+ completed: z9.number().int().min(0),
2310
+ exited: z9.number().int().min(0),
2311
+ failed: z9.number().int().min(0)
2312
+ });
2313
+ var Automation = z9.object({
2191
2314
  id: Id,
2192
- name: z8.string().min(1).max(200),
2315
+ name: z9.string().min(1).max(200),
2193
2316
  status: AutomationStatus,
2194
2317
  /** Every automation sends under one topic; there are no transactional automations. */
2195
2318
  topic: Slug,
2196
2319
  provider_id: Id.nullable(),
2197
2320
  settings: AutomationSettings,
2198
2321
  /** The flow people are running through, null while the automation has never been published. */
2199
- published_version: z8.number().int().min(1).nullable(),
2322
+ published_version: z9.number().int().min(1).nullable(),
2200
2323
  /** The flow being edited. Increments on every save, like a template's version. */
2201
- draft_version: z8.number().int().min(1),
2324
+ draft_version: z9.number().int().min(1),
2202
2325
  counts: AutomationCounts,
2203
2326
  created_at: Timestamp,
2204
2327
  updated_at: Timestamp,
@@ -2211,16 +2334,16 @@ var AutomationWithFlow = Automation.extend({
2211
2334
  published_flow: AutomationFlow.nullable()
2212
2335
  });
2213
2336
  var AutomationSummary = Automation;
2214
- var AutomationCreate = z8.object({
2215
- name: z8.string().min(1).max(200),
2337
+ var AutomationCreate = z9.object({
2338
+ name: z9.string().min(1).max(200),
2216
2339
  topic: Slug,
2217
2340
  provider_id: Id.optional(),
2218
2341
  flow: AutomationFlow.optional(),
2219
2342
  settings: AutomationSettings.partial().optional()
2220
2343
  });
2221
- var AutomationUpdate = z8.object({
2222
- base_version: z8.number().int().min(1),
2223
- name: z8.string().min(1).max(200).optional(),
2344
+ var AutomationUpdate = z9.object({
2345
+ base_version: z9.number().int().min(1),
2346
+ name: z9.string().min(1).max(200).optional(),
2224
2347
  topic: Slug.optional(),
2225
2348
  provider_id: Id.optional(),
2226
2349
  flow: AutomationFlow.optional(),
@@ -2233,42 +2356,42 @@ var AutomationListQuery = PageQuery.extend({
2233
2356
  status: AutomationStatus.optional(),
2234
2357
  topic: Slug.optional()
2235
2358
  });
2236
- var AutomationPublishRequest = z8.object({
2359
+ var AutomationPublishRequest = z9.object({
2237
2360
  /**
2238
2361
  * Answer what this publish would do and change nothing, whatever the flow
2239
2362
  * looks like. Without it a publish that has no issues and moves nobody
2240
2363
  * simply goes ahead, which is right for an API caller and wrong for a
2241
2364
  * dialog that is only showing somebody what they are about to do.
2242
2365
  */
2243
- dry_run: z8.boolean().optional(),
2244
- confirm: z8.boolean().optional(),
2366
+ dry_run: z9.boolean().optional(),
2367
+ confirm: z9.boolean().optional(),
2245
2368
  /** Per removed step: the step its waiting runs move to, or null to end them. */
2246
- moves: z8.record(StepId, StepId.nullable()).optional(),
2369
+ moves: z9.record(StepId, StepId.nullable()).optional(),
2247
2370
  /** Also enter everyone who matches a trigger's condition right now. */
2248
- backfill: z8.boolean().optional()
2371
+ backfill: z9.boolean().optional()
2249
2372
  }).strict();
2250
- var AutomationPublishMove = z8.object({
2373
+ var AutomationPublishMove = z9.object({
2251
2374
  step_id: StepId,
2252
2375
  /** Why the step's people have to move: it is gone, or its delay changed. */
2253
- change: z8.enum(["removed", "delay_changed", "kind_changed"]),
2254
- waiting: z8.number().int().min(0),
2376
+ change: z9.enum(["removed", "delay_changed", "kind_changed"]),
2377
+ waiting: z9.number().int().min(0),
2255
2378
  /** Where they go: a step id, or null to end their runs with `step_removed`. */
2256
2379
  destination: StepId.nullable()
2257
2380
  });
2258
- var AutomationPublishResult = z8.object({
2259
- published: z8.boolean(),
2381
+ var AutomationPublishResult = z9.object({
2382
+ published: z9.boolean(),
2260
2383
  automation: Automation,
2261
2384
  /** Empty when nothing has to move; non-empty and `published` false asks for a confirmation. */
2262
- moves: z8.array(AutomationPublishMove),
2385
+ moves: z9.array(AutomationPublishMove),
2263
2386
  /** How many people the backfill entered, or would enter when it is not confirmed. */
2264
- backfill: z8.number().int().min(0),
2265
- issues: z8.array(AutomationIssue)
2266
- });
2267
- var AutomationDuplicateRequest = z8.object({ name: z8.string().min(1).max(200).optional() }).strict();
2268
- var AutomationEnrollRequest = z8.object({
2269
- contact_ids: z8.array(Id).min(1).max(1e3).optional(),
2270
- external_ids: z8.array(z8.string().min(1).max(255)).min(1).max(1e3).optional(),
2271
- emails: z8.array(Email).min(1).max(1e3).optional(),
2387
+ backfill: z9.number().int().min(0),
2388
+ issues: z9.array(AutomationIssue)
2389
+ });
2390
+ var AutomationDuplicateRequest = z9.object({ name: z9.string().min(1).max(200).optional() }).strict();
2391
+ var AutomationEnrollRequest = z9.object({
2392
+ contact_ids: z9.array(Id).min(1).max(1e3).optional(),
2393
+ external_ids: z9.array(z9.string().min(1).max(255)).min(1).max(1e3).optional(),
2394
+ emails: z9.array(Email).min(1).max(1e3).optional(),
2272
2395
  segment_id: Id.optional(),
2273
2396
  /** Where to start them; the flow's entry step by default. */
2274
2397
  step_id: StepId.optional()
@@ -2276,34 +2399,34 @@ var AutomationEnrollRequest = z8.object({
2276
2399
  (v) => [v.contact_ids, v.external_ids, v.emails, v.segment_id].filter((x) => x !== void 0).length === 1,
2277
2400
  "name the people exactly one way: contact_ids, external_ids, emails or segment_id"
2278
2401
  );
2279
- var AutomationEnrollment = z8.object({
2402
+ var AutomationEnrollment = z9.object({
2280
2403
  contact_id: Id.nullable(),
2281
2404
  email: Email.nullable(),
2282
- external_id: z8.string().nullable(),
2283
- entered: z8.boolean(),
2405
+ external_id: z9.string().nullable(),
2406
+ entered: z9.boolean(),
2284
2407
  run_id: Id.nullable(),
2285
2408
  reason: AutomationEntryRefusal.nullable()
2286
2409
  });
2287
- var AutomationEnrollResult = z8.object({
2288
- entered: z8.number().int().min(0),
2289
- refused: z8.number().int().min(0),
2290
- results: z8.array(AutomationEnrollment)
2410
+ var AutomationEnrollResult = z9.object({
2411
+ entered: z9.number().int().min(0),
2412
+ refused: z9.number().int().min(0),
2413
+ results: z9.array(AutomationEnrollment)
2291
2414
  });
2292
- var AutomationRunStatus = z8.enum(["active", "waiting", "completed", "exited", "failed"]);
2293
- var AutomationRun = z8.object({
2415
+ var AutomationRunStatus = z9.enum(["active", "waiting", "completed", "exited", "failed"]);
2416
+ var AutomationRun = z9.object({
2294
2417
  id: Id,
2295
2418
  automation_id: Id,
2296
2419
  contact_id: Id,
2297
2420
  email: Email,
2298
- external_id: z8.string().nullable(),
2299
- version: z8.number().int().min(1),
2421
+ external_id: z9.string().nullable(),
2422
+ version: z9.number().int().min(1),
2300
2423
  status: AutomationRunStatus,
2301
2424
  current_step_id: StepId.nullable(),
2302
2425
  next_action_at: Timestamp.nullable(),
2303
2426
  wait_reason: AutomationWaitReason.nullable(),
2304
- end_reason: z8.string().nullable(),
2427
+ end_reason: z9.string().nullable(),
2305
2428
  /** What went wrong the last time this run tried to take its step, null otherwise. */
2306
- last_error: z8.string().nullable(),
2429
+ last_error: z9.string().nullable(),
2307
2430
  entered_at: Timestamp,
2308
2431
  ended_at: Timestamp.nullable()
2309
2432
  });
@@ -2313,13 +2436,13 @@ var AutomationRunListQuery = PageQuery.extend({
2313
2436
  contact_id: Id.optional()
2314
2437
  });
2315
2438
  var ContactAutomationRun = AutomationRun.extend({
2316
- automation: z8.object({ id: Id, name: z8.string(), status: AutomationStatus })
2439
+ automation: z9.object({ id: Id, name: z9.string(), status: AutomationStatus })
2317
2440
  });
2318
2441
  var ContactAutomationListQuery = PageQuery.extend({ status: AutomationRunStatus.optional() });
2319
- var AutomationStepExecution = z8.object({
2442
+ var AutomationStepExecution = z9.object({
2320
2443
  step_id: StepId,
2321
2444
  step_kind: AutomationStepKind,
2322
- visit: z8.number().int().min(1),
2445
+ visit: z9.number().int().min(1),
2323
2446
  started_at: Timestamp,
2324
2447
  finished_at: Timestamp.nullable(),
2325
2448
  /**
@@ -2331,48 +2454,48 @@ var AutomationStepExecution = z8.object({
2331
2454
  */
2332
2455
  outcome: Properties
2333
2456
  });
2334
- var AutomationJourney = z8.object({
2457
+ var AutomationJourney = z9.object({
2335
2458
  run: AutomationRun,
2336
- steps: z8.array(AutomationStepExecution)
2459
+ steps: z9.array(AutomationStepExecution)
2337
2460
  });
2338
- var AutomationStepReport = z8.object({
2461
+ var AutomationStepReport = z9.object({
2339
2462
  step_id: StepId,
2340
2463
  step_kind: AutomationStepKind,
2341
- reached: z8.number().int().min(0),
2342
- waiting: z8.number().int().min(0),
2343
- passed: z8.number().int().min(0),
2464
+ reached: z9.number().int().min(0),
2465
+ waiting: z9.number().int().min(0),
2466
+ passed: z9.number().int().min(0),
2344
2467
  /** Per branch, for a condition: how many took `yes` and how many `no`. */
2345
- branches: z8.record(z8.number().int().min(0)),
2468
+ branches: z9.record(z9.number().int().min(0)),
2346
2469
  /** The step mailing's id, for an email step of the published version. */
2347
2470
  mailing_id: Id.nullable()
2348
2471
  });
2349
- var AutomationReport = z8.object({
2472
+ var AutomationReport = z9.object({
2350
2473
  counts: AutomationCounts,
2351
2474
  /** Why the people who left did: `AutomationEndReason` to a count. */
2352
- end_reasons: z8.record(z8.number().int().min(0)),
2475
+ end_reasons: z9.record(z9.number().int().min(0)),
2353
2476
  /**
2354
2477
  * Why people a trigger named did not enter: `AutomationEntryRefusal` to a
2355
2478
  * count. Without it a pause, an exclusion or a missing subscription would
2356
2479
  * turn people away invisibly.
2357
2480
  */
2358
- refusals: z8.record(z8.number().int().min(0)),
2359
- steps: z8.array(AutomationStepReport)
2360
- });
2361
- var AutomationExitRunRequest = z8.object({ reason: z8.string().max(200).optional() }).strict();
2362
- var AutomationRunParams = z8.object({ id: Id, run_id: Id });
2363
- var AutomationStepParams = z8.object({ id: Id, step_id: StepId });
2364
- var AutomationTestEmailRequest = z8.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
2365
- var AutomationValidateRequest = z8.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
2366
- var EventCreate = z8.object({
2481
+ refusals: z9.record(z9.number().int().min(0)),
2482
+ steps: z9.array(AutomationStepReport)
2483
+ });
2484
+ var AutomationExitRunRequest = z9.object({ reason: z9.string().max(200).optional() }).strict();
2485
+ var AutomationRunParams = z9.object({ id: Id, run_id: Id });
2486
+ var AutomationStepParams = z9.object({ id: Id, step_id: StepId });
2487
+ var AutomationTestEmailRequest = z9.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
2488
+ var AutomationValidateRequest = z9.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
2489
+ var EventCreate = z9.object({
2367
2490
  name: EventName,
2368
- contact: z8.object({ external_id: z8.string().min(1).max(255).optional(), email: Email.optional(), id: Id.optional() }).refine((c) => [c.external_id, c.email, c.id].filter((x) => x !== void 0).length === 1, "name the contact exactly one way"),
2491
+ contact: z9.object({ external_id: z9.string().min(1).max(255).optional(), email: Email.optional(), id: Id.optional() }).refine((c) => [c.external_id, c.email, c.id].filter((x) => x !== void 0).length === 1, "name the contact exactly one way"),
2369
2492
  data: Properties.optional(),
2370
2493
  occurred_at: Timestamp.optional(),
2371
- id: z8.string().min(1).max(128).optional()
2494
+ id: z9.string().min(1).max(128).optional()
2372
2495
  }).strict();
2373
- var Event = z8.object({
2496
+ var Event = z9.object({
2374
2497
  id: Id,
2375
- client_event_id: z8.string().nullable(),
2498
+ client_event_id: z9.string().nullable(),
2376
2499
  name: EventName,
2377
2500
  contact_id: Id,
2378
2501
  data: Properties,
@@ -2383,7 +2506,7 @@ var Event = z8.object({
2383
2506
  * hand. Each is then admitted or refused by the runtime on its own rules
2384
2507
  * (consent, exclusions, re-entry), which `automations.report` counts.
2385
2508
  */
2386
- entered: z8.number().int().min(0)
2509
+ entered: z9.number().int().min(0)
2387
2510
  });
2388
2511
  var EventListQuery = PageQuery.extend({
2389
2512
  name: EventName.optional(),
@@ -2391,19 +2514,19 @@ var EventListQuery = PageQuery.extend({
2391
2514
  });
2392
2515
 
2393
2516
  // src/workspace.ts
2394
- var CompanyId = z9.string().min(1).max(64);
2517
+ var CompanyId = z10.string().min(1).max(64);
2395
2518
  var ASSET_POLICIES = ["any", "service_only"];
2396
- var AssetPolicy = z9.enum(ASSET_POLICIES);
2519
+ var AssetPolicy = z10.enum(ASSET_POLICIES);
2397
2520
  var MAX_ALLOWED_ASSET_HOSTS = 20;
2398
- var AssetHost = z9.string().trim().toLowerCase().min(1).max(253).regex(/^(?=.{1,253}(?::\d{1,5})?$)[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+(:\d{1,5})?$/, "a host name such as example.com");
2521
+ var AssetHost = z10.string().trim().toLowerCase().min(1).max(253).regex(/^(?=.{1,253}(?::\d{1,5})?$)[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+(:\d{1,5})?$/, "a host name such as example.com");
2399
2522
  var MAX_MERGE_DEFAULTS = 50;
2400
2523
  var MAX_MERGE_DEFAULT_LENGTH = 2e3;
2401
- var MergeFieldName = z9.string().regex(/^[a-z][a-z0-9_]*$/, "a merge-field name: lowercase letters, digits and underscores, starting with a letter").max(64);
2402
- var MergeDefaultValue = z9.union([z9.string().max(MAX_MERGE_DEFAULT_LENGTH), z9.number().finite(), z9.boolean()]);
2403
- var MergeDefaults = z9.record(MergeFieldName, MergeDefaultValue).refine((m) => Object.keys(m).length <= MAX_MERGE_DEFAULTS, `at most ${MAX_MERGE_DEFAULTS} merge defaults`).refine((m) => !Object.keys(m).some((k) => k in RESERVED_MERGE_FIELDS), {
2524
+ var MergeFieldName = z10.string().regex(/^[a-z][a-z0-9_]*$/, "a merge-field name: lowercase letters, digits and underscores, starting with a letter").max(64);
2525
+ var MergeDefaultValue = z10.union([z10.string().max(MAX_MERGE_DEFAULT_LENGTH), z10.number().finite(), z10.boolean()]);
2526
+ var MergeDefaults = z10.record(MergeFieldName, MergeDefaultValue).refine((m) => Object.keys(m).length <= MAX_MERGE_DEFAULTS, `at most ${MAX_MERGE_DEFAULTS} merge defaults`).refine((m) => !Object.keys(m).some((k) => k in RESERVED_MERGE_FIELDS), {
2404
2527
  message: `a reserved merge field (${Object.keys(RESERVED_MERGE_FIELDS).join(", ")}) cannot have a workspace default`
2405
2528
  });
2406
- var WorkspaceSettings = z9.object({
2529
+ var WorkspaceSettings = z10.object({
2407
2530
  /**
2408
2531
  * The workspace's main language (a {@link LocaleTag}, e.g. "de"): the main
2409
2532
  * language of a new template, and of the hosted pages when nothing else
@@ -2416,9 +2539,9 @@ var WorkspaceSettings = z9.object({
2416
2539
  * each; the hosted pages are offered in those of them they support (English,
2417
2540
  * German, French, Italian, Spanish). The service stores canonical casing.
2418
2541
  */
2419
- locales: z9.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
2542
+ locales: z10.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
2420
2543
  /** Open and click tracking. Off by default, opt-in per workspace. */
2421
- tracking_enabled: z9.boolean(),
2544
+ tracking_enabled: z10.boolean(),
2422
2545
  /** Where images, stylesheets and fonts in a mail may load from. `any` by default. */
2423
2546
  asset_policy: AssetPolicy,
2424
2547
  /**
@@ -2426,7 +2549,7 @@ var WorkspaceSettings = z9.object({
2426
2549
  * the workspace's website, typically. Empty by default. Ignored under `any`,
2427
2550
  * which allows everything already.
2428
2551
  */
2429
- allowed_asset_hosts: z9.array(AssetHost).max(MAX_ALLOWED_ASSET_HOSTS),
2552
+ allowed_asset_hosts: z10.array(AssetHost).max(MAX_ALLOWED_ASSET_HOSTS),
2430
2553
  /** Merge values every mail of the workspace can use (see `MergeDefaults`). Empty by default. */
2431
2554
  merge_defaults: MergeDefaults,
2432
2555
  /**
@@ -2435,10 +2558,10 @@ var WorkspaceSettings = z9.object({
2435
2558
  */
2436
2559
  default_timezone: TimezoneName.nullable()
2437
2560
  });
2438
- var Workspace = z9.object({
2561
+ var Workspace = z10.object({
2439
2562
  id: Id,
2440
2563
  slug: Slug,
2441
- name: z9.string().min(1).max(120),
2564
+ name: z10.string().min(1).max(120),
2442
2565
  settings: WorkspaceSettings,
2443
2566
  /**
2444
2567
  * The auth-brain company (tenant) the workspace was created for, or null for
@@ -2449,13 +2572,13 @@ var Workspace = z9.object({
2449
2572
  created_at: Timestamp,
2450
2573
  updated_at: Timestamp
2451
2574
  });
2452
- var WorkspaceCreate = z9.object({
2575
+ var WorkspaceCreate = z10.object({
2453
2576
  slug: Slug,
2454
- name: z9.string().min(1).max(120),
2577
+ name: z10.string().min(1).max(120),
2455
2578
  settings: WorkspaceSettings.partial().optional(),
2456
- owner: z9.object({
2579
+ owner: z10.object({
2457
2580
  email: Email,
2458
- name: z9.string().max(200).nullable().optional()
2581
+ name: z10.string().max(200).nullable().optional()
2459
2582
  }),
2460
2583
  /**
2461
2584
  * The signed-in person's active auth-brain company. The dashboard always
@@ -2465,49 +2588,49 @@ var WorkspaceCreate = z9.object({
2465
2588
  */
2466
2589
  company_id: CompanyId.optional()
2467
2590
  });
2468
- var WorkspaceUpdate = z9.object({
2469
- name: z9.string().min(1).max(120),
2591
+ var WorkspaceUpdate = z10.object({
2592
+ name: z10.string().min(1).max(120),
2470
2593
  settings: WorkspaceSettings.partial()
2471
2594
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
2472
- var WorkspaceMove = z9.object({ company_id: CompanyId });
2595
+ var WorkspaceMove = z10.object({ company_id: CompanyId });
2473
2596
  var MEMBER_ROLES = ["owner", "admin", "editor", "viewer"];
2474
- var MemberRole = z9.enum(MEMBER_ROLES);
2597
+ var MemberRole = z10.enum(MEMBER_ROLES);
2475
2598
  var WorkspaceMembership = Workspace.extend({ role: MemberRole });
2476
- var Member = z9.object({
2599
+ var Member = z10.object({
2477
2600
  id: Id,
2478
2601
  /** The person's auth-brain subject. */
2479
- subject: z9.string().min(1).max(255),
2602
+ subject: z10.string().min(1).max(255),
2480
2603
  email: Email,
2481
- name: z9.string().max(200).nullable(),
2604
+ name: z10.string().max(200).nullable(),
2482
2605
  role: MemberRole,
2483
2606
  created_at: Timestamp
2484
2607
  });
2485
- var MemberCreate = z9.object({
2486
- subject: z9.string().min(1).max(255),
2608
+ var MemberCreate = z10.object({
2609
+ subject: z10.string().min(1).max(255),
2487
2610
  email: Email,
2488
- name: z9.string().max(200).nullable().optional(),
2611
+ name: z10.string().max(200).nullable().optional(),
2489
2612
  role: MemberRole
2490
2613
  });
2491
- var MemberUpdate = z9.object({ role: MemberRole });
2614
+ var MemberUpdate = z10.object({ role: MemberRole });
2492
2615
  var API_KEY_SCOPES = ["full", "read", "send"];
2493
- var ApiKeyScope = z9.enum(API_KEY_SCOPES);
2494
- var ApiKey = z9.object({
2616
+ var ApiKeyScope = z10.enum(API_KEY_SCOPES);
2617
+ var ApiKey = z10.object({
2495
2618
  id: Id,
2496
- name: z9.string().min(1).max(120),
2619
+ name: z10.string().min(1).max(120),
2497
2620
  /** The first characters of the key, for recognising it in a list. */
2498
- prefix: z9.string().min(4).max(32),
2621
+ prefix: z10.string().min(4).max(32),
2499
2622
  scope: ApiKeyScope,
2500
2623
  last_used_at: Timestamp.nullable(),
2501
2624
  revoked_at: Timestamp.nullable(),
2502
2625
  created_at: Timestamp
2503
2626
  });
2504
- var ApiKeyCreate = z9.object({
2505
- name: z9.string().min(1).max(120),
2627
+ var ApiKeyCreate = z10.object({
2628
+ name: z10.string().min(1).max(120),
2506
2629
  /** Omitted means `full`. */
2507
2630
  scope: ApiKeyScope.optional()
2508
2631
  });
2509
- var ApiKeyCreated = z9.object({
2510
- key: z9.string().min(20),
2632
+ var ApiKeyCreated = z10.object({
2633
+ key: z10.string().min(20),
2511
2634
  api_key: ApiKey
2512
2635
  });
2513
2636
  var AUDIT_ACTIONS = [
@@ -2534,6 +2657,7 @@ var AUDIT_ACTIONS = [
2534
2657
  "template.created",
2535
2658
  "template.updated",
2536
2659
  "template.deleted",
2660
+ "template.inputs_declared",
2537
2661
  "saved_section.created",
2538
2662
  "saved_section.updated",
2539
2663
  "saved_section.deleted",
@@ -2595,29 +2719,29 @@ var AUDIT_ACTIONS = [
2595
2719
  "automation.run_ended",
2596
2720
  "event.recorded"
2597
2721
  ];
2598
- var AuditAction = z9.enum(AUDIT_ACTIONS);
2599
- var AuditActor = z9.discriminatedUnion("type", [
2600
- z9.object({ type: z9.literal("member"), member_id: Id, subject: z9.string().min(1) }),
2601
- z9.object({
2602
- type: z9.literal("api_key"),
2722
+ var AuditAction = z10.enum(AUDIT_ACTIONS);
2723
+ var AuditActor = z10.discriminatedUnion("type", [
2724
+ z10.object({ type: z10.literal("member"), member_id: Id, subject: z10.string().min(1) }),
2725
+ z10.object({
2726
+ type: z10.literal("api_key"),
2603
2727
  api_key_id: Id,
2604
2728
  /**
2605
2729
  * Who the client's application said it was acting for, from
2606
2730
  * `ON_BEHALF_OF_HEADER`: reported by that application, never verified.
2607
2731
  * Absent when the call carried no label.
2608
2732
  */
2609
- on_behalf_of: z9.string().min(1).max(ON_BEHALF_OF_MAX_LENGTH).optional()
2733
+ on_behalf_of: z10.string().min(1).max(ON_BEHALF_OF_MAX_LENGTH).optional()
2610
2734
  }),
2611
2735
  /** The service itself (the worker, a bounce, the hosted unsubscribe page). */
2612
- z9.object({ type: z9.literal("system"), reason: z9.string().min(1).max(200) })
2736
+ z10.object({ type: z10.literal("system"), reason: z10.string().min(1).max(200) })
2613
2737
  ]);
2614
- var AuditEntry = z9.object({
2738
+ var AuditEntry = z10.object({
2615
2739
  id: Id,
2616
2740
  action: AuditAction,
2617
2741
  actor: AuditActor,
2618
- target_type: z9.string().min(1).max(64),
2742
+ target_type: z10.string().min(1).max(64),
2619
2743
  target_id: Id.nullable(),
2620
- details: z9.record(z9.unknown()),
2744
+ details: z10.record(z10.unknown()),
2621
2745
  created_at: Timestamp
2622
2746
  });
2623
2747
  var AuditQuery = PageQuery.extend({
@@ -2626,12 +2750,12 @@ var AuditQuery = PageQuery.extend({
2626
2750
  });
2627
2751
 
2628
2752
  // src/invites.ts
2629
- import { z as z10 } from "zod";
2753
+ import { z as z11 } from "zod";
2630
2754
  var INVITE_STATUSES = ["pending", "accepted", "revoked", "expired"];
2631
- var InviteStatus = z10.enum(INVITE_STATUSES);
2755
+ var InviteStatus = z11.enum(INVITE_STATUSES);
2632
2756
  var DEFAULT_INVITE_TTL_DAYS = 7;
2633
2757
  var MAX_INVITE_TTL_DAYS = 30;
2634
- var Invite = z10.object({
2758
+ var Invite = z11.object({
2635
2759
  id: Id,
2636
2760
  /** Stored lowercased; only a person signed in with this address can accept. */
2637
2761
  email: Email,
@@ -2639,32 +2763,32 @@ var Invite = z10.object({
2639
2763
  /** Derived from the timestamps below, never stored. */
2640
2764
  status: InviteStatus,
2641
2765
  /** The member who invited, while they are still one (null after they left). */
2642
- invited_by: z10.object({ member_id: Id.nullable(), email: Email.nullable() }),
2766
+ invited_by: z11.object({ member_id: Id.nullable(), email: Email.nullable() }),
2643
2767
  expires_at: Timestamp,
2644
2768
  accepted_at: Timestamp.nullable(),
2645
2769
  revoked_at: Timestamp.nullable(),
2646
2770
  created_at: Timestamp
2647
2771
  });
2648
- var InviteCreate = z10.object({
2772
+ var InviteCreate = z11.object({
2649
2773
  email: Email,
2650
2774
  role: MemberRole,
2651
- expires_in_days: z10.number().int().min(1).max(MAX_INVITE_TTL_DAYS).optional()
2775
+ expires_in_days: z11.number().int().min(1).max(MAX_INVITE_TTL_DAYS).optional()
2652
2776
  });
2653
- var InviteCreated = z10.object({
2777
+ var InviteCreated = z11.object({
2654
2778
  invite: Invite,
2655
- token: z10.string().min(32).max(128)
2779
+ token: z11.string().min(32).max(128)
2656
2780
  });
2657
2781
  var InviteListQuery = PageQuery.extend({
2658
2782
  status: InviteStatus.optional()
2659
2783
  });
2660
- var InviteAccept = z10.object({
2661
- token: z10.string().min(32).max(128),
2784
+ var InviteAccept = z11.object({
2785
+ token: z11.string().min(32).max(128),
2662
2786
  email: Email,
2663
- name: z10.string().max(200).nullable().optional()
2787
+ name: z11.string().max(200).nullable().optional()
2664
2788
  });
2665
- var InviteAccepted = z10.object({
2789
+ var InviteAccepted = z11.object({
2666
2790
  workspace: WorkspaceMembership,
2667
- already_member: z10.boolean()
2791
+ already_member: z11.boolean()
2668
2792
  });
2669
2793
  var INVITE_REFUSAL_REASONS = ["email_mismatch", "inviter_lacks_role", "expired", "revoked", "accepted"];
2670
2794
 
@@ -2971,14 +3095,14 @@ function insertionNameProblem(insertions, name, current) {
2971
3095
  if (has(RESERVED_MERGE_FIELDS, name)) return `"${name}" is a merge field the service fills itself. Choose another name.`;
2972
3096
  if (name !== current && has(insertions, name)) return `There is already an insertion called "${name}".`;
2973
3097
  const chooser = Object.entries(insertions).find(([other, def]) => def.by === name && other !== current);
2974
- if (chooser) return `"${name}" is the value that chooses "${chooser[0]}". Choose another name.`;
2975
- if (current !== void 0 && ownEntry(insertions, current)?.by === name) return `"${name}" is the value that chooses this insertion. Choose another name.`;
3098
+ if (chooser) return `"${name}" is the value "${chooser[0]}" depends on. Choose another name.`;
3099
+ if (current !== void 0 && ownEntry(insertions, current)?.by === name) return `"${name}" is the value this insertion depends on. Choose another name.`;
2976
3100
  return null;
2977
3101
  }
2978
3102
  function insertionByProblem(insertions, by, self) {
2979
- if (!InsertionName.safeParse(by).success) return "The value that chooses is a merge-field name: lowercase letters, digits and underscores (like reason).";
2980
- if (by === "unsubscribe_url") return "The unsubscribe link cannot choose a text. Use a value the client or the contact provides.";
2981
- if (by === self || has(insertions, by)) return `"${by}" is an insertion, not a value. Use a value the client or the contact provides.`;
3103
+ if (!InsertionName.safeParse(by).success) return "The value it depends on is a merge-field name: lowercase letters, digits and underscores (like reason).";
3104
+ if (by === "unsubscribe_url") return "An insertion cannot depend on the unsubscribe link. Use a value the app or the contact provides.";
3105
+ if (by === self || has(insertions, by)) return `"${by}" is an insertion, not a value. Use a value the app or the contact provides.`;
2982
3106
  return null;
2983
3107
  }
2984
3108
  function normalizeChoiceKey(raw) {
@@ -2986,10 +3110,10 @@ function normalizeChoiceKey(raw) {
2986
3110
  }
2987
3111
  function choiceKeyProblem(insertion, key, current) {
2988
3112
  if (INSERTION_TEXT_SLOTS.includes(key)) {
2989
- return `"${key}" names the insertion's ${key === "filled" ? '"any other filled value"' : '"otherwise"'} text, so it cannot be a choice. Choose another value.`;
3113
+ return `"${key}" is kept for the insertion's ${key === "filled" ? '"any other value"' : '"empty"'} sentence, so it cannot be a value. Choose another value.`;
2990
3114
  }
2991
- if (!InsertionChoiceKey.safeParse(key).success) return "A choice is the value a client sends: lowercase letters, digits, hyphens and underscores (like venue).";
2992
- if (key !== current && has(insertion.choices, key)) return `There is already a choice "${key}".`;
3115
+ if (!InsertionChoiceKey.safeParse(key).success) return "A value is written exactly as the app sends it: lowercase letters, digits, hyphens and underscores (like venue).";
3116
+ if (key !== current && has(insertion.choices, key)) return `"${key}" already has its own sentence.`;
2993
3117
  return null;
2994
3118
  }
2995
3119
  function addInsertion(drafts, rawName, rawBy) {
@@ -2998,7 +3122,7 @@ function addInsertion(drafts, rawName, rawBy) {
2998
3122
  if (Object.keys(drafts.insertions).length >= MAX_INSERTIONS) return { ok: false, message: `A template holds at most ${MAX_INSERTIONS} insertions.` };
2999
3123
  const nameProblem = insertionNameProblem(drafts.insertions, name);
3000
3124
  if (nameProblem) return { ok: false, message: nameProblem };
3001
- if (name === by) return { ok: false, message: "An insertion cannot be chosen by its own name. Use the value the client sends (like reason)." };
3125
+ if (name === by) return { ok: false, message: "An insertion cannot depend on its own name. Use the value the app sends (like reason)." };
3002
3126
  const byProblem = insertionByProblem(drafts.insertions, by);
3003
3127
  if (byProblem) return { ok: false, message: byProblem };
3004
3128
  return { ok: true, drafts: editMainInsertions(drafts, { ...drafts.insertions, [name]: { by, choices: {}, filled: null, otherwise: "" } }) };
@@ -3189,15 +3313,99 @@ function insertionRefusalHint(details) {
3189
3313
  const missing = Array.isArray(details?.missing) ? details.missing.filter((m) => typeof m === "object" && m !== null && typeof m.insertion === "string" && typeof m.choice === "string") : [];
3190
3314
  return missing.length > 0 ? `The language has ${describeMissingTexts(missing)}. ${hint}` : hint;
3191
3315
  }
3316
+ function tokenOf(name) {
3317
+ return new RegExp(String.raw`\{\{(\s*)${name}(\s*)(\|[^}]*)?\}\}`, "g");
3318
+ }
3319
+ function renameTokenInText(text, from, to) {
3320
+ let count = 0;
3321
+ const out = text.replace(tokenOf(from), (_m, before, after, fallback) => {
3322
+ count++;
3323
+ return `{{${before}${to}${after}${fallback ?? ""}}}`;
3324
+ });
3325
+ return { text: count > 0 ? out : text, count };
3326
+ }
3327
+ function renameTokenInDocument(document, from, to) {
3328
+ let count = 0;
3329
+ const walk = (value) => {
3330
+ if (typeof value === "string") {
3331
+ const r = renameTokenInText(value, from, to);
3332
+ count += r.count;
3333
+ return r.text;
3334
+ }
3335
+ if (Array.isArray(value)) {
3336
+ let changed = false;
3337
+ const next2 = value.map((v) => {
3338
+ const w = walk(v);
3339
+ if (w !== v) changed = true;
3340
+ return w;
3341
+ });
3342
+ return changed ? next2 : value;
3343
+ }
3344
+ if (value && typeof value === "object") {
3345
+ let changed = false;
3346
+ const next2 = {};
3347
+ for (const [k, v] of Object.entries(value)) {
3348
+ const w = walk(v);
3349
+ if (w !== v) changed = true;
3350
+ next2[k] = w;
3351
+ }
3352
+ return changed ? next2 : value;
3353
+ }
3354
+ return value;
3355
+ };
3356
+ const renamed = walk(document);
3357
+ return { document: renamed, count };
3358
+ }
3359
+ function renameInsertionPlacements(drafts, from, to) {
3360
+ if (from === to) return { drafts, places: [] };
3361
+ const places = [];
3362
+ const note2 = (locale, where, count) => {
3363
+ if (count > 0) places.push({ locale, where, count });
3364
+ };
3365
+ const body = renameTokenInDocument(drafts.main.document, from, to);
3366
+ const subject = renameTokenInText(drafts.main.subject, from, to);
3367
+ const preheader = renameTokenInText(drafts.main.preheader, from, to);
3368
+ note2(null, "body", body.count);
3369
+ note2(null, "subject", subject.count);
3370
+ note2(null, "preheader", preheader.count);
3371
+ let out = {
3372
+ ...drafts,
3373
+ main: { subject: subject.text, preheader: preheader.text, document: body.document },
3374
+ mainDocumentChanged: drafts.mainDocumentChanged || body.count > 0
3375
+ };
3376
+ for (const [tag, version] of Object.entries(drafts.translations)) {
3377
+ const b = renameTokenInDocument(version.document, from, to);
3378
+ const s = version.subject === null ? { text: null, count: 0 } : renameTokenInText(version.subject, from, to);
3379
+ const p = version.preheader === null ? { text: null, count: 0 } : renameTokenInText(version.preheader, from, to);
3380
+ note2(tag, "body", b.count);
3381
+ note2(tag, "subject", s.count);
3382
+ note2(tag, "preheader", p.count);
3383
+ if (b.count + s.count + p.count === 0) continue;
3384
+ out = {
3385
+ ...out,
3386
+ translations: { ...out.translations, [tag]: { ...version, document: b.document, subject: s.text, preheader: p.text } },
3387
+ changed: out.changed.includes(tag) ? out.changed : [...out.changed, tag]
3388
+ };
3389
+ }
3390
+ return { drafts: out, places };
3391
+ }
3392
+ function renameInsertionEverywhere(drafts, from, rawTo) {
3393
+ const renamed = renameInsertionChecked(drafts, from, rawTo);
3394
+ if (!renamed.ok) return renamed;
3395
+ const to = rawTo.trim();
3396
+ if (to === from) return { ok: true, drafts, places: [] };
3397
+ const placed = renameInsertionPlacements(renamed.drafts, from, to);
3398
+ return { ok: true, drafts: placed.drafts, places: placed.places };
3399
+ }
3192
3400
 
3193
3401
  // src/providers.ts
3194
- import { z as z11 } from "zod";
3402
+ import { z as z12 } from "zod";
3195
3403
  var PROVIDER_KINDS = ["smtp", "resend"];
3196
- var ProviderKind = z11.enum(PROVIDER_KINDS);
3197
- var ProviderPolicy = z11.object({
3198
- daily_recipient_budget: z11.number().int().min(1).max(1e7),
3199
- min_interval_ms: z11.number().int().min(0).max(36e5),
3200
- max_recipients_per_message: z11.number().int().min(1).max(1e3)
3404
+ var ProviderKind = z12.enum(PROVIDER_KINDS);
3405
+ var ProviderPolicy = z12.object({
3406
+ daily_recipient_budget: z12.number().int().min(1).max(1e7),
3407
+ min_interval_ms: z12.number().int().min(0).max(36e5),
3408
+ max_recipients_per_message: z12.number().int().min(1).max(1e3)
3201
3409
  });
3202
3410
  var ICLOUD_SMTP_POLICY = {
3203
3411
  daily_recipient_budget: 800,
@@ -3205,17 +3413,17 @@ var ICLOUD_SMTP_POLICY = {
3205
3413
  max_recipients_per_message: 1
3206
3414
  };
3207
3415
  var SMTP_SECURITY = ["tls", "starttls"];
3208
- var SmtpConfigBase = z11.object({
3209
- host: z11.string().min(1).max(255),
3210
- port: z11.number().int().min(1).max(65535),
3416
+ var SmtpConfigBase = z12.object({
3417
+ host: z12.string().min(1).max(255),
3418
+ port: z12.number().int().min(1).max(65535),
3211
3419
  /** `tls` connects encrypted (465), `starttls` upgrades (587). Never plaintext. */
3212
- security: z11.enum(SMTP_SECURITY),
3213
- username: z11.string().min(1).max(255)
3420
+ security: z12.enum(SMTP_SECURITY),
3421
+ username: z12.string().min(1).max(255)
3214
3422
  });
3215
- var ResendConfigBase = z11.object({});
3216
- var ProviderRejections = z11.object({
3217
- count: z11.number().int().min(0),
3218
- last_error: z11.string().nullable(),
3423
+ var ResendConfigBase = z12.object({});
3424
+ var ProviderRejections = z12.object({
3425
+ count: z12.number().int().min(0),
3426
+ last_error: z12.string().nullable(),
3219
3427
  last_at: Timestamp.nullable(),
3220
3428
  /**
3221
3429
  * The last time the bounce circuit breaker tripped on one of this provider's
@@ -3225,59 +3433,59 @@ var ProviderRejections = z11.object({
3225
3433
  * run's bounce blocks were undone and the mailing paused. `sample` is the
3226
3434
  * reply that tripped it.
3227
3435
  */
3228
- anomaly: z11.object({
3436
+ anomaly: z12.object({
3229
3437
  at: Timestamp,
3230
3438
  /** `mailing`: one mailing was paused. `provider`: 5 refusals in a row with the same reply across the provider's sends (test sends and one-recipient mailings included) within 24 hours. */
3231
- scope: z11.enum(["mailing", "provider"]),
3439
+ scope: z12.enum(["mailing", "provider"]),
3232
3440
  /**
3233
3441
  * True while the provider-wide breaker is open: no bounce blocks through
3234
3442
  * this provider, test sends refused and mailings not started or resumed
3235
3443
  * (`provider_anomaly`), until an admin clears it (`providers.clearAnomaly`).
3236
3444
  */
3237
- blocking: z11.boolean(),
3445
+ blocking: z12.boolean(),
3238
3446
  mailing_id: Id.nullable(),
3239
- reason: z11.string(),
3240
- sample: z11.string()
3447
+ reason: z12.string(),
3448
+ sample: z12.string()
3241
3449
  }).nullable()
3242
3450
  });
3243
- var ProviderEvents = z11.object({
3244
- status: z11.enum(["active", "needs_secret"]),
3245
- source: z11.enum(["automatic", "manual"]).nullable(),
3246
- url: z11.string().url(),
3247
- error: z11.string().nullable(),
3451
+ var ProviderEvents = z12.object({
3452
+ status: z12.enum(["active", "needs_secret"]),
3453
+ source: z12.enum(["automatic", "manual"]).nullable(),
3454
+ url: z12.string().url(),
3455
+ error: z12.string().nullable(),
3248
3456
  /**
3249
3457
  * Events that named an email this provider never sent through the service
3250
3458
  * (another workspace or system sharing the Resend account): counted, never
3251
3459
  * acted on.
3252
3460
  */
3253
- unmatched: z11.number().int().min(0)
3461
+ unmatched: z12.number().int().min(0)
3254
3462
  });
3255
3463
  var RESEND_EVENT_TYPES = ["email.bounced", "email.complained", "email.delivery_delayed"];
3256
- var ResendSigningSecret = z11.string().max(200).regex(/^whsec_[A-Za-z0-9+/]{16,}={0,2}$/, "must be the signing secret Resend shows, starting with whsec_");
3257
- var ProviderEventsSecret = z11.object({ signing_secret: ResendSigningSecret });
3464
+ var ResendSigningSecret = z12.string().max(200).regex(/^whsec_[A-Za-z0-9+/]{16,}={0,2}$/, "must be the signing secret Resend shows, starting with whsec_");
3465
+ var ProviderEventsSecret = z12.object({ signing_secret: ResendSigningSecret });
3258
3466
  var ProviderFields = {
3259
- name: z11.string().min(1).max(120),
3260
- from_name: z11.string().min(1).max(120),
3467
+ name: z12.string().min(1).max(120),
3468
+ from_name: z12.string().min(1).max(120),
3261
3469
  from_email: Email,
3262
3470
  reply_to: Email.nullable(),
3263
3471
  policy: ProviderPolicy
3264
3472
  };
3265
- var Provider = z11.discriminatedUnion("kind", [
3266
- z11.object({
3473
+ var Provider = z12.discriminatedUnion("kind", [
3474
+ z12.object({
3267
3475
  id: Id,
3268
- kind: z11.literal("smtp"),
3476
+ kind: z12.literal("smtp"),
3269
3477
  config: SmtpConfigBase,
3270
- has_secret: z11.boolean(),
3478
+ has_secret: z12.boolean(),
3271
3479
  ...ProviderFields,
3272
3480
  rejections: ProviderRejections,
3273
3481
  created_at: Timestamp,
3274
3482
  updated_at: Timestamp
3275
3483
  }),
3276
- z11.object({
3484
+ z12.object({
3277
3485
  id: Id,
3278
- kind: z11.literal("resend"),
3486
+ kind: z12.literal("resend"),
3279
3487
  config: ResendConfigBase,
3280
- has_secret: z11.boolean(),
3488
+ has_secret: z12.boolean(),
3281
3489
  ...ProviderFields,
3282
3490
  rejections: ProviderRejections,
3283
3491
  events: ProviderEvents,
@@ -3285,31 +3493,31 @@ var Provider = z11.discriminatedUnion("kind", [
3285
3493
  updated_at: Timestamp
3286
3494
  })
3287
3495
  ]);
3288
- var ProviderCreate = z11.discriminatedUnion("kind", [
3289
- z11.object({
3290
- kind: z11.literal("smtp"),
3291
- config: SmtpConfigBase.extend({ password: z11.string().min(1).max(1024) }),
3496
+ var ProviderCreate = z12.discriminatedUnion("kind", [
3497
+ z12.object({
3498
+ kind: z12.literal("smtp"),
3499
+ config: SmtpConfigBase.extend({ password: z12.string().min(1).max(1024) }),
3292
3500
  ...ProviderFields
3293
3501
  }),
3294
- z11.object({
3295
- kind: z11.literal("resend"),
3296
- config: ResendConfigBase.extend({ api_key: z11.string().min(1).max(1024) }),
3502
+ z12.object({
3503
+ kind: z12.literal("resend"),
3504
+ config: ResendConfigBase.extend({ api_key: z12.string().min(1).max(1024) }),
3297
3505
  ...ProviderFields
3298
3506
  })
3299
3507
  ]);
3300
- var ProviderUpdate = z11.discriminatedUnion("kind", [
3301
- z11.object({
3302
- kind: z11.literal("smtp"),
3303
- config: SmtpConfigBase.extend({ password: z11.string().min(1).max(1024).optional() }).partial().optional(),
3508
+ var ProviderUpdate = z12.discriminatedUnion("kind", [
3509
+ z12.object({
3510
+ kind: z12.literal("smtp"),
3511
+ config: SmtpConfigBase.extend({ password: z12.string().min(1).max(1024).optional() }).partial().optional(),
3304
3512
  name: ProviderFields.name.optional(),
3305
3513
  from_name: ProviderFields.from_name.optional(),
3306
3514
  from_email: ProviderFields.from_email.optional(),
3307
3515
  reply_to: ProviderFields.reply_to.optional(),
3308
3516
  policy: ProviderPolicy.partial().optional()
3309
3517
  }),
3310
- z11.object({
3311
- kind: z11.literal("resend"),
3312
- config: ResendConfigBase.extend({ api_key: z11.string().min(1).max(1024).optional() }).optional(),
3518
+ z12.object({
3519
+ kind: z12.literal("resend"),
3520
+ config: ResendConfigBase.extend({ api_key: z12.string().min(1).max(1024).optional() }).optional(),
3313
3521
  name: ProviderFields.name.optional(),
3314
3522
  from_name: ProviderFields.from_name.optional(),
3315
3523
  from_email: ProviderFields.from_email.optional(),
@@ -3317,48 +3525,48 @@ var ProviderUpdate = z11.discriminatedUnion("kind", [
3317
3525
  policy: ProviderPolicy.partial().optional()
3318
3526
  })
3319
3527
  ]);
3320
- var ProviderUsage = z11.object({
3528
+ var ProviderUsage = z12.object({
3321
3529
  provider_id: Id,
3322
- recipients_last_24h: z11.number().int().min(0),
3323
- remaining_budget: z11.number().int().min(0),
3530
+ recipients_last_24h: z12.number().int().min(0),
3531
+ remaining_budget: z12.number().int().min(0),
3324
3532
  /** When enough of the rolling window frees up to send again, if exhausted. */
3325
3533
  next_capacity_at: Timestamp.nullable()
3326
3534
  });
3327
- var ProviderVerifyResult = z11.object({
3328
- ok: z11.boolean(),
3329
- error: z11.string().nullable()
3535
+ var ProviderVerifyResult = z12.object({
3536
+ ok: z12.boolean(),
3537
+ error: z12.string().nullable()
3330
3538
  });
3331
3539
 
3332
3540
  // src/contacts.ts
3333
- import { z as z12 } from "zod";
3334
- var Topic = z12.object({
3541
+ import { z as z13 } from "zod";
3542
+ var Topic = z13.object({
3335
3543
  id: Id,
3336
3544
  slug: Slug,
3337
- name: z12.string().min(1).max(120),
3545
+ name: z13.string().min(1).max(120),
3338
3546
  /** Shown on the hosted preference page. */
3339
- description: z12.string().max(1e3).nullable(),
3547
+ description: z13.string().max(1e3).nullable(),
3340
3548
  /** Translations of `name` and `description` per locale, for the hosted page. */
3341
- translations: z12.record(
3342
- z12.object({ name: z12.string().min(1).max(120), description: z12.string().max(1e3).nullable() })
3549
+ translations: z13.record(
3550
+ z13.object({ name: z13.string().min(1).max(120), description: z13.string().max(1e3).nullable() })
3343
3551
  ),
3344
3552
  created_at: Timestamp,
3345
3553
  updated_at: Timestamp
3346
3554
  });
3347
- var TopicCreate = z12.object({
3555
+ var TopicCreate = z13.object({
3348
3556
  slug: Slug,
3349
- name: z12.string().min(1).max(120),
3350
- description: z12.string().max(1e3).optional(),
3557
+ name: z13.string().min(1).max(120),
3558
+ description: z13.string().max(1e3).optional(),
3351
3559
  translations: Topic.shape.translations.optional()
3352
3560
  });
3353
3561
  var TopicUpdate = TopicCreate.omit({ slug: true }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
3354
- var Contact = z12.object({
3562
+ var Contact = z13.object({
3355
3563
  id: Id,
3356
- external_id: z12.string().min(1).max(255).nullable(),
3564
+ external_id: z13.string().min(1).max(255).nullable(),
3357
3565
  /** Stored lowercased, unique per workspace. */
3358
3566
  email: Email,
3359
- first_name: z12.string().max(200).nullable(),
3360
- last_name: z12.string().max(200).nullable(),
3361
- locale: z12.string().min(2).max(35).nullable(),
3567
+ first_name: z13.string().max(200).nullable(),
3568
+ last_name: z13.string().max(200).nullable(),
3569
+ locale: z13.string().min(2).max(35).nullable(),
3362
3570
  /**
3363
3571
  * The person's own time zone, an IANA name such as `Europe/Berlin` (A1).
3364
3572
  * Every wall clock an automation waits for is read in it, falling back to the
@@ -3366,65 +3574,65 @@ var Contact = z12.object({
3366
3574
  */
3367
3575
  timezone: TimezoneName.nullable(),
3368
3576
  properties: Properties,
3369
- topics: z12.array(Slug),
3577
+ topics: z13.array(Slug),
3370
3578
  /** The slugs of the contact's tags (S4). */
3371
- tags: z12.array(Slug),
3579
+ tags: z13.array(Slug),
3372
3580
  created_at: Timestamp,
3373
3581
  updated_at: Timestamp
3374
3582
  });
3375
- var ContactUpsert = z12.object({
3376
- external_id: z12.string().min(1).max(255).optional(),
3583
+ var ContactUpsert = z13.object({
3584
+ external_id: z13.string().min(1).max(255).optional(),
3377
3585
  email: Email.optional(),
3378
- first_name: z12.string().max(200).nullable().optional(),
3379
- last_name: z12.string().max(200).nullable().optional(),
3380
- locale: z12.string().min(2).max(35).nullable().optional(),
3586
+ first_name: z13.string().max(200).nullable().optional(),
3587
+ last_name: z13.string().max(200).nullable().optional(),
3588
+ locale: z13.string().min(2).max(35).nullable().optional(),
3381
3589
  timezone: TimezoneName.nullable().optional(),
3382
3590
  properties: Properties.optional(),
3383
- topics: z12.array(Slug).max(100).optional()
3591
+ topics: z13.array(Slug).max(100).optional()
3384
3592
  }).refine((v) => v.external_id !== void 0 || v.email !== void 0, {
3385
3593
  message: "external_id or email is required",
3386
3594
  path: ["email"]
3387
3595
  });
3388
- var ContactUpsertResult = z12.object({
3596
+ var ContactUpsertResult = z13.object({
3389
3597
  contact: Contact,
3390
- created: z12.boolean()
3598
+ created: z13.boolean()
3391
3599
  });
3392
3600
  var ContactListQuery = PageQuery.extend({
3393
- email: z12.string().min(1).max(254).optional(),
3394
- external_id: z12.string().min(1).max(255).optional(),
3601
+ email: z13.string().min(1).max(254).optional(),
3602
+ external_id: z13.string().min(1).max(255).optional(),
3395
3603
  topic: Slug.optional()
3396
3604
  });
3397
- var ContactErased = z12.object({
3398
- ok: z12.literal(true),
3399
- erased_messages: z12.number().int().min(0),
3400
- erased_recipients: z12.number().int().min(0),
3401
- suppressions_kept: z12.number().int().min(0)
3605
+ var ContactErased = z13.object({
3606
+ ok: z13.literal(true),
3607
+ erased_messages: z13.number().int().min(0),
3608
+ erased_recipients: z13.number().int().min(0),
3609
+ suppressions_kept: z13.number().int().min(0)
3402
3610
  });
3403
3611
  var SUPPRESSION_REASONS = ["unsubscribed", "bounced", "complained", "manual"];
3404
- var SuppressionReason = z12.enum(SUPPRESSION_REASONS);
3405
- var Suppression = z12.object({
3612
+ var SuppressionReason = z13.enum(SUPPRESSION_REASONS);
3613
+ var Suppression = z13.object({
3406
3614
  id: Id,
3407
3615
  email: Email,
3408
3616
  reason: SuppressionReason,
3409
3617
  topic: Slug.nullable(),
3410
3618
  source_message_id: Id.nullable(),
3411
- note: z12.string().max(1e3).nullable(),
3619
+ note: z13.string().max(1e3).nullable(),
3412
3620
  created_at: Timestamp
3413
3621
  });
3414
- var SuppressionCreate = z12.object({
3622
+ var SuppressionCreate = z13.object({
3415
3623
  email: Email,
3416
- reason: z12.enum(["manual", "unsubscribed"]),
3624
+ reason: z13.enum(["manual", "unsubscribed"]),
3417
3625
  topic: Slug.nullable().optional(),
3418
- note: z12.string().max(1e3).optional()
3626
+ note: z13.string().max(1e3).optional()
3419
3627
  });
3420
3628
  var SuppressionListQuery = PageQuery.extend({
3421
- email: z12.string().min(1).max(254).optional(),
3629
+ email: z13.string().min(1).max(254).optional(),
3422
3630
  reason: SuppressionReason.optional(),
3423
3631
  topic: Slug.optional()
3424
3632
  });
3425
3633
 
3426
3634
  // src/webhooks.ts
3427
- import { z as z13 } from "zod";
3635
+ import { z as z14 } from "zod";
3428
3636
  var WEBHOOK_EVENT_TYPES = [
3429
3637
  "message.sent",
3430
3638
  "message.failed",
@@ -3468,23 +3676,23 @@ var WEBHOOK_EVENT_TYPES = [
3468
3676
  "template.updated",
3469
3677
  "template.deleted"
3470
3678
  ];
3471
- var WebhookEventType = z13.enum(WEBHOOK_EVENT_TYPES);
3472
- var MessageEventBase = z13.object({
3679
+ var WebhookEventType = z14.enum(WEBHOOK_EVENT_TYPES);
3680
+ var MessageEventBase = z14.object({
3473
3681
  message_id: Id,
3474
3682
  mailing_id: Id.nullable(),
3475
3683
  mailing_metadata: MailingMetadata.nullable(),
3476
3684
  recipient_id: Id.nullable(),
3477
3685
  contact_id: Id.nullable(),
3478
- external_id: z13.string().nullable(),
3686
+ external_id: z14.string().nullable(),
3479
3687
  email: Email,
3480
- subject: z13.string(),
3688
+ subject: z14.string(),
3481
3689
  topic: Slug.nullable(),
3482
- provider_message_id: z13.string().nullable(),
3483
- is_test: z13.boolean()
3690
+ provider_message_id: z14.string().nullable(),
3691
+ is_test: z14.boolean()
3484
3692
  });
3485
3693
  var MessageSentData = MessageEventBase.extend({
3486
3694
  /** The final HTML as sent, so the client can archive it beside its own records. */
3487
- html: z13.string(),
3695
+ html: z14.string(),
3488
3696
  sent_at: Timestamp,
3489
3697
  /**
3490
3698
  * The choice each insertion made (see `Message.insertions`); absent or null
@@ -3495,20 +3703,20 @@ var MessageSentData = MessageEventBase.extend({
3495
3703
  insertions: InsertionChoices.nullish()
3496
3704
  });
3497
3705
  var MessageFailedData = MessageEventBase.extend({
3498
- error: z13.string(),
3706
+ error: z14.string(),
3499
3707
  /** False when the provider rejected permanently; the recipient will not be retried. */
3500
- retryable: z13.boolean(),
3708
+ retryable: z14.boolean(),
3501
3709
  failed_at: Timestamp
3502
3710
  });
3503
3711
  var UNSUBSCRIBE_SOURCES = ["hosted_page", "one_click", "api", "dashboard", "signup_form"];
3504
- var ContactUnsubscribedData = z13.object({
3712
+ var ContactUnsubscribedData = z14.object({
3505
3713
  contact_id: Id.nullable(),
3506
- external_id: z13.string().nullable(),
3714
+ external_id: z14.string().nullable(),
3507
3715
  email: Email,
3508
3716
  /** The topic unsubscribed from; null means every topic. */
3509
3717
  topic: Slug.nullable(),
3510
3718
  mailing_id: Id.nullable(),
3511
- source: z13.enum(UNSUBSCRIBE_SOURCES),
3719
+ source: z14.enum(UNSUBSCRIBE_SOURCES),
3512
3720
  unsubscribed_at: Timestamp
3513
3721
  });
3514
3722
  var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: true }).extend({
@@ -3517,142 +3725,142 @@ var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: tr
3517
3725
  * breaker undid a `bounced` block it judged false (a `contact.bounced` for the
3518
3726
  * same address and mailing went out before); `topic` is null.
3519
3727
  */
3520
- source: z13.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
3728
+ source: z14.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
3521
3729
  resubscribed_at: Timestamp
3522
3730
  });
3523
- var ContactBouncedData = z13.object({
3731
+ var ContactBouncedData = z14.object({
3524
3732
  contact_id: Id.nullable(),
3525
- external_id: z13.string().nullable(),
3733
+ external_id: z14.string().nullable(),
3526
3734
  email: Email,
3527
3735
  /** `bounced` for a hard bounce, `complained` for a spam complaint. */
3528
- reason: z13.enum(["bounced", "complained"]),
3736
+ reason: z14.enum(["bounced", "complained"]),
3529
3737
  message_id: Id.nullable(),
3530
- diagnostic: z13.string().nullable(),
3738
+ diagnostic: z14.string().nullable(),
3531
3739
  bounced_at: Timestamp
3532
3740
  });
3533
- var MailingFinishedData = z13.object({
3741
+ var MailingFinishedData = z14.object({
3534
3742
  mailing_id: Id,
3535
3743
  mailing_metadata: MailingMetadata,
3536
- status: z13.enum(["sent", "partially_failed", "cancelled"]),
3744
+ status: z14.enum(["sent", "partially_failed", "cancelled"]),
3537
3745
  counts: MailingCounts,
3538
3746
  finished_at: Timestamp
3539
3747
  });
3540
- var ContactSubscribedData = z13.object({
3748
+ var ContactSubscribedData = z14.object({
3541
3749
  contact_id: Id,
3542
- external_id: z13.string().nullable(),
3750
+ external_id: z14.string().nullable(),
3543
3751
  email: Email,
3544
- topics: z13.array(Slug),
3545
- source: z13.enum(["signup_form", "api", "dashboard", "automation"]),
3752
+ topics: z14.array(Slug),
3753
+ source: z14.enum(["signup_form", "api", "dashboard", "automation"]),
3546
3754
  signup_form_id: Id.nullable(),
3547
- signup_form_version: z13.number().int().min(1).nullable(),
3755
+ signup_form_version: z14.number().int().min(1).nullable(),
3548
3756
  subscribed_at: Timestamp
3549
3757
  });
3550
- var ImportFinishedData = z13.object({
3758
+ var ImportFinishedData = z14.object({
3551
3759
  import_id: Id,
3552
- status: z13.enum(["completed", "cancelled", "failed"]),
3760
+ status: z14.enum(["completed", "cancelled", "failed"]),
3553
3761
  result: ImportReport.nullable(),
3554
- error: z13.string().nullable(),
3762
+ error: z14.string().nullable(),
3555
3763
  finished_at: Timestamp
3556
3764
  });
3557
- var MailingScheduledData = z13.object({
3765
+ var MailingScheduledData = z14.object({
3558
3766
  mailing_id: Id,
3559
3767
  mailing_metadata: MailingMetadata,
3560
3768
  scheduled_at: Timestamp.nullable()
3561
3769
  });
3562
- var MailingStartedData = z13.object({
3770
+ var MailingStartedData = z14.object({
3563
3771
  mailing_id: Id,
3564
3772
  mailing_metadata: MailingMetadata,
3565
- trigger: z13.enum(["send", "schedule"]),
3566
- recipients: z13.number().int().min(0),
3773
+ trigger: z14.enum(["send", "schedule"]),
3774
+ recipients: z14.number().int().min(0),
3567
3775
  started_at: Timestamp
3568
3776
  });
3569
- var MailingScheduleFailedData = z13.object({
3777
+ var MailingScheduleFailedData = z14.object({
3570
3778
  mailing_id: Id,
3571
3779
  mailing_metadata: MailingMetadata,
3572
- code: z13.string(),
3573
- message: z13.string(),
3780
+ code: z14.string(),
3781
+ message: z14.string(),
3574
3782
  failed_at: Timestamp
3575
3783
  });
3576
- var MailingAbWinnerSelectedData = z13.object({
3784
+ var MailingAbWinnerSelectedData = z14.object({
3577
3785
  mailing_id: Id,
3578
3786
  mailing_metadata: MailingMetadata,
3579
- winner: z13.string(),
3580
- decided_by: z13.enum(["metric", "manual"]),
3581
- variants: z13.array(VariantAnalytics),
3787
+ winner: z14.string(),
3788
+ decided_by: z14.enum(["metric", "manual"]),
3789
+ variants: z14.array(VariantAnalytics),
3582
3790
  decided_at: Timestamp
3583
3791
  });
3584
- var ContactTaggedData = z13.object({
3792
+ var ContactTaggedData = z14.object({
3585
3793
  contact_id: Id,
3586
- external_id: z13.string().nullable(),
3794
+ external_id: z14.string().nullable(),
3587
3795
  email: Email,
3588
3796
  /** Only the tags the contact did not already have. */
3589
- tags: z13.array(Slug).min(1),
3590
- source: z13.enum(["api", "dashboard", "signup_form", "import", "automation"]),
3797
+ tags: z14.array(Slug).min(1),
3798
+ source: z14.enum(["api", "dashboard", "signup_form", "import", "automation"]),
3591
3799
  tagged_at: Timestamp
3592
3800
  });
3593
- var ContactUpdatedData = z13.object({
3801
+ var ContactUpdatedData = z14.object({
3594
3802
  contact_id: Id,
3595
- external_id: z13.string().nullable(),
3803
+ external_id: z14.string().nullable(),
3596
3804
  email: Email,
3597
- changed: z13.array(z13.string()).min(1),
3805
+ changed: z14.array(z14.string()).min(1),
3598
3806
  properties: Properties,
3599
- source: z13.enum(["api", "dashboard", "signup_form", "import", "automation"]),
3807
+ source: z14.enum(["api", "dashboard", "signup_form", "import", "automation"]),
3600
3808
  updated_at: Timestamp
3601
3809
  });
3602
- var AutomationRunEventBase = z13.object({
3810
+ var AutomationRunEventBase = z14.object({
3603
3811
  automation_id: Id,
3604
- automation_name: z13.string(),
3812
+ automation_name: z14.string(),
3605
3813
  run_id: Id,
3606
- version: z13.number().int().min(1),
3814
+ version: z14.number().int().min(1),
3607
3815
  contact_id: Id,
3608
- external_id: z13.string().nullable(),
3816
+ external_id: z14.string().nullable(),
3609
3817
  email: Email
3610
3818
  });
3611
3819
  var AutomationRunStartedData = AutomationRunEventBase.extend({
3612
3820
  /** What let them in: a trigger kind, or `manual` for an explicit enrolment. */
3613
- trigger_kind: z13.string(),
3821
+ trigger_kind: z14.string(),
3614
3822
  entered_at: Timestamp
3615
3823
  });
3616
3824
  var AutomationRunCompletedData = AutomationRunEventBase.extend({
3617
- last_step_id: z13.string().nullable(),
3825
+ last_step_id: z14.string().nullable(),
3618
3826
  completed_at: Timestamp
3619
3827
  });
3620
3828
  var AutomationRunExitedData = AutomationRunEventBase.extend({
3621
3829
  reason: AutomationEndReason,
3622
- step_id: z13.string().nullable(),
3830
+ step_id: z14.string().nullable(),
3623
3831
  exited_at: Timestamp
3624
3832
  });
3625
3833
  var AutomationRunFailedData = AutomationRunEventBase.extend({
3626
- reason: z13.string(),
3627
- step_id: z13.string().nullable(),
3834
+ reason: z14.string(),
3835
+ step_id: z14.string().nullable(),
3628
3836
  failed_at: Timestamp
3629
3837
  });
3630
3838
  var AutomationWebhookData = AutomationRunEventBase.extend({
3631
- step_id: z13.string(),
3839
+ step_id: z14.string(),
3632
3840
  /** The step's own label, when it was given one, so a receiver can branch on a name. */
3633
- step_label: z13.string().nullable(),
3841
+ step_label: z14.string().nullable(),
3634
3842
  /** Whatever the step carries, verbatim. Null when it carries nothing. */
3635
3843
  payload: JsonValue.nullable(),
3636
3844
  fired_at: Timestamp
3637
3845
  });
3638
- var TemplateEventBase = z13.object({
3846
+ var TemplateEventBase = z14.object({
3639
3847
  template_id: Id,
3640
- name: z13.string().min(1).max(200),
3641
- version: z13.number().int().min(1),
3642
- source: z13.enum(["api", "dashboard", "mjml_import"])
3848
+ name: z14.string().min(1).max(200),
3849
+ version: z14.number().int().min(1),
3850
+ source: z14.enum(["api", "dashboard", "mjml_import"])
3643
3851
  });
3644
3852
  var TemplateCreatedData = TemplateEventBase.extend({ created_at: Timestamp });
3645
- var TemplateUpdatedData = TemplateEventBase.extend({ archived: z13.boolean(), updated_at: Timestamp });
3853
+ var TemplateUpdatedData = TemplateEventBase.extend({ archived: z14.boolean(), updated_at: Timestamp });
3646
3854
  var TemplateDeletedData = TemplateEventBase.extend({ deleted_at: Timestamp });
3647
- var envelope = (type, data) => z13.object({
3855
+ var envelope = (type, data) => z14.object({
3648
3856
  /** Unique per event: a receiver deduplicates on it (deliveries may repeat). */
3649
3857
  id: Id,
3650
- type: z13.literal(type),
3858
+ type: z14.literal(type),
3651
3859
  created_at: Timestamp,
3652
3860
  workspace_id: Id,
3653
3861
  data
3654
3862
  });
3655
- var WebhookEvent = z13.discriminatedUnion("type", [
3863
+ var WebhookEvent = z14.discriminatedUnion("type", [
3656
3864
  envelope("message.sent", MessageSentData),
3657
3865
  envelope("message.failed", MessageFailedData),
3658
3866
  envelope("contact.unsubscribed", ContactUnsubscribedData),
@@ -3676,16 +3884,16 @@ var WebhookEvent = z13.discriminatedUnion("type", [
3676
3884
  envelope("template.updated", TemplateUpdatedData),
3677
3885
  envelope("template.deleted", TemplateDeletedData)
3678
3886
  ]);
3679
- var WebhookEndpoint = z13.object({
3887
+ var WebhookEndpoint = z14.object({
3680
3888
  id: Id,
3681
- url: z13.string().url(),
3682
- description: z13.string().max(500).nullable(),
3683
- events: z13.array(WebhookEventType).min(1),
3684
- enabled: z13.boolean(),
3889
+ url: z14.string().url(),
3890
+ description: z14.string().max(500).nullable(),
3891
+ events: z14.array(WebhookEventType).min(1),
3892
+ enabled: z14.boolean(),
3685
3893
  created_at: Timestamp,
3686
3894
  updated_at: Timestamp
3687
3895
  });
3688
- var WebhookUrl = z13.string().url().refine((u) => {
3896
+ var WebhookUrl = z14.string().url().refine((u) => {
3689
3897
  try {
3690
3898
  const url = new URL(u);
3691
3899
  if (url.protocol === "https:") return true;
@@ -3694,35 +3902,35 @@ var WebhookUrl = z13.string().url().refine((u) => {
3694
3902
  return false;
3695
3903
  }
3696
3904
  }, "must be https (http only for localhost)");
3697
- var WebhookEndpointCreate = z13.object({
3905
+ var WebhookEndpointCreate = z14.object({
3698
3906
  url: WebhookUrl,
3699
- description: z13.string().max(500).optional(),
3700
- events: z13.array(WebhookEventType).min(1),
3701
- enabled: z13.boolean().optional()
3907
+ description: z14.string().max(500).optional(),
3908
+ events: z14.array(WebhookEventType).min(1),
3909
+ enabled: z14.boolean().optional()
3702
3910
  });
3703
- var WebhookEndpointUpdate = z13.object({
3911
+ var WebhookEndpointUpdate = z14.object({
3704
3912
  url: WebhookUrl,
3705
- description: z13.string().max(500).nullable(),
3706
- events: z13.array(WebhookEventType).min(1),
3707
- enabled: z13.boolean()
3913
+ description: z14.string().max(500).nullable(),
3914
+ events: z14.array(WebhookEventType).min(1),
3915
+ enabled: z14.boolean()
3708
3916
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
3709
- var WebhookEndpointWithSecret = z13.object({
3917
+ var WebhookEndpointWithSecret = z14.object({
3710
3918
  endpoint: WebhookEndpoint,
3711
- secret: z13.string().min(32)
3919
+ secret: z14.string().min(32)
3712
3920
  });
3713
3921
  var WEBHOOK_DELIVERY_STATUSES = ["pending", "succeeded", "failed"];
3714
- var WebhookDeliveryStatus = z13.enum(WEBHOOK_DELIVERY_STATUSES);
3922
+ var WebhookDeliveryStatus = z14.enum(WEBHOOK_DELIVERY_STATUSES);
3715
3923
  var WEBHOOK_MAX_ATTEMPTS = 8;
3716
3924
  var WEBHOOK_RETRY_DELAYS_SECONDS = [30, 120, 600, 1800, 3600, 7200, 21600];
3717
- var WebhookDelivery = z13.object({
3925
+ var WebhookDelivery = z14.object({
3718
3926
  id: Id,
3719
3927
  endpoint_id: Id,
3720
3928
  event_id: Id,
3721
3929
  event_type: WebhookEventType,
3722
3930
  status: WebhookDeliveryStatus,
3723
- attempts: z13.number().int().min(0),
3724
- last_status_code: z13.number().int().min(100).max(599).nullable(),
3725
- last_error: z13.string().nullable(),
3931
+ attempts: z14.number().int().min(0),
3932
+ last_status_code: z14.number().int().min(100).max(599).nullable(),
3933
+ last_error: z14.string().nullable(),
3726
3934
  next_attempt_at: Timestamp.nullable(),
3727
3935
  delivered_at: Timestamp.nullable(),
3728
3936
  created_at: Timestamp
@@ -3731,7 +3939,7 @@ var WebhookDeliveryListQuery = PageQuery.extend({
3731
3939
  status: WebhookDeliveryStatus.optional(),
3732
3940
  event_type: WebhookEventType.optional()
3733
3941
  });
3734
- var WebhookDeliveryParams = z13.object({ id: Id, delivery_id: Id });
3942
+ var WebhookDeliveryParams = z14.object({ id: Id, delivery_id: Id });
3735
3943
 
3736
3944
  // src/webhook-signing.ts
3737
3945
  var WEBHOOK_SIGNATURE_HEADER = "x-mail-signature";
@@ -3798,79 +4006,79 @@ async function verifyWebhook(input) {
3798
4006
  }
3799
4007
 
3800
4008
  // src/billing.ts
3801
- import { z as z14 } from "zod";
4009
+ import { z as z15 } from "zod";
3802
4010
  var PLAN_IDS = ["free", "starter", "growth", "design_partner"];
3803
- var PlanId = z14.enum(PLAN_IDS);
3804
- var PlanLimits = z14.object({
3805
- monthly_messages: z14.number().int().min(0).nullable(),
3806
- contacts: z14.number().int().min(0).nullable(),
3807
- members: z14.number().int().min(1).nullable(),
3808
- providers: z14.number().int().min(1).nullable(),
3809
- webhook_endpoints: z14.number().int().min(0).nullable(),
4011
+ var PlanId = z15.enum(PLAN_IDS);
4012
+ var PlanLimits = z15.object({
4013
+ monthly_messages: z15.number().int().min(0).nullable(),
4014
+ contacts: z15.number().int().min(0).nullable(),
4015
+ members: z15.number().int().min(1).nullable(),
4016
+ providers: z15.number().int().min(1).nullable(),
4017
+ webhook_endpoints: z15.number().int().min(0).nullable(),
3810
4018
  /** Automations that may be live (active or paused) at once (A1). */
3811
- active_automations: z14.number().int().min(0).nullable(),
4019
+ active_automations: z15.number().int().min(0).nullable(),
3812
4020
  /** Steps one automation may hold. Null is the flow's own cap, not unlimited. */
3813
- automation_steps: z14.number().int().min(1).nullable()
4021
+ automation_steps: z15.number().int().min(1).nullable()
3814
4022
  });
3815
- var PlanFeatures = z14.object({
4023
+ var PlanFeatures = z15.object({
3816
4024
  /** A/B tests of subject and content on a mailing (S4). */
3817
- ab_testing: z14.boolean(),
4025
+ ab_testing: z15.boolean(),
3818
4026
  /** Open and click tracking, still off until a workspace turns it on (`settings.tracking_enabled`). */
3819
- tracking: z14.boolean(),
4027
+ tracking: z15.boolean(),
3820
4028
  /** Sending and hosting pages on the workspace's own domain (a later phase). */
3821
- custom_domains: z14.boolean(),
4029
+ custom_domains: z15.boolean(),
3822
4030
  /** Automations: flows a person walks through step by step (A1). */
3823
- automations: z14.boolean()
4031
+ automations: z15.boolean()
3824
4032
  });
3825
4033
  var PLAN_FEATURES = ["ab_testing", "tracking", "custom_domains", "automations"];
3826
- var Plan = z14.object({
4034
+ var Plan = z15.object({
3827
4035
  id: PlanId,
3828
- name: z14.string().min(1),
4036
+ name: z15.string().min(1),
3829
4037
  /** Price in the smallest currency unit per month; null for plans not sold. */
3830
- monthly_price_cents: z14.number().int().min(0).nullable(),
3831
- currency: z14.string().length(3),
4038
+ monthly_price_cents: z15.number().int().min(0).nullable(),
4039
+ currency: z15.string().length(3),
3832
4040
  limits: PlanLimits,
3833
4041
  features: PlanFeatures
3834
4042
  });
3835
- var CatalogPlan = Plan.extend({ sellable: z14.boolean() });
3836
- var Subscription = z14.object({
4043
+ var CatalogPlan = Plan.extend({ sellable: z15.boolean() });
4044
+ var Subscription = z15.object({
3837
4045
  workspace_id: Id,
3838
4046
  plan: PlanId,
3839
- status: z14.enum(["active", "trialing", "past_due", "cancelled"]),
4047
+ status: z15.enum(["active", "trialing", "past_due", "cancelled"]),
3840
4048
  current_period_start: Timestamp,
3841
4049
  current_period_end: Timestamp,
3842
- cancel_at_period_end: z14.boolean(),
4050
+ cancel_at_period_end: z15.boolean(),
3843
4051
  /**
3844
4052
  * A design partner outside billing (plan `design_partner`, no limits, no
3845
4053
  * checkout). Set only by an operator, never through the API.
3846
4054
  */
3847
- billing_exempt: z14.boolean()
4055
+ billing_exempt: z15.boolean()
3848
4056
  });
3849
4057
  var USAGE_METRICS = ["messages", "contacts", "members", "providers", "webhook_endpoints", "active_automations"];
3850
- var UsageMetric = z14.enum(USAGE_METRICS);
4058
+ var UsageMetric = z15.enum(USAGE_METRICS);
3851
4059
  var USAGE_WARNING_RATIO = 0.8;
3852
- var UsageWarning = z14.object({
4060
+ var UsageWarning = z15.object({
3853
4061
  metric: UsageMetric,
3854
- used: z14.number().int().min(0),
3855
- limit: z14.number().int().min(0),
4062
+ used: z15.number().int().min(0),
4063
+ limit: z15.number().int().min(0),
3856
4064
  /** `approaching`: at or above USAGE_WARNING_RATIO of the limit; `reached`: at or above the limit. */
3857
- level: z14.enum(["approaching", "reached"])
4065
+ level: z15.enum(["approaching", "reached"])
3858
4066
  });
3859
- var Usage = z14.object({
4067
+ var Usage = z15.object({
3860
4068
  plan: PlanId,
3861
4069
  period_start: Timestamp,
3862
4070
  period_end: Timestamp,
3863
- metrics: z14.record(UsageMetric, z14.object({ used: z14.number().int().min(0), limit: z14.number().int().min(0).nullable() })),
3864
- warnings: z14.array(UsageWarning)
4071
+ metrics: z15.record(UsageMetric, z15.object({ used: z15.number().int().min(0), limit: z15.number().int().min(0).nullable() })),
4072
+ warnings: z15.array(UsageWarning)
3865
4073
  });
3866
- var CheckoutRequest = z14.object({
3867
- plan: z14.enum(["starter", "growth"]),
3868
- success_url: z14.string().url(),
3869
- cancel_url: z14.string().url()
4074
+ var CheckoutRequest = z15.object({
4075
+ plan: z15.enum(["starter", "growth"]),
4076
+ success_url: z15.string().url(),
4077
+ cancel_url: z15.string().url()
3870
4078
  });
3871
- var CheckoutSession = z14.object({ url: z14.string().url() });
3872
- var PortalRequest = z14.object({ return_url: z14.string().url() });
3873
- var PortalSession = z14.object({ url: z14.string().url() });
4079
+ var CheckoutSession = z15.object({ url: z15.string().url() });
4080
+ var PortalRequest = z15.object({ return_url: z15.string().url() });
4081
+ var PortalSession = z15.object({ url: z15.string().url() });
3874
4082
  var USAGE_WARNING_HEADER = "x-mail-usage-warning";
3875
4083
  function formatUsageWarningHeader(warnings) {
3876
4084
  if (warnings.length === 0) return null;
@@ -3890,7 +4098,7 @@ function parseUsageWarningHeader(value) {
3890
4098
  }
3891
4099
 
3892
4100
  // src/routes.ts
3893
- import { z as z15 } from "zod";
4101
+ import { z as z16 } from "zod";
3894
4102
  var list = (item) => page(item);
3895
4103
  var foundationRoutes = {
3896
4104
  "workspaces.create": {
@@ -4047,6 +4255,25 @@ var templateRoutes = {
4047
4255
  access: "write",
4048
4256
  phase: "S1"
4049
4257
  },
4258
+ /**
4259
+ * The sending app declares what the template receives (see
4260
+ * `template-inputs.ts`). Replaces the stored declaration whole; the same
4261
+ * declaration again is a no-op (`changed: false`). Creates no template
4262
+ * version and takes no `base_version`, so it never conflicts with an edit.
4263
+ * An API key only (`send` or `full`): the declaration is the app's statement
4264
+ * about its own code, so a dashboard member is refused with `forbidden`, a
4265
+ * rule the access levels cannot express and the service enforces itself.
4266
+ */
4267
+ "templates.declareInputs": {
4268
+ method: "PUT",
4269
+ path: "/v1/templates/:id/inputs",
4270
+ params: IdParams,
4271
+ body: TemplateInputsDeclaration,
4272
+ response: TemplateInputsDeclared,
4273
+ status: 200,
4274
+ access: "write",
4275
+ phase: "S1"
4276
+ },
4050
4277
  "templates.delete": {
4051
4278
  method: "DELETE",
4052
4279
  path: "/v1/templates/:id",
@@ -4098,7 +4325,7 @@ var templateRoutes = {
4098
4325
  path: "/v1/templates/:id/export",
4099
4326
  params: IdParams,
4100
4327
  query: TemplateExportQuery,
4101
- response: z15.string(),
4328
+ response: z16.string(),
4102
4329
  responseType: "text",
4103
4330
  status: 200,
4104
4331
  access: "read",
@@ -4422,7 +4649,7 @@ var sendingRoutes = {
4422
4649
  path: "/v1/mailings/:id/export",
4423
4650
  params: IdParams,
4424
4651
  query: MailingExportQuery,
4425
- response: z15.string(),
4652
+ response: z16.string(),
4426
4653
  responseType: "text",
4427
4654
  status: 200,
4428
4655
  access: "read",
@@ -4655,7 +4882,7 @@ var platformRoutes = {
4655
4882
  "contactProperties.list": {
4656
4883
  method: "GET",
4657
4884
  path: "/v1/contact-properties",
4658
- response: z15.object({ data: z15.array(ContactPropertyDefinition) }),
4885
+ response: z16.object({ data: z16.array(ContactPropertyDefinition) }),
4659
4886
  status: 200,
4660
4887
  access: "read",
4661
4888
  phase: "S4"
@@ -4954,7 +5181,7 @@ var billingRoutes = {
4954
5181
  "billing.plans": {
4955
5182
  method: "GET",
4956
5183
  path: "/v1/billing/plans",
4957
- response: z15.object({ data: z15.array(CatalogPlan) }),
5184
+ response: z16.object({ data: z16.array(CatalogPlan) }),
4958
5185
  status: 200,
4959
5186
  access: "read",
4960
5187
  phase: "S5"
@@ -5096,7 +5323,7 @@ var automationRoutes = {
5096
5323
  method: "POST",
5097
5324
  path: "/v1/automations/:id/pause",
5098
5325
  params: IdParams,
5099
- body: z15.object({}).strict(),
5326
+ body: z16.object({}).strict(),
5100
5327
  response: Automation,
5101
5328
  status: 200,
5102
5329
  access: "write",
@@ -5106,7 +5333,7 @@ var automationRoutes = {
5106
5333
  method: "POST",
5107
5334
  path: "/v1/automations/:id/resume",
5108
5335
  params: IdParams,
5109
- body: z15.object({}).strict(),
5336
+ body: z16.object({}).strict(),
5110
5337
  response: Automation,
5111
5338
  status: 200,
5112
5339
  access: "write",
@@ -5116,7 +5343,7 @@ var automationRoutes = {
5116
5343
  method: "POST",
5117
5344
  path: "/v1/automations/:id/archive",
5118
5345
  params: IdParams,
5119
- body: z15.object({}).strict(),
5346
+ body: z16.object({}).strict(),
5120
5347
  response: Automation,
5121
5348
  status: 200,
5122
5349
  access: "write",
@@ -5495,6 +5722,13 @@ export {
5495
5722
  MAX_STEPS,
5496
5723
  MAX_STEP_VISITS,
5497
5724
  MAX_SUBJECT_LENGTH,
5725
+ MAX_TEMPLATE_INPUTS,
5726
+ MAX_TEMPLATE_INPUTS_APP_LENGTH,
5727
+ MAX_TEMPLATE_INPUTS_SEEN,
5728
+ MAX_TEMPLATE_INPUT_EXAMPLE_LENGTH,
5729
+ MAX_TEMPLATE_INPUT_LABEL_LENGTH,
5730
+ MAX_TEMPLATE_INPUT_NOTE_LENGTH,
5731
+ MAX_TEMPLATE_INPUT_VALUES,
5498
5732
  MAX_TEMPLATE_TRANSLATIONS,
5499
5733
  MAX_TRIGGERS,
5500
5734
  MEMBER_ROLES,
@@ -5589,6 +5823,7 @@ export {
5589
5823
  RecipientStatus,
5590
5824
  RemoteImage,
5591
5825
  ResendSigningSecret,
5826
+ SERVICE_FILLED_MERGE_FIELDS,
5592
5827
  SIGNUP_FORM_FIELDS,
5593
5828
  SKIP_REASONS,
5594
5829
  SMTP_SECURITY,
@@ -5618,6 +5853,8 @@ export {
5618
5853
  SuppressionCreate,
5619
5854
  SuppressionListQuery,
5620
5855
  SuppressionReason,
5856
+ TEMPLATE_INPUT_KINDS,
5857
+ TEMPLATE_INPUT_PROBLEM_REASONS,
5621
5858
  TEMPLATE_LANGUAGE_STATUSES,
5622
5859
  TERMINAL_MAILING_STATUSES,
5623
5860
  Tag,
@@ -5634,6 +5871,16 @@ export {
5634
5871
  TemplateImportPreview,
5635
5872
  TemplateImportPreviewRequest,
5636
5873
  TemplateImportResult,
5874
+ TemplateInput,
5875
+ TemplateInputMap,
5876
+ TemplateInputName,
5877
+ TemplateInputSeen,
5878
+ TemplateInputSource,
5879
+ TemplateInputValue,
5880
+ TemplateInputs,
5881
+ TemplateInputsDeclaration,
5882
+ TemplateInputsDeclared,
5883
+ TemplateInputsSeen,
5637
5884
  TemplateLanguageStatus,
5638
5885
  TemplateListQuery,
5639
5886
  TemplatePreheader,
@@ -5787,9 +6034,14 @@ export {
5787
6034
  renameInsertionChecked,
5788
6035
  renameInsertionChoice,
5789
6036
  renameInsertionChoiceChecked,
6037
+ renameInsertionEverywhere,
6038
+ renameInsertionPlacements,
6039
+ renameTokenInDocument,
6040
+ renameTokenInText,
5790
6041
  resolveInsertions,
5791
6042
  restorePatch,
5792
6043
  routes,
6044
+ sameJson,
5793
6045
  sampleMergeValue,
5794
6046
  saveDemotions,
5795
6047
  sendingRoutes,
@@ -5801,6 +6053,8 @@ export {
5801
6053
  stepTargets,
5802
6054
  storedTemplateLine,
5803
6055
  stronglyConnected,
6056
+ templateInputDrift,
6057
+ templateInputProblems,
5804
6058
  templateRoutes,
5805
6059
  testGroupSize,
5806
6060
  tightLoops,