@marlinjai/mail-contract 0.10.0 → 0.12.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.
package/dist/index.js CHANGED
@@ -209,6 +209,7 @@ __export(index_exports, {
209
209
  InviteListQuery: () => InviteListQuery,
210
210
  InviteStatus: () => InviteStatus,
211
211
  JsonValue: () => JsonValue,
212
+ LETTER_ONLY_MERGE_FIELDS: () => LETTER_ONLY_MERGE_FIELDS,
212
213
  LETTER_RECIPIENT_REFUSAL: () => LETTER_RECIPIENT_REFUSAL,
213
214
  LIST_UNSUBSCRIBE_POST_VALUE: () => LIST_UNSUBSCRIBE_POST_VALUE,
214
215
  LOCALE_TAG_PATTERN: () => LOCALE_TAG_PATTERN,
@@ -277,7 +278,10 @@ __export(index_exports, {
277
278
  MailingLanguageReport: () => MailingLanguageReport,
278
279
  MailingLanguageStatus: () => MailingLanguageStatus,
279
280
  MailingListQuery: () => MailingListQuery,
281
+ MailingMerge: () => MailingMerge,
280
282
  MailingMetadata: () => MailingMetadata,
283
+ MailingResolveRequest: () => MailingResolveRequest,
284
+ MailingResolveResult: () => MailingResolveResult,
281
285
  MailingRetryFailedRequest: () => MailingRetryFailedRequest,
282
286
  MailingScheduleFailedData: () => MailingScheduleFailedData,
283
287
  MailingScheduleRequest: () => MailingScheduleRequest,
@@ -302,6 +306,8 @@ __export(index_exports, {
302
306
  MessageOutcome: () => MessageOutcome,
303
307
  MessageSentData: () => MessageSentData,
304
308
  MessageSummary: () => MessageSummary,
309
+ MessageValues: () => MessageValues,
310
+ NAME_ON_BROADCAST_REFUSAL: () => NAME_ON_BROADCAST_REFUSAL,
305
311
  NotifyRecipients: () => NotifyRecipients,
306
312
  NotifyStep: () => NotifyStep,
307
313
  ON_BEHALF_OF_HEADER: () => ON_BEHALF_OF_HEADER,
@@ -337,6 +343,8 @@ __export(index_exports, {
337
343
  REQUEST_ID_HEADER: () => REQUEST_ID_HEADER,
338
344
  RESEND_EVENT_TYPES: () => RESEND_EVENT_TYPES,
339
345
  RESERVED_MERGE_FIELDS: () => RESERVED_MERGE_FIELDS,
346
+ RESOLVE_PROBLEMS: () => RESOLVE_PROBLEMS,
347
+ RESOLVE_REJECTIONS: () => RESOLVE_REJECTIONS,
340
348
  RETRYABLE_ERRORS: () => RETRYABLE_ERRORS,
341
349
  RETRY_AFTER_HEADER: () => RETRY_AFTER_HEADER,
342
350
  RE_ENTRY_MODES: () => RE_ENTRY_MODES,
@@ -349,6 +357,9 @@ __export(index_exports, {
349
357
  RecipientStatus: () => RecipientStatus,
350
358
  RemoteImage: () => RemoteImage,
351
359
  ResendSigningSecret: () => ResendSigningSecret,
360
+ ResolveProblem: () => ResolveProblem,
361
+ ResolvedRecipient: () => ResolvedRecipient,
362
+ ResolvedValue: () => ResolvedValue,
352
363
  SERVICE_FILLED_MERGE_FIELDS: () => SERVICE_FILLED_MERGE_FIELDS,
353
364
  SIGNUP_FORM_FIELDS: () => SIGNUP_FORM_FIELDS,
354
365
  SKIP_REASONS: () => SKIP_REASONS,
@@ -385,6 +396,8 @@ __export(index_exports, {
385
396
  TEMPLATE_SORTS: () => TEMPLATE_SORTS,
386
397
  TEMPLATE_SORT_DEFAULT_ORDER: () => TEMPLATE_SORT_DEFAULT_ORDER,
387
398
  TERMINAL_MAILING_STATUSES: () => TERMINAL_MAILING_STATUSES,
399
+ TRUSTED_APPS: () => TRUSTED_APPS,
400
+ TRUSTED_APP_OPERATIONS: () => TRUSTED_APP_OPERATIONS,
388
401
  Tag: () => Tag,
389
402
  TagAssignment: () => TagAssignment,
390
403
  TagCreate: () => TagCreate,
@@ -430,15 +443,19 @@ __export(index_exports, {
430
443
  TrackingSettings: () => TrackingSettings,
431
444
  TranslationInsertion: () => TranslationInsertion,
432
445
  TranslationInsertions: () => TranslationInsertions,
446
+ TrustedApp: () => TrustedApp,
433
447
  UNSUBSCRIBE_PATH_PREFIX: () => UNSUBSCRIBE_PATH_PREFIX,
434
448
  UNSUBSCRIBE_SOURCES: () => UNSUBSCRIBE_SOURCES,
435
449
  USAGE_METRICS: () => USAGE_METRICS,
436
450
  USAGE_WARNING_HEADER: () => USAGE_WARNING_HEADER,
437
451
  USAGE_WARNING_RATIO: () => USAGE_WARNING_RATIO,
452
+ UnfilledLink: () => UnfilledLink,
438
453
  Usage: () => Usage,
439
454
  UsageMetric: () => UsageMetric,
440
455
  UsageWarning: () => UsageWarning,
456
+ VALUE_LAYERS: () => VALUE_LAYERS,
441
457
  ValidationIssue: () => ValidationIssue,
458
+ ValueLayer: () => ValueLayer,
442
459
  VariantAnalytics: () => VariantAnalytics,
443
460
  WEBHOOK_DELIVERY_STATUSES: () => WEBHOOK_DELIVERY_STATUSES,
444
461
  WEBHOOK_EVENT_ID_HEADER: () => WEBHOOK_EVENT_ID_HEADER,
@@ -502,6 +519,7 @@ __export(index_exports, {
502
519
  editMainInsertions: () => editMainInsertions,
503
520
  effectivePreviewPicks: () => effectivePreviewPicks,
504
521
  emptyFlow: () => emptyFlow,
522
+ emptyLinkValues: () => emptyLinkValues,
505
523
  errorBody: () => errorBody,
506
524
  escapeMergeHtml: () => escapeMergeHtml,
507
525
  exportFilename: () => exportFilename,
@@ -532,6 +550,8 @@ __export(index_exports, {
532
550
  languageInsertions: () => languageInsertions,
533
551
  languageName: () => languageName,
534
552
  languageTabs: () => languageTabs,
553
+ letterOnlyValues: () => letterOnlyValues,
554
+ linkTokens: () => linkTokens,
535
555
  mainInsertionText: () => mainInsertionText,
536
556
  matchLocale: () => matchLocale,
537
557
  matchRoute: () => matchRoute,
@@ -552,6 +572,8 @@ __export(index_exports, {
552
572
  previewInsertions: () => previewInsertions,
553
573
  previewPersonalization: () => previewPersonalization,
554
574
  primaryLanguage: () => primaryLanguage,
575
+ printedFields: () => printedFields,
576
+ rawMergeValue: () => rawMergeValue,
555
577
  reachable: () => reachable,
556
578
  readyWithoutInsertions: () => readyWithoutInsertions,
557
579
  readyWithoutSubject: () => readyWithoutSubject,
@@ -568,6 +590,7 @@ __export(index_exports, {
568
590
  renameTokenInDocument: () => renameTokenInDocument,
569
591
  renameTokenInText: () => renameTokenInText,
570
592
  resolveInsertions: () => resolveInsertions,
593
+ resolveValue: () => resolveValue,
571
594
  restorePatch: () => restorePatch,
572
595
  routes: () => routes,
573
596
  sameJson: () => sameJson,
@@ -591,9 +614,12 @@ __export(index_exports, {
591
614
  translationInsertionProblems: () => translationInsertionProblems,
592
615
  translationTextFromInput: () => translationTextFromInput,
593
616
  triggerKey: () => triggerKey,
617
+ trustedAppMayCall: () => trustedAppMayCall,
594
618
  unknownRefusedInsertions: () => unknownRefusedInsertions,
595
619
  unplacedInsertions: () => unplacedInsertions,
596
620
  validateAutomation: () => validateAutomation,
621
+ valueNames: () => valueNames,
622
+ valuesRead: () => valuesRead,
597
623
  verifyWebhook: () => verifyWebhook
598
624
  });
599
625
  module.exports = __toCommonJS(index_exports);
@@ -677,6 +703,12 @@ var ERROR_STATUS = {
677
703
  invalid_mjml: 422,
678
704
  missing_unsubscribe_url: 422,
679
705
  mailing_not_ready: 422,
706
+ /**
707
+ * A value placed inside a link's address comes out empty for at least one
708
+ * recipient, so the mailing does not start; `details.values` lists each such
709
+ * value with how many recipients it is empty for.
710
+ */
711
+ unfilled_link: 422,
680
712
  unknown_topic: 422,
681
713
  unknown_provider: 422,
682
714
  /**
@@ -745,10 +777,10 @@ var API_VERSION_PREFIX = "/v1";
745
777
  var HEALTH_PATH = "/healthz";
746
778
 
747
779
  // src/workspace.ts
748
- var import_zod10 = require("zod");
780
+ var import_zod11 = require("zod");
749
781
 
750
782
  // src/automations.ts
751
- var import_zod9 = require("zod");
783
+ var import_zod10 = require("zod");
752
784
 
753
785
  // src/templates.ts
754
786
  var import_zod5 = require("zod");
@@ -769,11 +801,11 @@ var RESERVED_MERGE_FIELDS = {
769
801
  };
770
802
  var MERGE_FIELD_PATTERN = /\{\{\s*([a-z][a-z0-9_]*)\s*(?:\|([^}]*))?\}\}/g;
771
803
  function findMergeFields(html) {
772
- const uses = [];
804
+ const uses2 = [];
773
805
  for (const match of html.matchAll(MERGE_FIELD_PATTERN)) {
774
- uses.push({ name: match[1], fallback: match[2] === void 0 ? null : match[2].trim() });
806
+ uses2.push({ name: match[1], fallback: match[2] === void 0 ? null : match[2].trim() });
775
807
  }
776
- return uses;
808
+ return uses2;
777
809
  }
778
810
  function missingRequiredMergeFields(html) {
779
811
  const used = new Set(findMergeFields(html).map((u) => u.name));
@@ -1456,10 +1488,10 @@ function exportFilename(name, format) {
1456
1488
  }
1457
1489
 
1458
1490
  // src/platform.ts
1459
- var import_zod8 = require("zod");
1491
+ var import_zod9 = require("zod");
1460
1492
 
1461
1493
  // src/mailings.ts
1462
- var import_zod7 = require("zod");
1494
+ var import_zod8 = require("zod");
1463
1495
 
1464
1496
  // src/ab-test.ts
1465
1497
  var import_zod6 = require("zod");
@@ -1510,6 +1542,167 @@ function testGroupSize(total, fraction, variants) {
1510
1542
  return Math.min(total, Math.max(variants, Math.ceil(total * fraction)));
1511
1543
  }
1512
1544
 
1545
+ // src/values.ts
1546
+ var import_zod7 = require("zod");
1547
+ var MAX_MERGE_DEFAULTS = 50;
1548
+ var MAX_MERGE_DEFAULT_LENGTH = 2e3;
1549
+ var MergeFieldName = import_zod7.z.string().regex(/^[a-z][a-z0-9_]*$/, "a merge-field name: lowercase letters, digits and underscores, starting with a letter").max(64);
1550
+ var MergeDefaultValue = import_zod7.z.union([import_zod7.z.string().max(MAX_MERGE_DEFAULT_LENGTH), import_zod7.z.number().finite(), import_zod7.z.boolean()]);
1551
+ var MailingMerge = import_zod7.z.record(MergeFieldName, MergeDefaultValue).refine((m) => Object.keys(m).length <= MAX_MERGE_DEFAULTS, `at most ${MAX_MERGE_DEFAULTS} values on a mailing`).refine((m) => !Object.keys(m).some((k) => SERVICE_FILLED_MERGE_FIELDS.includes(k)), {
1552
+ message: `the service fills ${SERVICE_FILLED_MERGE_FIELDS.join(" and ")}; a mailing cannot set them`
1553
+ });
1554
+ var LETTER_ONLY_MERGE_FIELDS = ["first_name", "last_name"];
1555
+ var NAME_ON_BROADCAST_REFUSAL = "name_on_broadcast";
1556
+ function letterOnlyValues(merge) {
1557
+ return LETTER_ONLY_MERGE_FIELDS.filter((name) => ownEntry(merge, name) !== void 0);
1558
+ }
1559
+ var VALUE_LAYERS = ["recipient", "mailing", "contact", "workspace", "fallback", "empty"];
1560
+ var ValueLayer = import_zod7.z.enum(VALUE_LAYERS);
1561
+ var ResolvedValue = import_zod7.z.object({ text: import_zod7.z.string(), layer: ValueLayer });
1562
+ var MessageValues = import_zod7.z.record(ResolvedValue);
1563
+ function scalarText(value) {
1564
+ if (typeof value === "string") return value;
1565
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
1566
+ if (typeof value === "boolean") return String(value);
1567
+ return null;
1568
+ }
1569
+ function isNameField(name) {
1570
+ return name === "first_name" || name === "last_name";
1571
+ }
1572
+ function rawMergeValue(name, sources) {
1573
+ const own = ownEntry(sources.recipient, name);
1574
+ if (scalarText(own) !== null) return { value: own, layer: "recipient" };
1575
+ const held = ownEntry(sources.mailing, name);
1576
+ if (scalarText(held) !== null) return { value: held, layer: "mailing" };
1577
+ if (isNameField(name)) {
1578
+ const stored = sources.contact?.[name];
1579
+ return typeof stored === "string" ? { value: stored, layer: "contact" } : null;
1580
+ }
1581
+ const property = ownEntry(sources.contact?.properties, name);
1582
+ if (scalarText(property) !== null) return { value: property, layer: "contact" };
1583
+ const byDefault = ownEntry(sources.workspace, name);
1584
+ return scalarText(byDefault) !== null ? { value: byDefault, layer: "workspace" } : null;
1585
+ }
1586
+ function resolveValue(name, fallback, sources) {
1587
+ const found = rawMergeValue(name, sources);
1588
+ const text = found === null ? null : scalarText(found.value);
1589
+ if (found !== null && text !== null && text.trim() !== "") return { text, layer: found.layer };
1590
+ const instead = fallback?.trim() ?? "";
1591
+ return instead === "" ? { text: "", layer: "empty" } : { text: instead, layer: "fallback" };
1592
+ }
1593
+ function pattern2() {
1594
+ return new RegExp(MERGE_FIELD_PATTERN.source, "g");
1595
+ }
1596
+ function isServiceFilled(name) {
1597
+ return SERVICE_FILLED_MERGE_FIELDS.includes(name);
1598
+ }
1599
+ function uses(text) {
1600
+ return [...text.matchAll(pattern2())].map((m) => ({ name: m[1], fallback: m[2] === void 0 ? null : m[2].trim() }));
1601
+ }
1602
+ function valueNames(texts, insertions) {
1603
+ const names = [];
1604
+ const add = (name) => {
1605
+ if (!isServiceFilled(name) && !names.includes(name)) names.push(name);
1606
+ };
1607
+ for (const text of texts) {
1608
+ for (const use of uses(text ?? "")) {
1609
+ const def = ownEntry(insertions, use.name);
1610
+ if (!def) {
1611
+ add(use.name);
1612
+ continue;
1613
+ }
1614
+ add(def.by);
1615
+ for (const inner of [...Object.values(def.choices), def.filled ?? "", def.otherwise]) for (const u of uses(inner)) add(u.name);
1616
+ }
1617
+ }
1618
+ return names;
1619
+ }
1620
+ function printedFields(texts, insertions, chosen2) {
1621
+ const out = [];
1622
+ const add = (use) => {
1623
+ if (isServiceFilled(use.name)) return;
1624
+ if (!out.some((o) => o.name === use.name && o.fallback === use.fallback)) out.push(use);
1625
+ };
1626
+ for (const text of texts) {
1627
+ for (const use of uses(text ?? "")) {
1628
+ if (!ownEntry(insertions, use.name)) add(use);
1629
+ else for (const inner of uses(ownEntry(chosen2, use.name)?.text ?? "")) add(inner);
1630
+ }
1631
+ }
1632
+ return out;
1633
+ }
1634
+ function valuesRead(texts, insertions, chosen2, resolve) {
1635
+ const out = {};
1636
+ const read = (use) => {
1637
+ if (isServiceFilled(use.name)) return;
1638
+ const value = resolve(use.name, use.fallback);
1639
+ const seen = ownEntry(out, use.name);
1640
+ if (seen === void 0 || value.layer === "empty" && seen.layer !== "empty") out[use.name] = value;
1641
+ };
1642
+ for (const text of texts) {
1643
+ for (const use of uses(text ?? "")) {
1644
+ const def = ownEntry(insertions, use.name);
1645
+ if (!def) {
1646
+ read(use);
1647
+ continue;
1648
+ }
1649
+ read({ name: def.by, fallback: null });
1650
+ for (const inner of uses(ownEntry(chosen2, use.name)?.text ?? "")) read(inner);
1651
+ }
1652
+ }
1653
+ return out;
1654
+ }
1655
+ var HREF = /\bhref\s*=\s*(?:"([^"]*)"|'([^']*)')/gi;
1656
+ function linkTokens(html) {
1657
+ const out = [];
1658
+ for (const match of html.matchAll(HREF)) {
1659
+ for (const use of uses(match[1] ?? match[2] ?? "")) {
1660
+ if (isServiceFilled(use.name)) continue;
1661
+ if (!out.some((o) => o.name === use.name && o.fallback === use.fallback)) out.push(use);
1662
+ }
1663
+ }
1664
+ return out;
1665
+ }
1666
+ function emptyLinkValues(tokens, p) {
1667
+ const empty = [];
1668
+ for (const token of tokens) {
1669
+ const ins = ownEntry(p.insertions, token.name);
1670
+ const text = ins ? ins.text.replace(pattern2(), (_m, name, fallback) => p.value(name, fallback)) : p.value(token.name, token.fallback ?? void 0);
1671
+ if (text.trim() === "" && !empty.includes(token.name)) empty.push(token.name);
1672
+ }
1673
+ return empty;
1674
+ }
1675
+ var UnfilledLink = import_zod7.z.object({
1676
+ /** The value, or the insertion, that comes out empty. */
1677
+ value: import_zod7.z.string(),
1678
+ /** How many recipients it is empty for. */
1679
+ recipients: import_zod7.z.number().int().min(1)
1680
+ });
1681
+ var RESOLVE_PROBLEMS = ["unfilled_link", "empty_value", "insertion_miss"];
1682
+ var ResolveProblem = import_zod7.z.object({
1683
+ kind: import_zod7.z.enum(RESOLVE_PROBLEMS),
1684
+ severity: import_zod7.z.enum(["blocking", "note"]),
1685
+ value: import_zod7.z.string(),
1686
+ message: import_zod7.z.string()
1687
+ });
1688
+ var ResolvedRecipient = import_zod7.z.object({
1689
+ /** The recipient's index in the request; null for the reader with nothing of their own. */
1690
+ index: import_zod7.z.number().int().min(0).nullable(),
1691
+ /** The address the message would go to; null for the reader with nothing of their own. */
1692
+ email: Email.nullable(),
1693
+ /** The contact found for the recipient; null when the address has none yet (a send creates it, empty). */
1694
+ contact_id: Id.nullable(),
1695
+ /** The language version this recipient would get. */
1696
+ locale: LocaleTag,
1697
+ /** The subject line as they would read it. */
1698
+ subject: import_zod7.z.string(),
1699
+ values: MessageValues,
1700
+ /** The choice each insertion would make; null when the content has none. */
1701
+ insertions: InsertionChoices.nullable(),
1702
+ problems: import_zod7.z.array(ResolveProblem)
1703
+ });
1704
+ var RESOLVE_REJECTIONS = ["unknown_contact", "duplicate_in_batch"];
1705
+
1513
1706
  // src/mailings.ts
1514
1707
  var MAILING_STATUSES = [
1515
1708
  "draft",
@@ -1520,9 +1713,9 @@ var MAILING_STATUSES = [
1520
1713
  "partially_failed",
1521
1714
  "cancelled"
1522
1715
  ];
1523
- var MailingStatus = import_zod7.z.enum(MAILING_STATUSES);
1716
+ var MailingStatus = import_zod8.z.enum(MAILING_STATUSES);
1524
1717
  var MAILING_ACTIONS = ["send", "schedule", "unschedule", "pause", "resume", "cancel", "retry-failed"];
1525
- var MailingAction = import_zod7.z.enum(MAILING_ACTIONS);
1718
+ var MailingAction = import_zod8.z.enum(MAILING_ACTIONS);
1526
1719
  var MAILING_TRANSITIONS = {
1527
1720
  draft: ["send", "schedule", "cancel"],
1528
1721
  scheduled: ["send", "schedule", "unschedule", "cancel"],
@@ -1537,23 +1730,23 @@ function canTransition(status, action) {
1537
1730
  }
1538
1731
  var EDITABLE_MAILING_STATUSES = ["draft", "scheduled"];
1539
1732
  var TERMINAL_MAILING_STATUSES = ["sent", "cancelled"];
1540
- var MailingMetadata = import_zod7.z.record(import_zod7.z.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");
1541
- var MailingCounts = import_zod7.z.object({
1542
- total: import_zod7.z.number().int().min(0),
1543
- queued: import_zod7.z.number().int().min(0),
1544
- sending: import_zod7.z.number().int().min(0),
1545
- sent: import_zod7.z.number().int().min(0),
1546
- failed: import_zod7.z.number().int().min(0),
1547
- skipped: import_zod7.z.number().int().min(0)
1733
+ var MailingMetadata = import_zod8.z.record(import_zod8.z.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");
1734
+ var MailingCounts = import_zod8.z.object({
1735
+ total: import_zod8.z.number().int().min(0),
1736
+ queued: import_zod8.z.number().int().min(0),
1737
+ sending: import_zod8.z.number().int().min(0),
1738
+ sent: import_zod8.z.number().int().min(0),
1739
+ failed: import_zod8.z.number().int().min(0),
1740
+ skipped: import_zod8.z.number().int().min(0)
1548
1741
  });
1549
1742
  var MAILING_KINDS = ["broadcast", "automation", "notification"];
1550
- var MailingKind = import_zod7.z.enum(MAILING_KINDS);
1551
- var Mailing = import_zod7.z.object({
1743
+ var MailingKind = import_zod8.z.enum(MAILING_KINDS);
1744
+ var Mailing = import_zod8.z.object({
1552
1745
  id: Id,
1553
1746
  kind: MailingKind,
1554
- name: import_zod7.z.string().max(200).nullable(),
1555
- subject: import_zod7.z.string().min(1).max(998),
1556
- preheader: import_zod7.z.string().max(500).nullable(),
1747
+ name: import_zod8.z.string().max(200).nullable(),
1748
+ subject: import_zod8.z.string().min(1).max(998),
1749
+ preheader: import_zod8.z.string().max(500).nullable(),
1557
1750
  /**
1558
1751
  * The template the document was taken from, if any. The snapshot is what is
1559
1752
  * sent in the main language; the template's other language versions are
@@ -1595,6 +1788,12 @@ var Mailing = import_zod7.z.object({
1595
1788
  status: MailingStatus,
1596
1789
  counts: MailingCounts,
1597
1790
  metadata: MailingMetadata,
1791
+ /**
1792
+ * The values held on this mailing (see `MailingMerge`): the same for
1793
+ * everyone who gets it, above the contact's stored name and properties and
1794
+ * the workspace's defaults, below the recipient's own. Empty by default.
1795
+ */
1796
+ merge: MailingMerge.default({}),
1598
1797
  scheduled_at: Timestamp.nullable(),
1599
1798
  /** The A/B test on subject or content (S4), null when there is none. */
1600
1799
  ab_test: AbTestState.nullable(),
@@ -1606,15 +1805,15 @@ var Mailing = import_zod7.z.object({
1606
1805
  * recipients refused as dead addresses in one run (see the provider's
1607
1806
  * `rejections.anomaly`). Resuming clears it and starts a new run.
1608
1807
  */
1609
- pause_reason: import_zod7.z.string().nullable().default(null),
1808
+ pause_reason: import_zod8.z.string().nullable().default(null),
1610
1809
  created_at: Timestamp,
1611
1810
  updated_at: Timestamp
1612
1811
  });
1613
1812
  var MailingSummary = Mailing.omit({ document: true });
1614
1813
  var MailingContent = {
1615
- name: import_zod7.z.string().max(200).optional(),
1616
- subject: import_zod7.z.string().min(1).max(998),
1617
- preheader: import_zod7.z.string().max(500).optional(),
1814
+ name: import_zod8.z.string().max(200).optional(),
1815
+ subject: import_zod8.z.string().min(1).max(998),
1816
+ preheader: import_zod8.z.string().max(500).optional(),
1618
1817
  /** See `Mailing.send_locale`. */
1619
1818
  send_locale: LocaleTag.nullable().optional(),
1620
1819
  /**
@@ -1625,9 +1824,11 @@ var MailingContent = {
1625
1824
  */
1626
1825
  topic: Slug.nullable().optional(),
1627
1826
  provider_id: Id,
1628
- metadata: MailingMetadata.optional()
1827
+ metadata: MailingMetadata.optional(),
1828
+ /** See `Mailing.merge`. `first_name` and `last_name` only on a letter (no topic). */
1829
+ merge: MailingMerge.optional()
1629
1830
  };
1630
- var MailingCreate = import_zod7.z.object({
1831
+ var MailingCreate = import_zod8.z.object({
1631
1832
  ...MailingContent,
1632
1833
  subject: MailingContent.subject.optional(),
1633
1834
  document: TemplateDocument.optional(),
@@ -1643,15 +1844,22 @@ var MailingCreate = import_zod7.z.object({
1643
1844
  message: "a mailing made from a document needs a subject",
1644
1845
  path: ["subject"]
1645
1846
  });
1646
- var MailingUpdate = import_zod7.z.object({
1647
- name: import_zod7.z.string().max(200).nullable().optional(),
1847
+ var MailingUpdate = import_zod8.z.object({
1848
+ name: import_zod8.z.string().max(200).nullable().optional(),
1648
1849
  subject: MailingContent.subject.optional(),
1649
- preheader: import_zod7.z.string().max(500).nullable().optional(),
1850
+ preheader: import_zod8.z.string().max(500).nullable().optional(),
1650
1851
  /** Null turns a draft into a letter, which it can only be with at most one recipient. */
1651
1852
  topic: Slug.nullable().optional(),
1652
1853
  send_locale: LocaleTag.nullable().optional(),
1653
1854
  provider_id: Id.optional(),
1654
1855
  metadata: MailingMetadata.optional(),
1856
+ /**
1857
+ * Replaces the mailing's values whole (see `Mailing.merge`). Giving a
1858
+ * mailing that holds `first_name` or `last_name` a topic is refused
1859
+ * (`name_on_broadcast`) unless the same call replaces its values without
1860
+ * them.
1861
+ */
1862
+ merge: MailingMerge.optional(),
1655
1863
  document: TemplateDocument.optional()
1656
1864
  }).refine((v) => Object.keys(v).length > 0, "at least one field");
1657
1865
  var MailingListQuery = PageQuery.extend({
@@ -1660,30 +1868,30 @@ var MailingListQuery = PageQuery.extend({
1660
1868
  kind: MailingKind.optional(),
1661
1869
  automation_id: Id.optional()
1662
1870
  });
1663
- var MailingSendRequest = import_zod7.z.object({}).strict();
1664
- var MailingRetryFailedRequest = import_zod7.z.object({
1871
+ var MailingSendRequest = import_zod8.z.object({}).strict();
1872
+ var MailingRetryFailedRequest = import_zod8.z.object({
1665
1873
  /**
1666
1874
  * Also requeue recipients whose outcome is unknown after a crash. They may
1667
1875
  * already have received the message, so this is a human's decision, never a
1668
1876
  * default.
1669
1877
  */
1670
- include_outcome_unknown: import_zod7.z.boolean().optional()
1878
+ include_outcome_unknown: import_zod8.z.boolean().optional()
1671
1879
  }).strict();
1672
- var MailingActionRequest = import_zod7.z.object({}).strict();
1673
- var MailingTestRequest = import_zod7.z.object({
1880
+ var MailingActionRequest = import_zod8.z.object({}).strict();
1881
+ var MailingTestRequest = import_zod8.z.object({
1674
1882
  to: Email,
1675
1883
  merge: Properties.optional(),
1676
1884
  locale: LocaleTag.optional()
1677
1885
  });
1678
- var MailingTestResult = import_zod7.z.object({
1886
+ var MailingTestResult = import_zod8.z.object({
1679
1887
  message_id: Id,
1680
- provider_message_id: import_zod7.z.string().nullable()
1888
+ provider_message_id: import_zod8.z.string().nullable()
1681
1889
  });
1682
1890
  var RECIPIENT_STATUSES = ["queued", "sending", "sent", "failed", "skipped"];
1683
- var RecipientStatus = import_zod7.z.enum(RECIPIENT_STATUSES);
1891
+ var RecipientStatus = import_zod8.z.enum(RECIPIENT_STATUSES);
1684
1892
  var SKIP_REASONS = ["suppressed", "not_subscribed", "contact_erased", "cancelled", "outcome_unknown"];
1685
- var SkipReason = import_zod7.z.enum(SKIP_REASONS);
1686
- var Recipient = import_zod7.z.object({
1893
+ var SkipReason = import_zod8.z.enum(SKIP_REASONS);
1894
+ var Recipient = import_zod8.z.object({
1687
1895
  id: Id,
1688
1896
  mailing_id: Id,
1689
1897
  contact_id: Id.nullable(),
@@ -1691,55 +1899,55 @@ var Recipient = import_zod7.z.object({
1691
1899
  merge: Properties,
1692
1900
  status: RecipientStatus,
1693
1901
  skip_reason: SkipReason.nullable(),
1694
- attempts: import_zod7.z.number().int().min(0),
1902
+ attempts: import_zod8.z.number().int().min(0),
1695
1903
  message_id: Id.nullable(),
1696
- last_error: import_zod7.z.string().nullable(),
1904
+ last_error: import_zod8.z.string().nullable(),
1697
1905
  created_at: Timestamp,
1698
1906
  updated_at: Timestamp
1699
1907
  });
1700
1908
  var MAX_RECIPIENTS_PER_BATCH = 1e3;
1701
1909
  var MAX_LETTER_RECIPIENTS = 1;
1702
1910
  var LETTER_RECIPIENT_REFUSAL = "letter_has_one_recipient";
1703
- var RecipientInput = import_zod7.z.object({
1911
+ var RecipientInput = import_zod8.z.object({
1704
1912
  contact_id: Id.optional(),
1705
- external_id: import_zod7.z.string().min(1).max(255).optional(),
1913
+ external_id: import_zod8.z.string().min(1).max(255).optional(),
1706
1914
  email: Email.optional(),
1707
1915
  merge: Properties.optional()
1708
1916
  }).refine((v) => v.contact_id !== void 0 || v.external_id !== void 0 || v.email !== void 0, {
1709
1917
  message: "contact_id, external_id or email is required",
1710
1918
  path: ["email"]
1711
1919
  });
1712
- var RecipientBatch = import_zod7.z.object({
1713
- recipients: import_zod7.z.array(RecipientInput).min(1).max(MAX_RECIPIENTS_PER_BATCH)
1920
+ var RecipientBatch = import_zod8.z.object({
1921
+ recipients: import_zod8.z.array(RecipientInput).min(1).max(MAX_RECIPIENTS_PER_BATCH)
1714
1922
  });
1715
1923
  var RECIPIENT_REJECTIONS = ["unknown_contact", "duplicate_in_batch"];
1716
- var RecipientBatchResult = import_zod7.z.object({
1924
+ var RecipientBatchResult = import_zod8.z.object({
1717
1925
  /** Newly queued. */
1718
- added: import_zod7.z.number().int().min(0),
1926
+ added: import_zod8.z.number().int().min(0),
1719
1927
  /** Already on the mailing from an earlier batch: left unchanged. */
1720
- already_present: import_zod7.z.number().int().min(0),
1928
+ already_present: import_zod8.z.number().int().min(0),
1721
1929
  /** Items not added, by their index in the request. */
1722
- rejected: import_zod7.z.array(import_zod7.z.object({ index: import_zod7.z.number().int().min(0), reason: import_zod7.z.enum(RECIPIENT_REJECTIONS) }))
1930
+ rejected: import_zod8.z.array(import_zod8.z.object({ index: import_zod8.z.number().int().min(0), reason: import_zod8.z.enum(RECIPIENT_REJECTIONS) }))
1723
1931
  });
1724
1932
  var RecipientListQuery = PageQuery.extend({
1725
1933
  status: RecipientStatus.optional(),
1726
1934
  skip_reason: SkipReason.optional()
1727
1935
  });
1728
1936
  var MESSAGE_OUTCOMES = ["sent", "failed"];
1729
- var MessageOutcome = import_zod7.z.enum(MESSAGE_OUTCOMES);
1730
- var MessageSummary = import_zod7.z.object({
1937
+ var MessageOutcome = import_zod8.z.enum(MESSAGE_OUTCOMES);
1938
+ var MessageSummary = import_zod8.z.object({
1731
1939
  id: Id,
1732
1940
  mailing_id: Id.nullable(),
1733
1941
  recipient_id: Id.nullable(),
1734
1942
  contact_id: Id.nullable(),
1735
1943
  to: Email,
1736
- subject: import_zod7.z.string(),
1944
+ subject: import_zod8.z.string(),
1737
1945
  provider_id: Id,
1738
- provider_message_id: import_zod7.z.string().nullable(),
1946
+ provider_message_id: import_zod8.z.string().nullable(),
1739
1947
  outcome: MessageOutcome,
1740
- error: import_zod7.z.string().nullable(),
1741
- is_test: import_zod7.z.boolean(),
1742
- recipient_count: import_zod7.z.number().int().min(1),
1948
+ error: import_zod8.z.string().nullable(),
1949
+ is_test: import_zod8.z.boolean(),
1950
+ recipient_count: import_zod8.z.number().int().min(1),
1743
1951
  /** The language version the message was sent in; null for messages archived before languages existed. */
1744
1952
  locale: LocaleTag.nullable(),
1745
1953
  /**
@@ -1749,24 +1957,32 @@ var MessageSummary = import_zod7.z.object({
1749
1957
  * "otherwise" text. Null when the message had no insertions.
1750
1958
  */
1751
1959
  insertions: InsertionChoices.nullable(),
1960
+ /**
1961
+ * The values the message was written with, by name: the text each one
1962
+ * printed and the layer it came from (see `MessageValues`), recorded when it
1963
+ * was sent, so a later change to a default never rewrites what a reader got.
1964
+ * Null for a message archived before values were recorded, and for a signup
1965
+ * form's confirmation, which belongs to no mailing.
1966
+ */
1967
+ values: MessageValues.nullable().default(null),
1752
1968
  created_at: Timestamp
1753
1969
  });
1754
- var Message = MessageSummary.extend({ html: import_zod7.z.string() });
1755
- var MailingLanguageStatus = import_zod7.z.enum(["main", "ready", "draft", "not_a_workspace_language"]);
1756
- var MailingLanguage = import_zod7.z.object({
1970
+ var Message = MessageSummary.extend({ html: import_zod8.z.string() });
1971
+ var MailingLanguageStatus = import_zod8.z.enum(["main", "ready", "draft", "not_a_workspace_language"]);
1972
+ var MailingLanguage = import_zod8.z.object({
1757
1973
  locale: LocaleTag,
1758
1974
  status: MailingLanguageStatus,
1759
1975
  /** Queued recipients who will get this version. */
1760
- planned: import_zod7.z.number().int().min(0),
1976
+ planned: import_zod8.z.number().int().min(0),
1761
1977
  /** Messages already sent in this language (tests excluded). */
1762
- sent: import_zod7.z.number().int().min(0)
1978
+ sent: import_zod8.z.number().int().min(0)
1763
1979
  });
1764
- var MailingLanguageReport = import_zod7.z.object({
1980
+ var MailingLanguageReport = import_zod8.z.object({
1765
1981
  main_locale: LocaleTag,
1766
1982
  send_locale: LocaleTag.nullable(),
1767
- languages: import_zod7.z.array(MailingLanguage),
1768
- fallback: import_zod7.z.array(import_zod7.z.object({ wanted: import_zod7.z.string(), planned: import_zod7.z.number().int().min(1) })),
1769
- no_language: import_zod7.z.number().int().min(0),
1983
+ languages: import_zod8.z.array(MailingLanguage),
1984
+ fallback: import_zod8.z.array(import_zod8.z.object({ wanted: import_zod8.z.string(), planned: import_zod8.z.number().int().min(1) })),
1985
+ no_language: import_zod8.z.number().int().min(0),
1770
1986
  /**
1771
1987
  * Values that no choice of an insertion takes, so the "otherwise" text goes
1772
1988
  * out (docs/plans/2026-09-25-translated-insertions.md, decision 3): per
@@ -1775,41 +1991,56 @@ var MailingLanguageReport = import_zod7.z.object({
1775
1991
  * template's keys never produces one; a non-empty list means the client and
1776
1992
  * the template have drifted apart.
1777
1993
  */
1778
- insertion_misses: import_zod7.z.array(
1779
- import_zod7.z.object({
1780
- insertion: import_zod7.z.string(),
1781
- value: import_zod7.z.string(),
1782
- planned: import_zod7.z.number().int().min(0),
1783
- sent: import_zod7.z.number().int().min(0)
1994
+ insertion_misses: import_zod8.z.array(
1995
+ import_zod8.z.object({
1996
+ insertion: import_zod8.z.string(),
1997
+ value: import_zod8.z.string(),
1998
+ planned: import_zod8.z.number().int().min(0),
1999
+ sent: import_zod8.z.number().int().min(0)
1784
2000
  })
1785
2001
  )
1786
2002
  });
2003
+ var MailingResolveRequest = import_zod8.z.object({
2004
+ recipients: import_zod8.z.array(RecipientInput).max(MAX_RECIPIENTS_PER_BATCH).optional()
2005
+ });
2006
+ var MailingResolveResult = import_zod8.z.object({
2007
+ /** Every value the mailing's content can read, in order of first appearance, without `email` and `unsubscribe_url`. */
2008
+ names: import_zod8.z.array(import_zod8.z.string()),
2009
+ /** The values and insertions placed inside a link's address: one of them empty for anybody refuses the send. */
2010
+ link_values: import_zod8.z.array(import_zod8.z.string()),
2011
+ /** One entry per resolved recipient, in the request's order; a single entry with `index: null` when none were given. */
2012
+ recipients: import_zod8.z.array(ResolvedRecipient),
2013
+ /** Items not resolved, by their index in the request, for the reasons `mailings.addRecipients` rejects one. */
2014
+ rejected: import_zod8.z.array(import_zod8.z.object({ index: import_zod8.z.number().int().min(0), reason: import_zod8.z.enum(RESOLVE_REJECTIONS) })),
2015
+ /** What would refuse `mailings.send` for these recipients, as its `unfilled_link` refusal lists it; empty means none. */
2016
+ blocking: import_zod8.z.array(UnfilledLink)
2017
+ });
1787
2018
  var MessageListQuery = PageQuery.extend({
1788
2019
  mailing_id: Id.optional(),
1789
2020
  outcome: MessageOutcome.optional()
1790
2021
  });
1791
2022
 
1792
2023
  // src/platform.ts
1793
- var Tag = import_zod8.z.object({
2024
+ var Tag = import_zod9.z.object({
1794
2025
  id: Id,
1795
2026
  slug: Slug,
1796
- name: import_zod8.z.string().min(1).max(120),
1797
- contact_count: import_zod8.z.number().int().min(0),
2027
+ name: import_zod9.z.string().min(1).max(120),
2028
+ contact_count: import_zod9.z.number().int().min(0),
1798
2029
  created_at: Timestamp
1799
2030
  });
1800
- var TagCreate = import_zod8.z.object({ slug: Slug, name: import_zod8.z.string().min(1).max(120) });
1801
- var TagAssignment = import_zod8.z.object({
1802
- contact_ids: import_zod8.z.array(Id).min(1).max(1e3)
2031
+ var TagCreate = import_zod9.z.object({ slug: Slug, name: import_zod9.z.string().min(1).max(120) });
2032
+ var TagAssignment = import_zod9.z.object({
2033
+ contact_ids: import_zod9.z.array(Id).min(1).max(1e3)
1803
2034
  });
1804
2035
  var CONTACT_PROPERTY_TYPES = ["string", "number", "boolean", "date"];
1805
- var ContactPropertyType = import_zod8.z.enum(CONTACT_PROPERTY_TYPES);
1806
- var ContactPropertyKey = import_zod8.z.string().regex(/^[A-Za-z0-9_.-]{1,64}$/, "letters, digits, dot, underscore and hyphen, 1 to 64");
1807
- var ContactPropertyDefinition = import_zod8.z.object({
2036
+ var ContactPropertyType = import_zod9.z.enum(CONTACT_PROPERTY_TYPES);
2037
+ var ContactPropertyKey = import_zod9.z.string().regex(/^[A-Za-z0-9_.-]{1,64}$/, "letters, digits, dot, underscore and hyphen, 1 to 64");
2038
+ var ContactPropertyDefinition = import_zod9.z.object({
1808
2039
  key: ContactPropertyKey,
1809
- label: import_zod8.z.string().min(1).max(120),
2040
+ label: import_zod9.z.string().min(1).max(120),
1810
2041
  type: ContactPropertyType
1811
2042
  });
1812
- var ContactPropertyParams = import_zod8.z.object({ key: ContactPropertyKey });
2043
+ var ContactPropertyParams = import_zod9.z.object({ key: ContactPropertyKey });
1813
2044
  var FILTER_OPERATORS = [
1814
2045
  "eq",
1815
2046
  "neq",
@@ -1825,8 +2056,8 @@ var FILTER_OPERATORS = [
1825
2056
  "in",
1826
2057
  "not_in"
1827
2058
  ];
1828
- var FilterOperator = import_zod8.z.enum(FILTER_OPERATORS);
1829
- var FilterField = import_zod8.z.string().regex(
2059
+ var FilterOperator = import_zod9.z.enum(FILTER_OPERATORS);
2060
+ var FilterField = import_zod9.z.string().regex(
1830
2061
  /^(email|first_name|last_name|locale|created_at|tag|topic|engagement:(opened|clicked)|property:[A-Za-z0-9_.-]{1,64})$/,
1831
2062
  "unknown filter field"
1832
2063
  );
@@ -1842,18 +2073,18 @@ var FILTER_FIELD_OPERATORS = {
1842
2073
  property: FILTER_OPERATORS
1843
2074
  };
1844
2075
  var MAX_FILTER_DEPTH = 5;
1845
- var FilterCondition = import_zod8.z.object({ field: FilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
2076
+ var FilterCondition = import_zod9.z.object({ field: FilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1846
2077
  message: "exists and not_exists take no value; every other operator needs one",
1847
2078
  path: ["value"]
1848
2079
  }).refine((c) => c.op !== "in" && c.op !== "not_in" || Array.isArray(c.value), {
1849
2080
  message: "in and not_in take an array",
1850
2081
  path: ["value"]
1851
2082
  });
1852
- var SegmentFilter = import_zod8.z.lazy(
1853
- () => import_zod8.z.union([
1854
- import_zod8.z.object({ and: import_zod8.z.array(SegmentFilter).min(1).max(50) }).strict(),
1855
- import_zod8.z.object({ or: import_zod8.z.array(SegmentFilter).min(1).max(50) }).strict(),
1856
- import_zod8.z.object({ not: SegmentFilter }).strict(),
2083
+ var SegmentFilter = import_zod9.z.lazy(
2084
+ () => import_zod9.z.union([
2085
+ import_zod9.z.object({ and: import_zod9.z.array(SegmentFilter).min(1).max(50) }).strict(),
2086
+ import_zod9.z.object({ or: import_zod9.z.array(SegmentFilter).min(1).max(50) }).strict(),
2087
+ import_zod9.z.object({ not: SegmentFilter }).strict(),
1857
2088
  FilterCondition
1858
2089
  ])
1859
2090
  );
@@ -1941,42 +2172,42 @@ function untypedValueProblem(c, every) {
1941
2172
  if (orderOp) return every(isFilterNumber, "numbers (define the property to compare dates)");
1942
2173
  return every((v) => isScalar(v) || v === null, "strings, numbers, booleans or null");
1943
2174
  }
1944
- var Segment = import_zod8.z.object({
2175
+ var Segment = import_zod9.z.object({
1945
2176
  id: Id,
1946
- name: import_zod8.z.string().min(1).max(120),
2177
+ name: import_zod9.z.string().min(1).max(120),
1947
2178
  filter: SegmentFilter,
1948
2179
  /** Computed on read. */
1949
- contact_count: import_zod8.z.number().int().min(0),
2180
+ contact_count: import_zod9.z.number().int().min(0),
1950
2181
  created_at: Timestamp,
1951
2182
  updated_at: Timestamp
1952
2183
  });
1953
- var SegmentCreate = import_zod8.z.object({ name: import_zod8.z.string().min(1).max(120), filter: BoundedSegmentFilter });
1954
- var SegmentPreviewRequest = import_zod8.z.object({ filter: BoundedSegmentFilter });
1955
- var SegmentPreview = import_zod8.z.object({
1956
- contact_count: import_zod8.z.number().int().min(0),
2184
+ var SegmentCreate = import_zod9.z.object({ name: import_zod9.z.string().min(1).max(120), filter: BoundedSegmentFilter });
2185
+ var SegmentPreviewRequest = import_zod9.z.object({ filter: BoundedSegmentFilter });
2186
+ var SegmentPreview = import_zod9.z.object({
2187
+ contact_count: import_zod9.z.number().int().min(0),
1957
2188
  /** Up to five matching contacts, for a human to sanity-check the filter. */
1958
- sample: import_zod8.z.array(import_zod8.z.object({ id: Id, email: Email })).max(5)
2189
+ sample: import_zod9.z.array(import_zod9.z.object({ id: Id, email: Email })).max(5)
1959
2190
  });
1960
- var MailingAudienceFromSegment = import_zod8.z.object({ segment_id: Id });
2191
+ var MailingAudienceFromSegment = import_zod9.z.object({ segment_id: Id });
1961
2192
  var SIGNUP_FORM_FIELDS = ["first_name", "last_name"];
1962
2193
  var HOSTED_PAGE_LOCALES = ["en", "de", "it", "fr", "es"];
1963
- var SignupFormTranslation = import_zod8.z.object({
1964
- title: import_zod8.z.string().min(1).max(120),
1965
- consent_text: import_zod8.z.string().min(1).max(2e3)
2194
+ var SignupFormTranslation = import_zod9.z.object({
2195
+ title: import_zod9.z.string().min(1).max(120),
2196
+ consent_text: import_zod9.z.string().min(1).max(2e3)
1966
2197
  });
1967
- var SignupForm = import_zod8.z.object({
2198
+ var SignupForm = import_zod9.z.object({
1968
2199
  id: Id,
1969
- name: import_zod8.z.string().min(1).max(120),
2200
+ name: import_zod9.z.string().min(1).max(120),
1970
2201
  /** The heading of the hosted page. */
1971
- title: import_zod8.z.string().min(1).max(120),
2202
+ title: import_zod9.z.string().min(1).max(120),
1972
2203
  /** What the person agrees to, shown above the button and recorded with the confirmation. */
1973
- consent_text: import_zod8.z.string().min(1).max(2e3),
1974
- translations: import_zod8.z.record(SignupFormTranslation),
1975
- topics: import_zod8.z.array(Slug).min(1),
1976
- tags: import_zod8.z.array(Slug),
2204
+ consent_text: import_zod9.z.string().min(1).max(2e3),
2205
+ translations: import_zod9.z.record(SignupFormTranslation),
2206
+ topics: import_zod9.z.array(Slug).min(1),
2207
+ tags: import_zod9.z.array(Slug),
1977
2208
  /** Fields shown besides email. */
1978
- fields: import_zod8.z.array(import_zod8.z.enum(SIGNUP_FORM_FIELDS)),
1979
- double_opt_in: import_zod8.z.literal(true),
2209
+ fields: import_zod9.z.array(import_zod9.z.enum(SIGNUP_FORM_FIELDS)),
2210
+ double_opt_in: import_zod9.z.literal(true),
1980
2211
  /** The provider the confirmation mail is sent through. */
1981
2212
  provider_id: Id,
1982
2213
  /**
@@ -1985,11 +2216,11 @@ var SignupForm = import_zod8.z.object({
1985
2216
  */
1986
2217
  confirmation_template_id: Id.nullable(),
1987
2218
  /** Where the person lands after confirming. Null shows the hosted confirmation page. */
1988
- redirect_url: import_zod8.z.string().url().nullable(),
2219
+ redirect_url: import_zod9.z.string().url().nullable(),
1989
2220
  /** Origins allowed to embed the form and call the submission route from a browser. */
1990
- allowed_origins: import_zod8.z.array(import_zod8.z.string().url()).max(20),
2221
+ allowed_origins: import_zod9.z.array(import_zod9.z.string().url()).max(20),
1991
2222
  /** Bumped on every change; recorded with each confirmation. */
1992
- version: import_zod8.z.number().int().min(1),
2223
+ version: import_zod9.z.number().int().min(1),
1993
2224
  created_at: Timestamp,
1994
2225
  updated_at: Timestamp
1995
2226
  });
@@ -2004,56 +2235,56 @@ var SignupFormCreate = SignupForm.omit({
2004
2235
  tags: SignupForm.shape.tags.optional(),
2005
2236
  fields: SignupForm.shape.fields.optional(),
2006
2237
  confirmation_template_id: Id.nullable().optional(),
2007
- redirect_url: import_zod8.z.string().url().nullable().optional(),
2238
+ redirect_url: import_zod9.z.string().url().nullable().optional(),
2008
2239
  allowed_origins: SignupForm.shape.allowed_origins.optional()
2009
2240
  });
2010
- var SignupFormEmbed = import_zod8.z.object({
2011
- hosted_url: import_zod8.z.string().url(),
2241
+ var SignupFormEmbed = import_zod9.z.object({
2242
+ hosted_url: import_zod9.z.string().url(),
2012
2243
  /** A plain HTML form posting to the hosted page; works without JavaScript. */
2013
- html: import_zod8.z.string(),
2244
+ html: import_zod9.z.string(),
2014
2245
  /** A small optional script that adds the time check and submits in place. */
2015
- script_url: import_zod8.z.string().url(),
2246
+ script_url: import_zod9.z.string().url(),
2016
2247
  /** Where a browser fetches a fresh `form_token` from (GET, public, CORS for `allowed_origins`). */
2017
- token_url: import_zod8.z.string().url()
2248
+ token_url: import_zod9.z.string().url()
2018
2249
  });
2019
- var SignupSubmission = import_zod8.z.object({
2250
+ var SignupSubmission = import_zod9.z.object({
2020
2251
  email: Email,
2021
- first_name: import_zod8.z.string().max(200).optional(),
2022
- last_name: import_zod8.z.string().max(200).optional(),
2023
- locale: import_zod8.z.string().min(2).max(35).optional(),
2252
+ first_name: import_zod9.z.string().max(200).optional(),
2253
+ last_name: import_zod9.z.string().max(200).optional(),
2254
+ locale: import_zod9.z.string().min(2).max(35).optional(),
2024
2255
  /** Honeypot: must be empty. */
2025
- website: import_zod8.z.string().max(0).optional(),
2256
+ website: import_zod9.z.string().max(0).optional(),
2026
2257
  /**
2027
2258
  * The signed render time from the form's token URL: a submission sooner than a
2028
2259
  * human could fill the form, or long after, is refused.
2029
2260
  */
2030
- form_token: import_zod8.z.string().min(1).max(512)
2261
+ form_token: import_zod9.z.string().min(1).max(512)
2031
2262
  });
2032
2263
  var IMPORT_STATUSES = ["uploaded", "validating", "validated", "committing", "completed", "failed", "cancelled"];
2033
- var ImportStatus = import_zod8.z.enum(IMPORT_STATUSES);
2264
+ var ImportStatus = import_zod9.z.enum(IMPORT_STATUSES);
2034
2265
  var IMPORT_TERMINAL_STATUSES = ["completed", "failed", "cancelled"];
2035
- var ImportColumnMapping = import_zod8.z.record(
2036
- import_zod8.z.string().regex(/^(email|external_id|first_name|last_name|locale|property:[A-Za-z0-9_.-]{1,64}|ignore)$/)
2266
+ var ImportColumnMapping = import_zod9.z.record(
2267
+ import_zod9.z.string().regex(/^(email|external_id|first_name|last_name|locale|property:[A-Za-z0-9_.-]{1,64}|ignore)$/)
2037
2268
  );
2038
2269
  var IMPORT_FILE_FIELD = "file";
2039
2270
  var MAX_IMPORT_BYTES = 50 * 1024 * 1024;
2040
2271
  var MAX_IMPORT_ROWS = 2e5;
2041
- var ImportMappingRequest = import_zod8.z.object({
2272
+ var ImportMappingRequest = import_zod9.z.object({
2042
2273
  /** CSV header -> contact field. Exactly one column maps to `email`. */
2043
2274
  mapping: ImportColumnMapping.refine(
2044
2275
  (m) => Object.values(m).filter((v) => v === "email").length === 1,
2045
2276
  "exactly one column maps to email"
2046
2277
  ),
2047
- topics: import_zod8.z.array(Slug).max(100),
2048
- tags: import_zod8.z.array(Slug).max(100),
2278
+ topics: import_zod9.z.array(Slug).max(100),
2279
+ tags: import_zod9.z.array(Slug).max(100),
2049
2280
  /** Existing contacts get the mapped fields overwritten; false only adds topics, tags and missing fields. */
2050
- update_existing: import_zod8.z.boolean().optional(),
2281
+ update_existing: import_zod9.z.boolean().optional(),
2051
2282
  /** The importer states the people consented; the service records who said so and when. */
2052
- consent_confirmed: import_zod8.z.literal(true)
2283
+ consent_confirmed: import_zod9.z.literal(true)
2053
2284
  });
2054
- var ImportCommitRequest = import_zod8.z.object({ mapping_version: import_zod8.z.number().int().min(1) });
2285
+ var ImportCommitRequest = import_zod9.z.object({ mapping_version: import_zod9.z.number().int().min(1) });
2055
2286
  var IMPORT_ROW_OUTCOMES = ["created", "updated", "unchanged", "suppressed", "skipped"];
2056
- var ImportRowOutcome = import_zod8.z.enum(IMPORT_ROW_OUTCOMES);
2287
+ var ImportRowOutcome = import_zod9.z.enum(IMPORT_ROW_OUTCOMES);
2057
2288
  var IMPORT_SKIP_REASONS = [
2058
2289
  "missing_email",
2059
2290
  "invalid_email",
@@ -2062,90 +2293,90 @@ var IMPORT_SKIP_REASONS = [
2062
2293
  "external_id_conflict",
2063
2294
  "wrong_column_count"
2064
2295
  ];
2065
- var ImportSkipReason = import_zod8.z.enum(IMPORT_SKIP_REASONS);
2066
- var ImportReport = import_zod8.z.object({
2067
- created: import_zod8.z.number().int().min(0),
2068
- updated: import_zod8.z.number().int().min(0),
2069
- unchanged: import_zod8.z.number().int().min(0),
2070
- suppressed: import_zod8.z.number().int().min(0),
2071
- skipped: import_zod8.z.number().int().min(0),
2072
- skipped_by_reason: import_zod8.z.record(ImportSkipReason, import_zod8.z.number().int().min(0)),
2296
+ var ImportSkipReason = import_zod9.z.enum(IMPORT_SKIP_REASONS);
2297
+ var ImportReport = import_zod9.z.object({
2298
+ created: import_zod9.z.number().int().min(0),
2299
+ updated: import_zod9.z.number().int().min(0),
2300
+ unchanged: import_zod9.z.number().int().min(0),
2301
+ suppressed: import_zod9.z.number().int().min(0),
2302
+ skipped: import_zod9.z.number().int().min(0),
2303
+ skipped_by_reason: import_zod9.z.record(ImportSkipReason, import_zod9.z.number().int().min(0)),
2073
2304
  /** Rows whose contact was subscribed without some topic, because the address is blocked for it. */
2074
- topics_withheld: import_zod8.z.number().int().min(0)
2305
+ topics_withheld: import_zod9.z.number().int().min(0)
2075
2306
  });
2076
- var ImportJob = import_zod8.z.object({
2307
+ var ImportJob = import_zod9.z.object({
2077
2308
  id: Id,
2078
2309
  status: ImportStatus,
2079
- file_name: import_zod8.z.string().max(255).nullable(),
2080
- file_bytes: import_zod8.z.number().int().min(0),
2081
- total_rows: import_zod8.z.number().int().min(0),
2310
+ file_name: import_zod9.z.string().max(255).nullable(),
2311
+ file_bytes: import_zod9.z.number().int().min(0),
2312
+ total_rows: import_zod9.z.number().int().min(0),
2082
2313
  /** The header row, as in the file. */
2083
- columns: import_zod8.z.array(import_zod8.z.string()),
2314
+ columns: import_zod9.z.array(import_zod9.z.string()),
2084
2315
  /** The first rows, for the mapping screen. */
2085
- sample: import_zod8.z.array(import_zod8.z.array(import_zod8.z.string())).max(5),
2316
+ sample: import_zod9.z.array(import_zod9.z.array(import_zod9.z.string())).max(5),
2086
2317
  /** A mapping guessed from the headers, for the mapping screen to start from. */
2087
2318
  suggested_mapping: ImportColumnMapping,
2088
2319
  mapping: ImportColumnMapping.nullable(),
2089
- mapping_version: import_zod8.z.number().int().min(0),
2090
- topics: import_zod8.z.array(Slug),
2091
- tags: import_zod8.z.array(Slug),
2092
- update_existing: import_zod8.z.boolean(),
2320
+ mapping_version: import_zod9.z.number().int().min(0),
2321
+ topics: import_zod9.z.array(Slug),
2322
+ tags: import_zod9.z.array(Slug),
2323
+ update_existing: import_zod9.z.boolean(),
2093
2324
  /** The dry run of the current mapping; null before one finished. */
2094
2325
  dry_run: ImportReport.nullable(),
2095
2326
  /** What the commit has written so far; null before it started. */
2096
2327
  result: ImportReport.nullable(),
2097
2328
  /** Rows the current phase (dry run or commit) has processed. */
2098
- processed_rows: import_zod8.z.number().int().min(0),
2329
+ processed_rows: import_zod9.z.number().int().min(0),
2099
2330
  /** Why a `failed` import failed. */
2100
- error: import_zod8.z.string().nullable(),
2331
+ error: import_zod9.z.string().nullable(),
2101
2332
  created_at: Timestamp,
2102
2333
  updated_at: Timestamp,
2103
2334
  finished_at: Timestamp.nullable()
2104
2335
  });
2105
- var ImportRow = import_zod8.z.object({
2336
+ var ImportRow = import_zod9.z.object({
2106
2337
  /** The line in the file, 1 being the first line after the header. */
2107
- row: import_zod8.z.number().int().min(1),
2108
- email: import_zod8.z.string().nullable(),
2338
+ row: import_zod9.z.number().int().min(1),
2339
+ email: import_zod9.z.string().nullable(),
2109
2340
  outcome: ImportRowOutcome,
2110
2341
  reason: ImportSkipReason.nullable(),
2111
2342
  /** A human explanation for a skipped row (which value, which column). */
2112
- message: import_zod8.z.string().nullable(),
2343
+ message: import_zod9.z.string().nullable(),
2113
2344
  contact_id: Id.nullable()
2114
2345
  });
2115
2346
  var ImportRowListQuery = PageQuery.extend({ outcome: ImportRowOutcome.optional() });
2116
- var MailingScheduleRequest = import_zod8.z.object({ send_at: Timestamp });
2117
- var TrackingSettings = import_zod8.z.object({ opens: import_zod8.z.boolean(), clicks: import_zod8.z.boolean() });
2118
- var VariantAnalytics = import_zod8.z.object({
2119
- key: import_zod8.z.string(),
2120
- sent: import_zod8.z.number().int().min(0),
2121
- unique_opens: import_zod8.z.number().int().min(0).nullable(),
2122
- unique_clicks: import_zod8.z.number().int().min(0).nullable()
2123
- });
2124
- var MailingAnalytics = import_zod8.z.object({
2347
+ var MailingScheduleRequest = import_zod9.z.object({ send_at: Timestamp });
2348
+ var TrackingSettings = import_zod9.z.object({ opens: import_zod9.z.boolean(), clicks: import_zod9.z.boolean() });
2349
+ var VariantAnalytics = import_zod9.z.object({
2350
+ key: import_zod9.z.string(),
2351
+ sent: import_zod9.z.number().int().min(0),
2352
+ unique_opens: import_zod9.z.number().int().min(0).nullable(),
2353
+ unique_clicks: import_zod9.z.number().int().min(0).nullable()
2354
+ });
2355
+ var MailingAnalytics = import_zod9.z.object({
2125
2356
  mailing_id: Id,
2126
2357
  counts: MailingCounts,
2127
2358
  /** What was tracked for this mailing, fixed when it started; null before it started. */
2128
2359
  tracking: TrackingSettings.nullable(),
2129
2360
  /** Unique recipients with a human open. Null when opens were not tracked. */
2130
- unique_opens: import_zod8.z.number().int().min(0).nullable(),
2361
+ unique_opens: import_zod9.z.number().int().min(0).nullable(),
2131
2362
  /**
2132
2363
  * Recipients whose only opens came from Apple Mail Privacy Protection, which
2133
2364
  * loads every image on delivery: counted apart, never as human opens.
2134
2365
  */
2135
- apple_mpp_opens: import_zod8.z.number().int().min(0).nullable(),
2366
+ apple_mpp_opens: import_zod9.z.number().int().min(0).nullable(),
2136
2367
  /** Opens and clicks from security scanners and prefetchers, filtered out of the unique counts. */
2137
- machine_events: import_zod8.z.number().int().min(0).nullable(),
2138
- unique_clicks: import_zod8.z.number().int().min(0).nullable(),
2139
- unsubscribes: import_zod8.z.number().int().min(0),
2140
- bounces: import_zod8.z.number().int().min(0),
2141
- complaints: import_zod8.z.number().int().min(0),
2142
- links: import_zod8.z.array(import_zod8.z.object({ url: import_zod8.z.string(), unique_clicks: import_zod8.z.number().int().min(0) })).nullable(),
2143
- variants: import_zod8.z.array(VariantAnalytics).nullable()
2368
+ machine_events: import_zod9.z.number().int().min(0).nullable(),
2369
+ unique_clicks: import_zod9.z.number().int().min(0).nullable(),
2370
+ unsubscribes: import_zod9.z.number().int().min(0),
2371
+ bounces: import_zod9.z.number().int().min(0),
2372
+ complaints: import_zod9.z.number().int().min(0),
2373
+ links: import_zod9.z.array(import_zod9.z.object({ url: import_zod9.z.string(), unique_clicks: import_zod9.z.number().int().min(0) })).nullable(),
2374
+ variants: import_zod9.z.array(VariantAnalytics).nullable()
2144
2375
  });
2145
2376
 
2146
2377
  // src/automations.ts
2147
2378
  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})$/;
2148
- var AutomationFilterField = import_zod9.z.string().regex(AUTOMATION_FILTER_FIELD_PATTERN, "unknown filter field");
2379
+ var AutomationFilterField = import_zod10.z.string().regex(AUTOMATION_FILTER_FIELD_PATTERN, "unknown filter field");
2149
2380
  var AUTOMATION_FILTER_FIELD_OPERATORS = {
2150
2381
  ...FILTER_FIELD_OPERATORS,
2151
2382
  segment: ["eq", "neq", "in", "not_in"],
@@ -2155,18 +2386,18 @@ var AUTOMATION_FILTER_FIELD_OPERATORS = {
2155
2386
  step: ["eq", "neq"]
2156
2387
  };
2157
2388
  var automationFilterFamily = filterFieldFamily;
2158
- var AutomationFilterCondition = import_zod9.z.object({ field: AutomationFilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
2389
+ var AutomationFilterCondition = import_zod10.z.object({ field: AutomationFilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
2159
2390
  message: "exists and not_exists take no value; every other operator needs one",
2160
2391
  path: ["value"]
2161
2392
  }).refine((c) => c.op !== "in" && c.op !== "not_in" || Array.isArray(c.value), {
2162
2393
  message: "in and not_in take an array",
2163
2394
  path: ["value"]
2164
2395
  });
2165
- var AutomationFilter = import_zod9.z.lazy(
2166
- () => import_zod9.z.union([
2167
- import_zod9.z.object({ and: import_zod9.z.array(AutomationFilter).min(1).max(50) }).strict(),
2168
- import_zod9.z.object({ or: import_zod9.z.array(AutomationFilter).min(1).max(50) }).strict(),
2169
- import_zod9.z.object({ not: AutomationFilter }).strict(),
2396
+ var AutomationFilter = import_zod10.z.lazy(
2397
+ () => import_zod10.z.union([
2398
+ import_zod10.z.object({ and: import_zod10.z.array(AutomationFilter).min(1).max(50) }).strict(),
2399
+ import_zod10.z.object({ or: import_zod10.z.array(AutomationFilter).min(1).max(50) }).strict(),
2400
+ import_zod10.z.object({ not: AutomationFilter }).strict(),
2170
2401
  AutomationFilterCondition
2171
2402
  ])
2172
2403
  );
@@ -2179,20 +2410,20 @@ function filterConditions(filter) {
2179
2410
  if ("not" in filter) return filterConditions(filter.not);
2180
2411
  return [filter];
2181
2412
  }
2182
- var StepId = import_zod9.z.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "letters, digits, underscore and hyphen, 1 to 64");
2183
- var TimeOfDay = import_zod9.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "HH:MM in 24 hours");
2184
- var Weekday = import_zod9.z.number().int().min(0).max(6);
2185
- var TimezoneName = import_zod9.z.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");
2413
+ var StepId = import_zod10.z.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "letters, digits, underscore and hyphen, 1 to 64");
2414
+ var TimeOfDay = import_zod10.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "HH:MM in 24 hours");
2415
+ var Weekday = import_zod10.z.number().int().min(0).max(6);
2416
+ var TimezoneName = import_zod10.z.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");
2186
2417
  var MAX_DELAY_SECONDS = 365 * 24 * 60 * 60;
2187
- var DateOnly = import_zod9.z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "a calendar date such as 2026-09-20").refine((v) => {
2418
+ var DateOnly = import_zod10.z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "a calendar date such as 2026-09-20").refine((v) => {
2188
2419
  const [y, m, d] = v.split("-").map(Number);
2189
2420
  const t = new Date(Date.UTC(y, m - 1, d));
2190
2421
  return t.getUTCFullYear() === y && t.getUTCMonth() + 1 === m && t.getUTCDate() === d;
2191
2422
  }, "a real calendar date");
2192
- var OffsetDays = import_zod9.z.number().int().min(-365).max(365);
2423
+ var OffsetDays = import_zod10.z.number().int().min(-365).max(365);
2193
2424
  var DATE_PASSED_ANSWERS = ["skip", "stop", "continue"];
2194
- var DatePassedAnswer = import_zod9.z.enum(DATE_PASSED_ANSWERS);
2195
- var EventName = import_zod9.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,79}$/, "letters, digits, dot, colon, underscore and hyphen, 1 to 80");
2425
+ var DatePassedAnswer = import_zod10.z.enum(DATE_PASSED_ANSWERS);
2426
+ var EventName = import_zod10.z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,79}$/, "letters, digits, dot, colon, underscore and hyphen, 1 to 80");
2196
2427
  var AUTOMATION_TRIGGER_KINDS = [
2197
2428
  "topic_subscribed",
2198
2429
  "form_confirmed",
@@ -2205,17 +2436,17 @@ var AUTOMATION_TRIGGER_KINDS = [
2205
2436
  "segment_entered",
2206
2437
  "link_clicked"
2207
2438
  ];
2208
- var AutomationTriggerKind = import_zod9.z.enum(AUTOMATION_TRIGGER_KINDS);
2439
+ var AutomationTriggerKind = import_zod10.z.enum(AUTOMATION_TRIGGER_KINDS);
2209
2440
  var exclude = { exclude: BoundedAutomationFilter.nullish() };
2210
- var AutomationTrigger = import_zod9.z.discriminatedUnion("kind", [
2211
- import_zod9.z.object({ kind: import_zod9.z.literal("topic_subscribed"), topic: Slug, ...exclude }).strict(),
2212
- import_zod9.z.object({ kind: import_zod9.z.literal("form_confirmed"), form_id: Id, ...exclude }).strict(),
2213
- import_zod9.z.object({ kind: import_zod9.z.literal("tag_added"), tag: Slug, ...exclude }).strict(),
2441
+ var AutomationTrigger = import_zod10.z.discriminatedUnion("kind", [
2442
+ import_zod10.z.object({ kind: import_zod10.z.literal("topic_subscribed"), topic: Slug, ...exclude }).strict(),
2443
+ import_zod10.z.object({ kind: import_zod10.z.literal("form_confirmed"), form_id: Id, ...exclude }).strict(),
2444
+ import_zod10.z.object({ kind: import_zod10.z.literal("tag_added"), tag: Slug, ...exclude }).strict(),
2214
2445
  /** `to` given: only a change that lands on this value fires. Absent: any change of the key. */
2215
- import_zod9.z.object({ kind: import_zod9.z.literal("property_changed"), key: ContactPropertyKey, to: JsonValue.optional(), ...exclude }).strict(),
2446
+ import_zod10.z.object({ kind: import_zod10.z.literal("property_changed"), key: ContactPropertyKey, to: JsonValue.optional(), ...exclude }).strict(),
2216
2447
  /** `where` filters the event's own data, so only `event:<key>` leaves belong in it. */
2217
- import_zod9.z.object({ kind: import_zod9.z.literal("event"), name: EventName, where: BoundedAutomationFilter.nullish(), ...exclude }).strict(),
2218
- import_zod9.z.object({ kind: import_zod9.z.literal("manual"), ...exclude }).strict(),
2448
+ import_zod10.z.object({ kind: import_zod10.z.literal("event"), name: EventName, where: BoundedAutomationFilter.nullish(), ...exclude }).strict(),
2449
+ import_zod10.z.object({ kind: import_zod10.z.literal("manual"), ...exclude }).strict(),
2219
2450
  /**
2220
2451
  * Every year on a date the contact carries: a birthday, a joining date, a
2221
2452
  * renewal. `offset_days` moves it ("three days before"), `at` is the wall
@@ -2225,8 +2456,8 @@ var AutomationTrigger = import_zod9.z.discriminatedUnion("kind", [
2225
2456
  * A 29 February date fires on 1 March in a year that has no 29 February, so
2226
2457
  * nobody is skipped every fourth year.
2227
2458
  */
2228
- import_zod9.z.object({
2229
- kind: import_zod9.z.literal("date_anniversary"),
2459
+ import_zod10.z.object({
2460
+ kind: import_zod10.z.literal("date_anniversary"),
2230
2461
  key: ContactPropertyKey,
2231
2462
  offset_days: OffsetDays,
2232
2463
  at: TimeOfDay,
@@ -2238,8 +2469,8 @@ var AutomationTrigger = import_zod9.z.discriminatedUnion("kind", [
2238
2469
  * not ask about a segment or about an event's data: there is no event, and a
2239
2470
  * segment is its own trigger kind.
2240
2471
  */
2241
- import_zod9.z.object({
2242
- kind: import_zod9.z.literal("exact_date"),
2472
+ import_zod10.z.object({
2473
+ kind: import_zod10.z.literal("exact_date"),
2243
2474
  on: DateOnly,
2244
2475
  at: TimeOfDay,
2245
2476
  where: BoundedAutomationFilter.nullish(),
@@ -2258,7 +2489,7 @@ var AutomationTrigger = import_zod9.z.discriminatedUnion("kind", [
2258
2489
  * already exists. Entering those people as well is the publish dialog's
2259
2490
  * backfill question, answered by a person rather than by the sweep.
2260
2491
  */
2261
- import_zod9.z.object({ kind: import_zod9.z.literal("segment_entered"), segment_id: Id, ...exclude }).strict(),
2492
+ import_zod10.z.object({ kind: import_zod10.z.literal("segment_entered"), segment_id: Id, ...exclude }).strict(),
2262
2493
  /**
2263
2494
  * S4. When somebody clicks a link in a mailing that has already gone out.
2264
2495
  *
@@ -2268,7 +2499,7 @@ var AutomationTrigger = import_zod9.z.discriminatedUnion("kind", [
2268
2499
  * tracking off there is no click to hear about, so the validator refuses it
2269
2500
  * rather than leaving an automation that can never fire.
2270
2501
  */
2271
- import_zod9.z.object({ kind: import_zod9.z.literal("link_clicked"), mailing_id: Id, url: import_zod9.z.string().min(1).max(2048).optional(), ...exclude }).strict()
2502
+ import_zod10.z.object({ kind: import_zod10.z.literal("link_clicked"), mailing_id: Id, url: import_zod10.z.string().min(1).max(2048).optional(), ...exclude }).strict()
2272
2503
  ]);
2273
2504
  var AUTOMATION_DATE_TRIGGER_KINDS = ["date_anniversary", "exact_date"];
2274
2505
  var MAX_TRIGGERS = 10;
@@ -2287,45 +2518,45 @@ var AUTOMATION_STEP_KINDS = [
2287
2518
  "webhook",
2288
2519
  "notify"
2289
2520
  ];
2290
- var AutomationStepKind = import_zod9.z.enum(AUTOMATION_STEP_KINDS);
2521
+ var AutomationStepKind = import_zod10.z.enum(AUTOMATION_STEP_KINDS);
2291
2522
  var next = { next: StepId.nullable() };
2292
- var Unchosen = import_zod9.z.literal("");
2293
- var DraftSlug = import_zod9.z.union([Slug, Unchosen]);
2294
- var DraftPropertyKey = import_zod9.z.union([ContactPropertyKey, Unchosen]);
2295
- var label2 = { label: import_zod9.z.string().max(120).nullish() };
2296
- var EmailStepLanguage = import_zod9.z.object({
2297
- subject: import_zod9.z.string().min(1).max(998),
2298
- preheader: import_zod9.z.string().max(500).nullable(),
2523
+ var Unchosen = import_zod10.z.literal("");
2524
+ var DraftSlug = import_zod10.z.union([Slug, Unchosen]);
2525
+ var DraftPropertyKey = import_zod10.z.union([ContactPropertyKey, Unchosen]);
2526
+ var label2 = { label: import_zod10.z.string().max(120).nullish() };
2527
+ var EmailStepLanguage = import_zod10.z.object({
2528
+ subject: import_zod10.z.string().min(1).max(998),
2529
+ preheader: import_zod10.z.string().max(500).nullable(),
2299
2530
  document: TemplateDocument,
2300
2531
  /** This language's insertions, its texts over the template's structure (every text present). */
2301
2532
  insertions: Insertions.nullish()
2302
2533
  }).strict();
2303
- var EmailStep = import_zod9.z.object({
2304
- kind: import_zod9.z.literal("email"),
2534
+ var EmailStep = import_zod10.z.object({
2535
+ kind: import_zod10.z.literal("email"),
2305
2536
  ...label2,
2306
2537
  ...next,
2307
2538
  template_id: Id.nullish(),
2308
2539
  document: TemplateDocument.nullish(),
2309
2540
  /** Empty while the step is being written, or when its template has a subject; else `not_chosen` refuses to publish it. */
2310
- subject: import_zod9.z.string().max(998),
2311
- preheader: import_zod9.z.string().max(500).nullish(),
2541
+ subject: import_zod10.z.string().max(998),
2542
+ preheader: import_zod10.z.string().max(500).nullish(),
2312
2543
  locale: LocaleTag.nullish(),
2313
- languages: import_zod9.z.record(LocaleTag, EmailStepLanguage).nullish(),
2544
+ languages: import_zod10.z.record(LocaleTag, EmailStepLanguage).nullish(),
2314
2545
  /** The main language's insertions, snapshot from the template when the automation is published. */
2315
2546
  insertions: Insertions.nullish()
2316
2547
  }).strict();
2317
- var DelayStep = import_zod9.z.object({
2318
- kind: import_zod9.z.literal("delay"),
2548
+ var DelayStep = import_zod10.z.object({
2549
+ kind: import_zod10.z.literal("delay"),
2319
2550
  ...label2,
2320
2551
  ...next,
2321
- wait: import_zod9.z.discriminatedUnion("mode", [
2322
- import_zod9.z.object({ mode: import_zod9.z.literal("duration"), seconds: import_zod9.z.number().int().min(1).max(MAX_DELAY_SECONDS) }).strict(),
2323
- import_zod9.z.object({ mode: import_zod9.z.literal("time_of_day"), at: TimeOfDay }).strict(),
2324
- import_zod9.z.object({ mode: import_zod9.z.literal("weekday"), weekday: Weekday, at: TimeOfDay }).strict(),
2552
+ wait: import_zod10.z.discriminatedUnion("mode", [
2553
+ import_zod10.z.object({ mode: import_zod10.z.literal("duration"), seconds: import_zod10.z.number().int().min(1).max(MAX_DELAY_SECONDS) }).strict(),
2554
+ import_zod10.z.object({ mode: import_zod10.z.literal("time_of_day"), at: TimeOfDay }).strict(),
2555
+ import_zod10.z.object({ mode: import_zod10.z.literal("weekday"), weekday: Weekday, at: TimeOfDay }).strict(),
2325
2556
  /** A fixed day has no next occurrence, so `continue` is not one of its answers. */
2326
- import_zod9.z.object({ mode: import_zod9.z.literal("date"), on: DateOnly, at: TimeOfDay, passed: import_zod9.z.enum(["skip", "stop"]) }).strict(),
2327
- import_zod9.z.object({
2328
- mode: import_zod9.z.literal("date_property"),
2557
+ import_zod10.z.object({ mode: import_zod10.z.literal("date"), on: DateOnly, at: TimeOfDay, passed: import_zod10.z.enum(["skip", "stop"]) }).strict(),
2558
+ import_zod10.z.object({
2559
+ mode: import_zod10.z.literal("date_property"),
2329
2560
  key: ContactPropertyKey,
2330
2561
  offset_days: OffsetDays,
2331
2562
  at: TimeOfDay,
@@ -2333,8 +2564,8 @@ var DelayStep = import_zod9.z.object({
2333
2564
  }).strict()
2334
2565
  ])
2335
2566
  }).strict();
2336
- var ConditionStep = import_zod9.z.object({
2337
- kind: import_zod9.z.literal("condition"),
2567
+ var ConditionStep = import_zod10.z.object({
2568
+ kind: import_zod10.z.literal("condition"),
2338
2569
  ...label2,
2339
2570
  filter: BoundedAutomationFilter,
2340
2571
  yes: StepId.nullable(),
@@ -2345,49 +2576,49 @@ var ConditionStep = import_zod9.z.object({
2345
2576
  * neither half means anything without the other: a window with no answer
2346
2577
  * for the end of it would be a silent decision.
2347
2578
  */
2348
- wait_for: import_zod9.z.object({ up_to_s: import_zod9.z.number().int().min(1).max(MAX_DELAY_SECONDS), on_timeout: import_zod9.z.enum(["yes", "no"]) }).strict().nullish()
2579
+ wait_for: import_zod10.z.object({ up_to_s: import_zod10.z.number().int().min(1).max(MAX_DELAY_SECONDS), on_timeout: import_zod10.z.enum(["yes", "no"]) }).strict().nullish()
2349
2580
  }).strict();
2350
- var SplitBranchKey = import_zod9.z.string().regex(/^[A-Za-z0-9_-]{1,32}$/, "letters, digits, underscore and hyphen, 1 to 32");
2581
+ var SplitBranchKey = import_zod10.z.string().regex(/^[A-Za-z0-9_-]{1,32}$/, "letters, digits, underscore and hyphen, 1 to 32");
2351
2582
  var MIN_SPLIT_BRANCHES = 2;
2352
2583
  var MAX_SPLIT_BRANCHES = 4;
2353
- var SplitStep = import_zod9.z.object({
2354
- kind: import_zod9.z.literal("split"),
2584
+ var SplitStep = import_zod10.z.object({
2585
+ kind: import_zod10.z.literal("split"),
2355
2586
  ...label2,
2356
- branches: import_zod9.z.array(
2357
- import_zod9.z.object({
2587
+ branches: import_zod10.z.array(
2588
+ import_zod10.z.object({
2358
2589
  key: SplitBranchKey,
2359
2590
  /** A whole percentage. Zero is allowed: a branch kept in the flow but switched off. */
2360
- weight: import_zod9.z.number().int().min(0).max(100),
2591
+ weight: import_zod10.z.number().int().min(0).max(100),
2361
2592
  next: StepId.nullable()
2362
2593
  }).strict()
2363
2594
  ).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")
2364
2595
  }).strict();
2365
- var GotoStep = import_zod9.z.object({ kind: import_zod9.z.literal("goto"), ...label2, target: StepId.nullable() }).strict();
2596
+ var GotoStep = import_zod10.z.object({ kind: import_zod10.z.literal("goto"), ...label2, target: StepId.nullable() }).strict();
2366
2597
  var MAX_STEP_VISITS = 20;
2367
- var WebhookStep = import_zod9.z.object({ kind: import_zod9.z.literal("webhook"), ...label2, ...next, endpoint_id: Id.nullable(), payload: JsonValue.nullish() }).strict();
2368
- var NotifyRecipients = import_zod9.z.union([import_zod9.z.literal("owner"), import_zod9.z.literal("admins"), import_zod9.z.object({ member_id: Id }).strict()]);
2369
- var NotifyStep = import_zod9.z.object({
2370
- kind: import_zod9.z.literal("notify"),
2598
+ var WebhookStep = import_zod10.z.object({ kind: import_zod10.z.literal("webhook"), ...label2, ...next, endpoint_id: Id.nullable(), payload: JsonValue.nullish() }).strict();
2599
+ var NotifyRecipients = import_zod10.z.union([import_zod10.z.literal("owner"), import_zod10.z.literal("admins"), import_zod10.z.object({ member_id: Id }).strict()]);
2600
+ var NotifyStep = import_zod10.z.object({
2601
+ kind: import_zod10.z.literal("notify"),
2371
2602
  ...label2,
2372
2603
  ...next,
2373
2604
  to: NotifyRecipients,
2374
2605
  /** Empty while the step is being written; `not_chosen` refuses to publish it. */
2375
- subject: import_zod9.z.string().max(998),
2376
- body: import_zod9.z.string().max(1e4)
2606
+ subject: import_zod10.z.string().max(998),
2607
+ body: import_zod10.z.string().max(1e4)
2377
2608
  }).strict();
2378
- var AutomationStep = import_zod9.z.discriminatedUnion("kind", [
2609
+ var AutomationStep = import_zod10.z.discriminatedUnion("kind", [
2379
2610
  EmailStep,
2380
2611
  DelayStep,
2381
2612
  ConditionStep,
2382
- import_zod9.z.object({ kind: import_zod9.z.literal("add_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
2383
- import_zod9.z.object({ kind: import_zod9.z.literal("remove_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
2613
+ import_zod10.z.object({ kind: import_zod10.z.literal("add_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
2614
+ import_zod10.z.object({ kind: import_zod10.z.literal("remove_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
2384
2615
  /** `value` null clears the property, as a contact upsert does. */
2385
- import_zod9.z.object({ kind: import_zod9.z.literal("set_property"), ...label2, ...next, key: DraftPropertyKey, value: JsonValue }).strict(),
2616
+ import_zod10.z.object({ kind: import_zod10.z.literal("set_property"), ...label2, ...next, key: DraftPropertyKey, value: JsonValue }).strict(),
2386
2617
  /** Subscribing never lifts a suppression: the service checks that, not the flow. */
2387
- import_zod9.z.object({ kind: import_zod9.z.literal("subscribe_topic"), ...label2, ...next, topic: DraftSlug }).strict(),
2618
+ import_zod10.z.object({ kind: import_zod10.z.literal("subscribe_topic"), ...label2, ...next, topic: DraftSlug }).strict(),
2388
2619
  /** `topic` unsubscribes from the automation's own topic, `all` from every topic. */
2389
- import_zod9.z.object({ kind: import_zod9.z.literal("unsubscribe"), ...label2, ...next, scope: import_zod9.z.enum(["topic", "all"]) }).strict(),
2390
- import_zod9.z.object({ kind: import_zod9.z.literal("exit"), ...label2 }).strict(),
2620
+ import_zod10.z.object({ kind: import_zod10.z.literal("unsubscribe"), ...label2, ...next, scope: import_zod10.z.enum(["topic", "all"]) }).strict(),
2621
+ import_zod10.z.object({ kind: import_zod10.z.literal("exit"), ...label2 }).strict(),
2391
2622
  SplitStep,
2392
2623
  GotoStep,
2393
2624
  WebhookStep,
@@ -2411,25 +2642,25 @@ function stepTargets(step) {
2411
2642
  }
2412
2643
  }
2413
2644
  var MAX_STEPS = 200;
2414
- var AutomationFlow = import_zod9.z.object({
2415
- triggers: import_zod9.z.array(AutomationTrigger).max(MAX_TRIGGERS),
2645
+ var AutomationFlow = import_zod10.z.object({
2646
+ triggers: import_zod10.z.array(AutomationTrigger).max(MAX_TRIGGERS),
2416
2647
  /** The first step. `null` is an empty flow. */
2417
2648
  entry: StepId.nullable(),
2418
- steps: import_zod9.z.record(StepId, AutomationStep)
2649
+ steps: import_zod10.z.record(StepId, AutomationStep)
2419
2650
  }).strict();
2420
2651
  var emptyFlow = () => ({ triggers: [], entry: null, steps: {} });
2421
- var QuietHours = import_zod9.z.object({
2652
+ var QuietHours = import_zod10.z.object({
2422
2653
  start: TimeOfDay,
2423
2654
  end: TimeOfDay,
2424
- weekdays: import_zod9.z.array(Weekday).min(1).max(7).nullish()
2655
+ weekdays: import_zod10.z.array(Weekday).min(1).max(7).nullish()
2425
2656
  }).strict();
2426
2657
  var RE_ENTRY_MODES = ["off", "after_exit"];
2427
- var ReEntryMode = import_zod9.z.enum(RE_ENTRY_MODES);
2658
+ var ReEntryMode = import_zod10.z.enum(RE_ENTRY_MODES);
2428
2659
  var MAX_RE_ENTRY_COOLDOWN_SECONDS = 365 * 24 * 60 * 60;
2429
- var AutomationSettings = import_zod9.z.object({
2660
+ var AutomationSettings = import_zod10.z.object({
2430
2661
  re_entry: ReEntryMode,
2431
2662
  /** Seconds a person must wait after leaving before entering again. Only with `after_exit`. */
2432
- re_entry_cooldown_s: import_zod9.z.number().int().min(0).max(MAX_RE_ENTRY_COOLDOWN_SECONDS).nullish(),
2663
+ re_entry_cooldown_s: import_zod10.z.number().int().min(0).max(MAX_RE_ENTRY_COOLDOWN_SECONDS).nullish(),
2433
2664
  quiet_hours: QuietHours.nullish(),
2434
2665
  /** Checked before every step; when it matches, the run ends. */
2435
2666
  exit_filter: BoundedAutomationFilter.nullish()
@@ -2487,18 +2718,18 @@ var AUTOMATION_ISSUE_CODES = [
2487
2718
  /** A one-off date that is already over everywhere on earth, so it would fire for nobody. */
2488
2719
  "date_in_the_past"
2489
2720
  ];
2490
- var AutomationIssueCode = import_zod9.z.enum(AUTOMATION_ISSUE_CODES);
2491
- var AutomationIssue = import_zod9.z.object({
2721
+ var AutomationIssueCode = import_zod10.z.enum(AUTOMATION_ISSUE_CODES);
2722
+ var AutomationIssue = import_zod10.z.object({
2492
2723
  code: AutomationIssueCode,
2493
2724
  /** The step the issue is about, when it is about one. */
2494
2725
  step_id: StepId.nullable(),
2495
2726
  /** Where inside the document, for the canvas to point at a field. */
2496
- path: import_zod9.z.array(import_zod9.z.union([import_zod9.z.string(), import_zod9.z.number()])),
2497
- message: import_zod9.z.string()
2727
+ path: import_zod10.z.array(import_zod10.z.union([import_zod10.z.string(), import_zod10.z.number()])),
2728
+ message: import_zod10.z.string()
2498
2729
  });
2499
- var AutomationValidation = import_zod9.z.object({
2500
- ok: import_zod9.z.boolean(),
2501
- issues: import_zod9.z.array(AutomationIssue)
2730
+ var AutomationValidation = import_zod10.z.object({
2731
+ ok: import_zod10.z.boolean(),
2732
+ issues: import_zod10.z.array(AutomationIssue)
2502
2733
  });
2503
2734
  function validateAutomation(flow, settings, ctx) {
2504
2735
  const issues = [];
@@ -2889,7 +3120,7 @@ function cycles(flow) {
2889
3120
  return out.sort();
2890
3121
  }
2891
3122
  var AUTOMATION_STATUSES = ["draft", "active", "paused", "archived"];
2892
- var AutomationStatus = import_zod9.z.enum(AUTOMATION_STATUSES);
3123
+ var AutomationStatus = import_zod10.z.enum(AUTOMATION_STATUSES);
2893
3124
  var AUTOMATION_END_REASONS = [
2894
3125
  "completed",
2895
3126
  "exit_filter",
@@ -2908,9 +3139,9 @@ var AUTOMATION_END_REASONS = [
2908
3139
  "ended_by_hand",
2909
3140
  "failed"
2910
3141
  ];
2911
- var AutomationEndReason = import_zod9.z.enum(AUTOMATION_END_REASONS);
3142
+ var AutomationEndReason = import_zod10.z.enum(AUTOMATION_END_REASONS);
2912
3143
  var AUTOMATION_WAIT_REASONS = ["delay", "quiet_hours", "plan_limit", "sending", "condition"];
2913
- var AutomationWaitReason = import_zod9.z.enum(AUTOMATION_WAIT_REASONS);
3144
+ var AutomationWaitReason = import_zod10.z.enum(AUTOMATION_WAIT_REASONS);
2914
3145
  var AUTOMATION_ENTRY_REFUSALS = [
2915
3146
  "already_inside",
2916
3147
  "re_entry_off",
@@ -2921,26 +3152,26 @@ var AUTOMATION_ENTRY_REFUSALS = [
2921
3152
  "not_active",
2922
3153
  "unknown_contact"
2923
3154
  ];
2924
- var AutomationEntryRefusal = import_zod9.z.enum(AUTOMATION_ENTRY_REFUSALS);
2925
- var AutomationCounts = import_zod9.z.object({
2926
- started: import_zod9.z.number().int().min(0),
2927
- in_progress: import_zod9.z.number().int().min(0),
2928
- completed: import_zod9.z.number().int().min(0),
2929
- exited: import_zod9.z.number().int().min(0),
2930
- failed: import_zod9.z.number().int().min(0)
2931
- });
2932
- var Automation = import_zod9.z.object({
3155
+ var AutomationEntryRefusal = import_zod10.z.enum(AUTOMATION_ENTRY_REFUSALS);
3156
+ var AutomationCounts = import_zod10.z.object({
3157
+ started: import_zod10.z.number().int().min(0),
3158
+ in_progress: import_zod10.z.number().int().min(0),
3159
+ completed: import_zod10.z.number().int().min(0),
3160
+ exited: import_zod10.z.number().int().min(0),
3161
+ failed: import_zod10.z.number().int().min(0)
3162
+ });
3163
+ var Automation = import_zod10.z.object({
2933
3164
  id: Id,
2934
- name: import_zod9.z.string().min(1).max(200),
3165
+ name: import_zod10.z.string().min(1).max(200),
2935
3166
  status: AutomationStatus,
2936
3167
  /** Every automation sends under one topic; there are no transactional automations. */
2937
3168
  topic: Slug,
2938
3169
  provider_id: Id.nullable(),
2939
3170
  settings: AutomationSettings,
2940
3171
  /** The flow people are running through, null while the automation has never been published. */
2941
- published_version: import_zod9.z.number().int().min(1).nullable(),
3172
+ published_version: import_zod10.z.number().int().min(1).nullable(),
2942
3173
  /** The flow being edited. Increments on every save, like a template's version. */
2943
- draft_version: import_zod9.z.number().int().min(1),
3174
+ draft_version: import_zod10.z.number().int().min(1),
2944
3175
  counts: AutomationCounts,
2945
3176
  created_at: Timestamp,
2946
3177
  updated_at: Timestamp,
@@ -2953,16 +3184,16 @@ var AutomationWithFlow = Automation.extend({
2953
3184
  published_flow: AutomationFlow.nullable()
2954
3185
  });
2955
3186
  var AutomationSummary = Automation;
2956
- var AutomationCreate = import_zod9.z.object({
2957
- name: import_zod9.z.string().min(1).max(200),
3187
+ var AutomationCreate = import_zod10.z.object({
3188
+ name: import_zod10.z.string().min(1).max(200),
2958
3189
  topic: Slug,
2959
3190
  provider_id: Id.optional(),
2960
3191
  flow: AutomationFlow.optional(),
2961
3192
  settings: AutomationSettings.partial().optional()
2962
3193
  });
2963
- var AutomationUpdate = import_zod9.z.object({
2964
- base_version: import_zod9.z.number().int().min(1),
2965
- name: import_zod9.z.string().min(1).max(200).optional(),
3194
+ var AutomationUpdate = import_zod10.z.object({
3195
+ base_version: import_zod10.z.number().int().min(1),
3196
+ name: import_zod10.z.string().min(1).max(200).optional(),
2966
3197
  topic: Slug.optional(),
2967
3198
  provider_id: Id.optional(),
2968
3199
  flow: AutomationFlow.optional(),
@@ -2975,42 +3206,42 @@ var AutomationListQuery = PageQuery.extend({
2975
3206
  status: AutomationStatus.optional(),
2976
3207
  topic: Slug.optional()
2977
3208
  });
2978
- var AutomationPublishRequest = import_zod9.z.object({
3209
+ var AutomationPublishRequest = import_zod10.z.object({
2979
3210
  /**
2980
3211
  * Answer what this publish would do and change nothing, whatever the flow
2981
3212
  * looks like. Without it a publish that has no issues and moves nobody
2982
3213
  * simply goes ahead, which is right for an API caller and wrong for a
2983
3214
  * dialog that is only showing somebody what they are about to do.
2984
3215
  */
2985
- dry_run: import_zod9.z.boolean().optional(),
2986
- confirm: import_zod9.z.boolean().optional(),
3216
+ dry_run: import_zod10.z.boolean().optional(),
3217
+ confirm: import_zod10.z.boolean().optional(),
2987
3218
  /** Per removed step: the step its waiting runs move to, or null to end them. */
2988
- moves: import_zod9.z.record(StepId, StepId.nullable()).optional(),
3219
+ moves: import_zod10.z.record(StepId, StepId.nullable()).optional(),
2989
3220
  /** Also enter everyone who matches a trigger's condition right now. */
2990
- backfill: import_zod9.z.boolean().optional()
3221
+ backfill: import_zod10.z.boolean().optional()
2991
3222
  }).strict();
2992
- var AutomationPublishMove = import_zod9.z.object({
3223
+ var AutomationPublishMove = import_zod10.z.object({
2993
3224
  step_id: StepId,
2994
3225
  /** Why the step's people have to move: it is gone, or its delay changed. */
2995
- change: import_zod9.z.enum(["removed", "delay_changed", "kind_changed"]),
2996
- waiting: import_zod9.z.number().int().min(0),
3226
+ change: import_zod10.z.enum(["removed", "delay_changed", "kind_changed"]),
3227
+ waiting: import_zod10.z.number().int().min(0),
2997
3228
  /** Where they go: a step id, or null to end their runs with `step_removed`. */
2998
3229
  destination: StepId.nullable()
2999
3230
  });
3000
- var AutomationPublishResult = import_zod9.z.object({
3001
- published: import_zod9.z.boolean(),
3231
+ var AutomationPublishResult = import_zod10.z.object({
3232
+ published: import_zod10.z.boolean(),
3002
3233
  automation: Automation,
3003
3234
  /** Empty when nothing has to move; non-empty and `published` false asks for a confirmation. */
3004
- moves: import_zod9.z.array(AutomationPublishMove),
3235
+ moves: import_zod10.z.array(AutomationPublishMove),
3005
3236
  /** How many people the backfill entered, or would enter when it is not confirmed. */
3006
- backfill: import_zod9.z.number().int().min(0),
3007
- issues: import_zod9.z.array(AutomationIssue)
3008
- });
3009
- var AutomationDuplicateRequest = import_zod9.z.object({ name: import_zod9.z.string().min(1).max(200).optional() }).strict();
3010
- var AutomationEnrollRequest = import_zod9.z.object({
3011
- contact_ids: import_zod9.z.array(Id).min(1).max(1e3).optional(),
3012
- external_ids: import_zod9.z.array(import_zod9.z.string().min(1).max(255)).min(1).max(1e3).optional(),
3013
- emails: import_zod9.z.array(Email).min(1).max(1e3).optional(),
3237
+ backfill: import_zod10.z.number().int().min(0),
3238
+ issues: import_zod10.z.array(AutomationIssue)
3239
+ });
3240
+ var AutomationDuplicateRequest = import_zod10.z.object({ name: import_zod10.z.string().min(1).max(200).optional() }).strict();
3241
+ var AutomationEnrollRequest = import_zod10.z.object({
3242
+ contact_ids: import_zod10.z.array(Id).min(1).max(1e3).optional(),
3243
+ external_ids: import_zod10.z.array(import_zod10.z.string().min(1).max(255)).min(1).max(1e3).optional(),
3244
+ emails: import_zod10.z.array(Email).min(1).max(1e3).optional(),
3014
3245
  segment_id: Id.optional(),
3015
3246
  /** Where to start them; the flow's entry step by default. */
3016
3247
  step_id: StepId.optional()
@@ -3018,34 +3249,34 @@ var AutomationEnrollRequest = import_zod9.z.object({
3018
3249
  (v) => [v.contact_ids, v.external_ids, v.emails, v.segment_id].filter((x) => x !== void 0).length === 1,
3019
3250
  "name the people exactly one way: contact_ids, external_ids, emails or segment_id"
3020
3251
  );
3021
- var AutomationEnrollment = import_zod9.z.object({
3252
+ var AutomationEnrollment = import_zod10.z.object({
3022
3253
  contact_id: Id.nullable(),
3023
3254
  email: Email.nullable(),
3024
- external_id: import_zod9.z.string().nullable(),
3025
- entered: import_zod9.z.boolean(),
3255
+ external_id: import_zod10.z.string().nullable(),
3256
+ entered: import_zod10.z.boolean(),
3026
3257
  run_id: Id.nullable(),
3027
3258
  reason: AutomationEntryRefusal.nullable()
3028
3259
  });
3029
- var AutomationEnrollResult = import_zod9.z.object({
3030
- entered: import_zod9.z.number().int().min(0),
3031
- refused: import_zod9.z.number().int().min(0),
3032
- results: import_zod9.z.array(AutomationEnrollment)
3260
+ var AutomationEnrollResult = import_zod10.z.object({
3261
+ entered: import_zod10.z.number().int().min(0),
3262
+ refused: import_zod10.z.number().int().min(0),
3263
+ results: import_zod10.z.array(AutomationEnrollment)
3033
3264
  });
3034
- var AutomationRunStatus = import_zod9.z.enum(["active", "waiting", "completed", "exited", "failed"]);
3035
- var AutomationRun = import_zod9.z.object({
3265
+ var AutomationRunStatus = import_zod10.z.enum(["active", "waiting", "completed", "exited", "failed"]);
3266
+ var AutomationRun = import_zod10.z.object({
3036
3267
  id: Id,
3037
3268
  automation_id: Id,
3038
3269
  contact_id: Id,
3039
3270
  email: Email,
3040
- external_id: import_zod9.z.string().nullable(),
3041
- version: import_zod9.z.number().int().min(1),
3271
+ external_id: import_zod10.z.string().nullable(),
3272
+ version: import_zod10.z.number().int().min(1),
3042
3273
  status: AutomationRunStatus,
3043
3274
  current_step_id: StepId.nullable(),
3044
3275
  next_action_at: Timestamp.nullable(),
3045
3276
  wait_reason: AutomationWaitReason.nullable(),
3046
- end_reason: import_zod9.z.string().nullable(),
3277
+ end_reason: import_zod10.z.string().nullable(),
3047
3278
  /** What went wrong the last time this run tried to take its step, null otherwise. */
3048
- last_error: import_zod9.z.string().nullable(),
3279
+ last_error: import_zod10.z.string().nullable(),
3049
3280
  entered_at: Timestamp,
3050
3281
  ended_at: Timestamp.nullable()
3051
3282
  });
@@ -3055,13 +3286,13 @@ var AutomationRunListQuery = PageQuery.extend({
3055
3286
  contact_id: Id.optional()
3056
3287
  });
3057
3288
  var ContactAutomationRun = AutomationRun.extend({
3058
- automation: import_zod9.z.object({ id: Id, name: import_zod9.z.string(), status: AutomationStatus })
3289
+ automation: import_zod10.z.object({ id: Id, name: import_zod10.z.string(), status: AutomationStatus })
3059
3290
  });
3060
3291
  var ContactAutomationListQuery = PageQuery.extend({ status: AutomationRunStatus.optional() });
3061
- var AutomationStepExecution = import_zod9.z.object({
3292
+ var AutomationStepExecution = import_zod10.z.object({
3062
3293
  step_id: StepId,
3063
3294
  step_kind: AutomationStepKind,
3064
- visit: import_zod9.z.number().int().min(1),
3295
+ visit: import_zod10.z.number().int().min(1),
3065
3296
  started_at: Timestamp,
3066
3297
  finished_at: Timestamp.nullable(),
3067
3298
  /**
@@ -3073,48 +3304,48 @@ var AutomationStepExecution = import_zod9.z.object({
3073
3304
  */
3074
3305
  outcome: Properties
3075
3306
  });
3076
- var AutomationJourney = import_zod9.z.object({
3307
+ var AutomationJourney = import_zod10.z.object({
3077
3308
  run: AutomationRun,
3078
- steps: import_zod9.z.array(AutomationStepExecution)
3309
+ steps: import_zod10.z.array(AutomationStepExecution)
3079
3310
  });
3080
- var AutomationStepReport = import_zod9.z.object({
3311
+ var AutomationStepReport = import_zod10.z.object({
3081
3312
  step_id: StepId,
3082
3313
  step_kind: AutomationStepKind,
3083
- reached: import_zod9.z.number().int().min(0),
3084
- waiting: import_zod9.z.number().int().min(0),
3085
- passed: import_zod9.z.number().int().min(0),
3314
+ reached: import_zod10.z.number().int().min(0),
3315
+ waiting: import_zod10.z.number().int().min(0),
3316
+ passed: import_zod10.z.number().int().min(0),
3086
3317
  /** Per branch, for a condition: how many took `yes` and how many `no`. */
3087
- branches: import_zod9.z.record(import_zod9.z.number().int().min(0)),
3318
+ branches: import_zod10.z.record(import_zod10.z.number().int().min(0)),
3088
3319
  /** The step mailing's id, for an email step of the published version. */
3089
3320
  mailing_id: Id.nullable()
3090
3321
  });
3091
- var AutomationReport = import_zod9.z.object({
3322
+ var AutomationReport = import_zod10.z.object({
3092
3323
  counts: AutomationCounts,
3093
3324
  /** Why the people who left did: `AutomationEndReason` to a count. */
3094
- end_reasons: import_zod9.z.record(import_zod9.z.number().int().min(0)),
3325
+ end_reasons: import_zod10.z.record(import_zod10.z.number().int().min(0)),
3095
3326
  /**
3096
3327
  * Why people a trigger named did not enter: `AutomationEntryRefusal` to a
3097
3328
  * count. Without it a pause, an exclusion or a missing subscription would
3098
3329
  * turn people away invisibly.
3099
3330
  */
3100
- refusals: import_zod9.z.record(import_zod9.z.number().int().min(0)),
3101
- steps: import_zod9.z.array(AutomationStepReport)
3102
- });
3103
- var AutomationExitRunRequest = import_zod9.z.object({ reason: import_zod9.z.string().max(200).optional() }).strict();
3104
- var AutomationRunParams = import_zod9.z.object({ id: Id, run_id: Id });
3105
- var AutomationStepParams = import_zod9.z.object({ id: Id, step_id: StepId });
3106
- var AutomationTestEmailRequest = import_zod9.z.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
3107
- var AutomationValidateRequest = import_zod9.z.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
3108
- var EventCreate = import_zod9.z.object({
3331
+ refusals: import_zod10.z.record(import_zod10.z.number().int().min(0)),
3332
+ steps: import_zod10.z.array(AutomationStepReport)
3333
+ });
3334
+ var AutomationExitRunRequest = import_zod10.z.object({ reason: import_zod10.z.string().max(200).optional() }).strict();
3335
+ var AutomationRunParams = import_zod10.z.object({ id: Id, run_id: Id });
3336
+ var AutomationStepParams = import_zod10.z.object({ id: Id, step_id: StepId });
3337
+ var AutomationTestEmailRequest = import_zod10.z.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
3338
+ var AutomationValidateRequest = import_zod10.z.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
3339
+ var EventCreate = import_zod10.z.object({
3109
3340
  name: EventName,
3110
- contact: import_zod9.z.object({ external_id: import_zod9.z.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"),
3341
+ contact: import_zod10.z.object({ external_id: import_zod10.z.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"),
3111
3342
  data: Properties.optional(),
3112
3343
  occurred_at: Timestamp.optional(),
3113
- id: import_zod9.z.string().min(1).max(128).optional()
3344
+ id: import_zod10.z.string().min(1).max(128).optional()
3114
3345
  }).strict();
3115
- var Event = import_zod9.z.object({
3346
+ var Event = import_zod10.z.object({
3116
3347
  id: Id,
3117
- client_event_id: import_zod9.z.string().nullable(),
3348
+ client_event_id: import_zod10.z.string().nullable(),
3118
3349
  name: EventName,
3119
3350
  contact_id: Id,
3120
3351
  data: Properties,
@@ -3125,7 +3356,7 @@ var Event = import_zod9.z.object({
3125
3356
  * hand. Each is then admitted or refused by the runtime on its own rules
3126
3357
  * (consent, exclusions, re-entry), which `automations.report` counts.
3127
3358
  */
3128
- entered: import_zod9.z.number().int().min(0)
3359
+ entered: import_zod10.z.number().int().min(0)
3129
3360
  });
3130
3361
  var EventListQuery = PageQuery.extend({
3131
3362
  name: EventName.optional(),
@@ -3133,19 +3364,15 @@ var EventListQuery = PageQuery.extend({
3133
3364
  });
3134
3365
 
3135
3366
  // src/workspace.ts
3136
- var CompanyId = import_zod10.z.string().min(1).max(64);
3367
+ var CompanyId = import_zod11.z.string().min(1).max(64);
3137
3368
  var ASSET_POLICIES = ["any", "service_only"];
3138
- var AssetPolicy = import_zod10.z.enum(ASSET_POLICIES);
3369
+ var AssetPolicy = import_zod11.z.enum(ASSET_POLICIES);
3139
3370
  var MAX_ALLOWED_ASSET_HOSTS = 20;
3140
- var AssetHost = import_zod10.z.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");
3141
- var MAX_MERGE_DEFAULTS = 50;
3142
- var MAX_MERGE_DEFAULT_LENGTH = 2e3;
3143
- var MergeFieldName = import_zod10.z.string().regex(/^[a-z][a-z0-9_]*$/, "a merge-field name: lowercase letters, digits and underscores, starting with a letter").max(64);
3144
- var MergeDefaultValue = import_zod10.z.union([import_zod10.z.string().max(MAX_MERGE_DEFAULT_LENGTH), import_zod10.z.number().finite(), import_zod10.z.boolean()]);
3145
- var MergeDefaults = import_zod10.z.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), {
3371
+ var AssetHost = import_zod11.z.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");
3372
+ var MergeDefaults = import_zod11.z.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), {
3146
3373
  message: `a reserved merge field (${Object.keys(RESERVED_MERGE_FIELDS).join(", ")}) cannot have a workspace default`
3147
3374
  });
3148
- var WorkspaceSettings = import_zod10.z.object({
3375
+ var WorkspaceSettings = import_zod11.z.object({
3149
3376
  /**
3150
3377
  * The workspace's main language (a {@link LocaleTag}, e.g. "de"): the main
3151
3378
  * language of a new template, and of the hosted pages when nothing else
@@ -3158,9 +3385,9 @@ var WorkspaceSettings = import_zod10.z.object({
3158
3385
  * each; the hosted pages are offered in those of them they support (English,
3159
3386
  * German, French, Italian, Spanish). The service stores canonical casing.
3160
3387
  */
3161
- locales: import_zod10.z.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
3388
+ locales: import_zod11.z.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
3162
3389
  /** Open and click tracking. Off by default, opt-in per workspace. */
3163
- tracking_enabled: import_zod10.z.boolean(),
3390
+ tracking_enabled: import_zod11.z.boolean(),
3164
3391
  /** Where images, stylesheets and fonts in a mail may load from. `any` by default. */
3165
3392
  asset_policy: AssetPolicy,
3166
3393
  /**
@@ -3168,7 +3395,7 @@ var WorkspaceSettings = import_zod10.z.object({
3168
3395
  * the workspace's website, typically. Empty by default. Ignored under `any`,
3169
3396
  * which allows everything already.
3170
3397
  */
3171
- allowed_asset_hosts: import_zod10.z.array(AssetHost).max(MAX_ALLOWED_ASSET_HOSTS),
3398
+ allowed_asset_hosts: import_zod11.z.array(AssetHost).max(MAX_ALLOWED_ASSET_HOSTS),
3172
3399
  /** Merge values every mail of the workspace can use (see `MergeDefaults`). Empty by default. */
3173
3400
  merge_defaults: MergeDefaults,
3174
3401
  /**
@@ -3177,10 +3404,10 @@ var WorkspaceSettings = import_zod10.z.object({
3177
3404
  */
3178
3405
  default_timezone: TimezoneName.nullable()
3179
3406
  });
3180
- var Workspace = import_zod10.z.object({
3407
+ var Workspace = import_zod11.z.object({
3181
3408
  id: Id,
3182
3409
  slug: Slug,
3183
- name: import_zod10.z.string().min(1).max(120),
3410
+ name: import_zod11.z.string().min(1).max(120),
3184
3411
  settings: WorkspaceSettings,
3185
3412
  /**
3186
3413
  * The auth-brain company (tenant) the workspace was created for, or null for
@@ -3191,13 +3418,13 @@ var Workspace = import_zod10.z.object({
3191
3418
  created_at: Timestamp,
3192
3419
  updated_at: Timestamp
3193
3420
  });
3194
- var WorkspaceCreate = import_zod10.z.object({
3421
+ var WorkspaceCreate = import_zod11.z.object({
3195
3422
  slug: Slug,
3196
- name: import_zod10.z.string().min(1).max(120),
3423
+ name: import_zod11.z.string().min(1).max(120),
3197
3424
  settings: WorkspaceSettings.partial().optional(),
3198
- owner: import_zod10.z.object({
3425
+ owner: import_zod11.z.object({
3199
3426
  email: Email,
3200
- name: import_zod10.z.string().max(200).nullable().optional()
3427
+ name: import_zod11.z.string().max(200).nullable().optional()
3201
3428
  }),
3202
3429
  /**
3203
3430
  * The signed-in person's active auth-brain company. The dashboard always
@@ -3207,49 +3434,49 @@ var WorkspaceCreate = import_zod10.z.object({
3207
3434
  */
3208
3435
  company_id: CompanyId.optional()
3209
3436
  });
3210
- var WorkspaceUpdate = import_zod10.z.object({
3211
- name: import_zod10.z.string().min(1).max(120),
3437
+ var WorkspaceUpdate = import_zod11.z.object({
3438
+ name: import_zod11.z.string().min(1).max(120),
3212
3439
  settings: WorkspaceSettings.partial()
3213
3440
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
3214
- var WorkspaceMove = import_zod10.z.object({ company_id: CompanyId });
3441
+ var WorkspaceMove = import_zod11.z.object({ company_id: CompanyId });
3215
3442
  var MEMBER_ROLES = ["owner", "admin", "editor", "viewer"];
3216
- var MemberRole = import_zod10.z.enum(MEMBER_ROLES);
3443
+ var MemberRole = import_zod11.z.enum(MEMBER_ROLES);
3217
3444
  var WorkspaceMembership = Workspace.extend({ role: MemberRole });
3218
- var Member = import_zod10.z.object({
3445
+ var Member = import_zod11.z.object({
3219
3446
  id: Id,
3220
3447
  /** The person's auth-brain subject. */
3221
- subject: import_zod10.z.string().min(1).max(255),
3448
+ subject: import_zod11.z.string().min(1).max(255),
3222
3449
  email: Email,
3223
- name: import_zod10.z.string().max(200).nullable(),
3450
+ name: import_zod11.z.string().max(200).nullable(),
3224
3451
  role: MemberRole,
3225
3452
  created_at: Timestamp
3226
3453
  });
3227
- var MemberCreate = import_zod10.z.object({
3228
- subject: import_zod10.z.string().min(1).max(255),
3454
+ var MemberCreate = import_zod11.z.object({
3455
+ subject: import_zod11.z.string().min(1).max(255),
3229
3456
  email: Email,
3230
- name: import_zod10.z.string().max(200).nullable().optional(),
3457
+ name: import_zod11.z.string().max(200).nullable().optional(),
3231
3458
  role: MemberRole
3232
3459
  });
3233
- var MemberUpdate = import_zod10.z.object({ role: MemberRole });
3460
+ var MemberUpdate = import_zod11.z.object({ role: MemberRole });
3234
3461
  var API_KEY_SCOPES = ["full", "read", "send"];
3235
- var ApiKeyScope = import_zod10.z.enum(API_KEY_SCOPES);
3236
- var ApiKey = import_zod10.z.object({
3462
+ var ApiKeyScope = import_zod11.z.enum(API_KEY_SCOPES);
3463
+ var ApiKey = import_zod11.z.object({
3237
3464
  id: Id,
3238
- name: import_zod10.z.string().min(1).max(120),
3465
+ name: import_zod11.z.string().min(1).max(120),
3239
3466
  /** The first characters of the key, for recognising it in a list. */
3240
- prefix: import_zod10.z.string().min(4).max(32),
3467
+ prefix: import_zod11.z.string().min(4).max(32),
3241
3468
  scope: ApiKeyScope,
3242
3469
  last_used_at: Timestamp.nullable(),
3243
3470
  revoked_at: Timestamp.nullable(),
3244
3471
  created_at: Timestamp
3245
3472
  });
3246
- var ApiKeyCreate = import_zod10.z.object({
3247
- name: import_zod10.z.string().min(1).max(120),
3473
+ var ApiKeyCreate = import_zod11.z.object({
3474
+ name: import_zod11.z.string().min(1).max(120),
3248
3475
  /** Omitted means `full`. */
3249
3476
  scope: ApiKeyScope.optional()
3250
3477
  });
3251
- var ApiKeyCreated = import_zod10.z.object({
3252
- key: import_zod10.z.string().min(20),
3478
+ var ApiKeyCreated = import_zod11.z.object({
3479
+ key: import_zod11.z.string().min(20),
3253
3480
  api_key: ApiKey
3254
3481
  });
3255
3482
  var AUDIT_ACTIONS = [
@@ -3338,29 +3565,41 @@ var AUDIT_ACTIONS = [
3338
3565
  "automation.run_ended",
3339
3566
  "event.recorded"
3340
3567
  ];
3341
- var AuditAction = import_zod10.z.enum(AUDIT_ACTIONS);
3342
- var AuditActor = import_zod10.z.discriminatedUnion("type", [
3343
- import_zod10.z.object({ type: import_zod10.z.literal("member"), member_id: Id, subject: import_zod10.z.string().min(1) }),
3344
- import_zod10.z.object({
3345
- type: import_zod10.z.literal("api_key"),
3568
+ var AuditAction = import_zod11.z.enum(AUDIT_ACTIONS);
3569
+ var TRUSTED_APPS = ["booking"];
3570
+ var TrustedApp = import_zod11.z.enum(TRUSTED_APPS);
3571
+ var AuditActor = import_zod11.z.discriminatedUnion("type", [
3572
+ import_zod11.z.object({
3573
+ type: import_zod11.z.literal("member"),
3574
+ member_id: Id,
3575
+ subject: import_zod11.z.string().min(1),
3576
+ /**
3577
+ * The application the person acted through, when it was not the dashboard:
3578
+ * the service set it from the service token the call carried, so it is
3579
+ * verified, unlike a key's `on_behalf_of`. Absent for the dashboard.
3580
+ */
3581
+ app: TrustedApp.optional()
3582
+ }),
3583
+ import_zod11.z.object({
3584
+ type: import_zod11.z.literal("api_key"),
3346
3585
  api_key_id: Id,
3347
3586
  /**
3348
3587
  * Who the client's application said it was acting for, from
3349
3588
  * `ON_BEHALF_OF_HEADER`: reported by that application, never verified.
3350
3589
  * Absent when the call carried no label.
3351
3590
  */
3352
- on_behalf_of: import_zod10.z.string().min(1).max(ON_BEHALF_OF_MAX_LENGTH).optional()
3591
+ on_behalf_of: import_zod11.z.string().min(1).max(ON_BEHALF_OF_MAX_LENGTH).optional()
3353
3592
  }),
3354
3593
  /** The service itself (the worker, a bounce, the hosted unsubscribe page). */
3355
- import_zod10.z.object({ type: import_zod10.z.literal("system"), reason: import_zod10.z.string().min(1).max(200) })
3594
+ import_zod11.z.object({ type: import_zod11.z.literal("system"), reason: import_zod11.z.string().min(1).max(200) })
3356
3595
  ]);
3357
- var AuditEntry = import_zod10.z.object({
3596
+ var AuditEntry = import_zod11.z.object({
3358
3597
  id: Id,
3359
3598
  action: AuditAction,
3360
3599
  actor: AuditActor,
3361
- target_type: import_zod10.z.string().min(1).max(64),
3600
+ target_type: import_zod11.z.string().min(1).max(64),
3362
3601
  target_id: Id.nullable(),
3363
- details: import_zod10.z.record(import_zod10.z.unknown()),
3602
+ details: import_zod11.z.record(import_zod11.z.unknown()),
3364
3603
  created_at: Timestamp
3365
3604
  });
3366
3605
  var AuditQuery = PageQuery.extend({
@@ -3369,12 +3608,12 @@ var AuditQuery = PageQuery.extend({
3369
3608
  });
3370
3609
 
3371
3610
  // src/invites.ts
3372
- var import_zod11 = require("zod");
3611
+ var import_zod12 = require("zod");
3373
3612
  var INVITE_STATUSES = ["pending", "accepted", "revoked", "expired"];
3374
- var InviteStatus = import_zod11.z.enum(INVITE_STATUSES);
3613
+ var InviteStatus = import_zod12.z.enum(INVITE_STATUSES);
3375
3614
  var DEFAULT_INVITE_TTL_DAYS = 7;
3376
3615
  var MAX_INVITE_TTL_DAYS = 30;
3377
- var Invite = import_zod11.z.object({
3616
+ var Invite = import_zod12.z.object({
3378
3617
  id: Id,
3379
3618
  /** Stored lowercased; only a person signed in with this address can accept. */
3380
3619
  email: Email,
@@ -3382,32 +3621,32 @@ var Invite = import_zod11.z.object({
3382
3621
  /** Derived from the timestamps below, never stored. */
3383
3622
  status: InviteStatus,
3384
3623
  /** The member who invited, while they are still one (null after they left). */
3385
- invited_by: import_zod11.z.object({ member_id: Id.nullable(), email: Email.nullable() }),
3624
+ invited_by: import_zod12.z.object({ member_id: Id.nullable(), email: Email.nullable() }),
3386
3625
  expires_at: Timestamp,
3387
3626
  accepted_at: Timestamp.nullable(),
3388
3627
  revoked_at: Timestamp.nullable(),
3389
3628
  created_at: Timestamp
3390
3629
  });
3391
- var InviteCreate = import_zod11.z.object({
3630
+ var InviteCreate = import_zod12.z.object({
3392
3631
  email: Email,
3393
3632
  role: MemberRole,
3394
- expires_in_days: import_zod11.z.number().int().min(1).max(MAX_INVITE_TTL_DAYS).optional()
3633
+ expires_in_days: import_zod12.z.number().int().min(1).max(MAX_INVITE_TTL_DAYS).optional()
3395
3634
  });
3396
- var InviteCreated = import_zod11.z.object({
3635
+ var InviteCreated = import_zod12.z.object({
3397
3636
  invite: Invite,
3398
- token: import_zod11.z.string().min(32).max(128)
3637
+ token: import_zod12.z.string().min(32).max(128)
3399
3638
  });
3400
3639
  var InviteListQuery = PageQuery.extend({
3401
3640
  status: InviteStatus.optional()
3402
3641
  });
3403
- var InviteAccept = import_zod11.z.object({
3404
- token: import_zod11.z.string().min(32).max(128),
3642
+ var InviteAccept = import_zod12.z.object({
3643
+ token: import_zod12.z.string().min(32).max(128),
3405
3644
  email: Email,
3406
- name: import_zod11.z.string().max(200).nullable().optional()
3645
+ name: import_zod12.z.string().max(200).nullable().optional()
3407
3646
  });
3408
- var InviteAccepted = import_zod11.z.object({
3647
+ var InviteAccepted = import_zod12.z.object({
3409
3648
  workspace: WorkspaceMembership,
3410
- already_member: import_zod11.z.boolean()
3649
+ already_member: import_zod12.z.boolean()
3411
3650
  });
3412
3651
  var INVITE_REFUSAL_REASONS = ["email_mismatch", "inviter_lacks_role", "expired", "revoked", "accepted"];
3413
3652
 
@@ -4037,13 +4276,13 @@ function renameInsertionEverywhere(drafts, from, rawTo) {
4037
4276
  }
4038
4277
 
4039
4278
  // src/providers.ts
4040
- var import_zod12 = require("zod");
4279
+ var import_zod13 = require("zod");
4041
4280
  var PROVIDER_KINDS = ["smtp", "resend"];
4042
- var ProviderKind = import_zod12.z.enum(PROVIDER_KINDS);
4043
- var ProviderPolicy = import_zod12.z.object({
4044
- daily_recipient_budget: import_zod12.z.number().int().min(1).max(1e7),
4045
- min_interval_ms: import_zod12.z.number().int().min(0).max(36e5),
4046
- max_recipients_per_message: import_zod12.z.number().int().min(1).max(1e3)
4281
+ var ProviderKind = import_zod13.z.enum(PROVIDER_KINDS);
4282
+ var ProviderPolicy = import_zod13.z.object({
4283
+ daily_recipient_budget: import_zod13.z.number().int().min(1).max(1e7),
4284
+ min_interval_ms: import_zod13.z.number().int().min(0).max(36e5),
4285
+ max_recipients_per_message: import_zod13.z.number().int().min(1).max(1e3)
4047
4286
  });
4048
4287
  var ICLOUD_SMTP_POLICY = {
4049
4288
  daily_recipient_budget: 800,
@@ -4051,17 +4290,17 @@ var ICLOUD_SMTP_POLICY = {
4051
4290
  max_recipients_per_message: 1
4052
4291
  };
4053
4292
  var SMTP_SECURITY = ["tls", "starttls"];
4054
- var SmtpConfigBase = import_zod12.z.object({
4055
- host: import_zod12.z.string().min(1).max(255),
4056
- port: import_zod12.z.number().int().min(1).max(65535),
4293
+ var SmtpConfigBase = import_zod13.z.object({
4294
+ host: import_zod13.z.string().min(1).max(255),
4295
+ port: import_zod13.z.number().int().min(1).max(65535),
4057
4296
  /** `tls` connects encrypted (465), `starttls` upgrades (587). Never plaintext. */
4058
- security: import_zod12.z.enum(SMTP_SECURITY),
4059
- username: import_zod12.z.string().min(1).max(255)
4297
+ security: import_zod13.z.enum(SMTP_SECURITY),
4298
+ username: import_zod13.z.string().min(1).max(255)
4060
4299
  });
4061
- var ResendConfigBase = import_zod12.z.object({});
4062
- var ProviderRejections = import_zod12.z.object({
4063
- count: import_zod12.z.number().int().min(0),
4064
- last_error: import_zod12.z.string().nullable(),
4300
+ var ResendConfigBase = import_zod13.z.object({});
4301
+ var ProviderRejections = import_zod13.z.object({
4302
+ count: import_zod13.z.number().int().min(0),
4303
+ last_error: import_zod13.z.string().nullable(),
4065
4304
  last_at: Timestamp.nullable(),
4066
4305
  /**
4067
4306
  * The last time the bounce circuit breaker tripped on one of this provider's
@@ -4071,59 +4310,59 @@ var ProviderRejections = import_zod12.z.object({
4071
4310
  * run's bounce blocks were undone and the mailing paused. `sample` is the
4072
4311
  * reply that tripped it.
4073
4312
  */
4074
- anomaly: import_zod12.z.object({
4313
+ anomaly: import_zod13.z.object({
4075
4314
  at: Timestamp,
4076
4315
  /** `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. */
4077
- scope: import_zod12.z.enum(["mailing", "provider"]),
4316
+ scope: import_zod13.z.enum(["mailing", "provider"]),
4078
4317
  /**
4079
4318
  * True while the provider-wide breaker is open: no bounce blocks through
4080
4319
  * this provider, test sends refused and mailings not started or resumed
4081
4320
  * (`provider_anomaly`), until an admin clears it (`providers.clearAnomaly`).
4082
4321
  */
4083
- blocking: import_zod12.z.boolean(),
4322
+ blocking: import_zod13.z.boolean(),
4084
4323
  mailing_id: Id.nullable(),
4085
- reason: import_zod12.z.string(),
4086
- sample: import_zod12.z.string()
4324
+ reason: import_zod13.z.string(),
4325
+ sample: import_zod13.z.string()
4087
4326
  }).nullable()
4088
4327
  });
4089
- var ProviderEvents = import_zod12.z.object({
4090
- status: import_zod12.z.enum(["active", "needs_secret"]),
4091
- source: import_zod12.z.enum(["automatic", "manual"]).nullable(),
4092
- url: import_zod12.z.string().url(),
4093
- error: import_zod12.z.string().nullable(),
4328
+ var ProviderEvents = import_zod13.z.object({
4329
+ status: import_zod13.z.enum(["active", "needs_secret"]),
4330
+ source: import_zod13.z.enum(["automatic", "manual"]).nullable(),
4331
+ url: import_zod13.z.string().url(),
4332
+ error: import_zod13.z.string().nullable(),
4094
4333
  /**
4095
4334
  * Events that named an email this provider never sent through the service
4096
4335
  * (another workspace or system sharing the Resend account): counted, never
4097
4336
  * acted on.
4098
4337
  */
4099
- unmatched: import_zod12.z.number().int().min(0)
4338
+ unmatched: import_zod13.z.number().int().min(0)
4100
4339
  });
4101
4340
  var RESEND_EVENT_TYPES = ["email.bounced", "email.complained", "email.delivery_delayed"];
4102
- var ResendSigningSecret = import_zod12.z.string().max(200).regex(/^whsec_[A-Za-z0-9+/]{16,}={0,2}$/, "must be the signing secret Resend shows, starting with whsec_");
4103
- var ProviderEventsSecret = import_zod12.z.object({ signing_secret: ResendSigningSecret });
4341
+ var ResendSigningSecret = import_zod13.z.string().max(200).regex(/^whsec_[A-Za-z0-9+/]{16,}={0,2}$/, "must be the signing secret Resend shows, starting with whsec_");
4342
+ var ProviderEventsSecret = import_zod13.z.object({ signing_secret: ResendSigningSecret });
4104
4343
  var ProviderFields = {
4105
- name: import_zod12.z.string().min(1).max(120),
4106
- from_name: import_zod12.z.string().min(1).max(120),
4344
+ name: import_zod13.z.string().min(1).max(120),
4345
+ from_name: import_zod13.z.string().min(1).max(120),
4107
4346
  from_email: Email,
4108
4347
  reply_to: Email.nullable(),
4109
4348
  policy: ProviderPolicy
4110
4349
  };
4111
- var Provider = import_zod12.z.discriminatedUnion("kind", [
4112
- import_zod12.z.object({
4350
+ var Provider = import_zod13.z.discriminatedUnion("kind", [
4351
+ import_zod13.z.object({
4113
4352
  id: Id,
4114
- kind: import_zod12.z.literal("smtp"),
4353
+ kind: import_zod13.z.literal("smtp"),
4115
4354
  config: SmtpConfigBase,
4116
- has_secret: import_zod12.z.boolean(),
4355
+ has_secret: import_zod13.z.boolean(),
4117
4356
  ...ProviderFields,
4118
4357
  rejections: ProviderRejections,
4119
4358
  created_at: Timestamp,
4120
4359
  updated_at: Timestamp
4121
4360
  }),
4122
- import_zod12.z.object({
4361
+ import_zod13.z.object({
4123
4362
  id: Id,
4124
- kind: import_zod12.z.literal("resend"),
4363
+ kind: import_zod13.z.literal("resend"),
4125
4364
  config: ResendConfigBase,
4126
- has_secret: import_zod12.z.boolean(),
4365
+ has_secret: import_zod13.z.boolean(),
4127
4366
  ...ProviderFields,
4128
4367
  rejections: ProviderRejections,
4129
4368
  events: ProviderEvents,
@@ -4131,31 +4370,31 @@ var Provider = import_zod12.z.discriminatedUnion("kind", [
4131
4370
  updated_at: Timestamp
4132
4371
  })
4133
4372
  ]);
4134
- var ProviderCreate = import_zod12.z.discriminatedUnion("kind", [
4135
- import_zod12.z.object({
4136
- kind: import_zod12.z.literal("smtp"),
4137
- config: SmtpConfigBase.extend({ password: import_zod12.z.string().min(1).max(1024) }),
4373
+ var ProviderCreate = import_zod13.z.discriminatedUnion("kind", [
4374
+ import_zod13.z.object({
4375
+ kind: import_zod13.z.literal("smtp"),
4376
+ config: SmtpConfigBase.extend({ password: import_zod13.z.string().min(1).max(1024) }),
4138
4377
  ...ProviderFields
4139
4378
  }),
4140
- import_zod12.z.object({
4141
- kind: import_zod12.z.literal("resend"),
4142
- config: ResendConfigBase.extend({ api_key: import_zod12.z.string().min(1).max(1024) }),
4379
+ import_zod13.z.object({
4380
+ kind: import_zod13.z.literal("resend"),
4381
+ config: ResendConfigBase.extend({ api_key: import_zod13.z.string().min(1).max(1024) }),
4143
4382
  ...ProviderFields
4144
4383
  })
4145
4384
  ]);
4146
- var ProviderUpdate = import_zod12.z.discriminatedUnion("kind", [
4147
- import_zod12.z.object({
4148
- kind: import_zod12.z.literal("smtp"),
4149
- config: SmtpConfigBase.extend({ password: import_zod12.z.string().min(1).max(1024).optional() }).partial().optional(),
4385
+ var ProviderUpdate = import_zod13.z.discriminatedUnion("kind", [
4386
+ import_zod13.z.object({
4387
+ kind: import_zod13.z.literal("smtp"),
4388
+ config: SmtpConfigBase.extend({ password: import_zod13.z.string().min(1).max(1024).optional() }).partial().optional(),
4150
4389
  name: ProviderFields.name.optional(),
4151
4390
  from_name: ProviderFields.from_name.optional(),
4152
4391
  from_email: ProviderFields.from_email.optional(),
4153
4392
  reply_to: ProviderFields.reply_to.optional(),
4154
4393
  policy: ProviderPolicy.partial().optional()
4155
4394
  }),
4156
- import_zod12.z.object({
4157
- kind: import_zod12.z.literal("resend"),
4158
- config: ResendConfigBase.extend({ api_key: import_zod12.z.string().min(1).max(1024).optional() }).optional(),
4395
+ import_zod13.z.object({
4396
+ kind: import_zod13.z.literal("resend"),
4397
+ config: ResendConfigBase.extend({ api_key: import_zod13.z.string().min(1).max(1024).optional() }).optional(),
4159
4398
  name: ProviderFields.name.optional(),
4160
4399
  from_name: ProviderFields.from_name.optional(),
4161
4400
  from_email: ProviderFields.from_email.optional(),
@@ -4163,48 +4402,48 @@ var ProviderUpdate = import_zod12.z.discriminatedUnion("kind", [
4163
4402
  policy: ProviderPolicy.partial().optional()
4164
4403
  })
4165
4404
  ]);
4166
- var ProviderUsage = import_zod12.z.object({
4405
+ var ProviderUsage = import_zod13.z.object({
4167
4406
  provider_id: Id,
4168
- recipients_last_24h: import_zod12.z.number().int().min(0),
4169
- remaining_budget: import_zod12.z.number().int().min(0),
4407
+ recipients_last_24h: import_zod13.z.number().int().min(0),
4408
+ remaining_budget: import_zod13.z.number().int().min(0),
4170
4409
  /** When enough of the rolling window frees up to send again, if exhausted. */
4171
4410
  next_capacity_at: Timestamp.nullable()
4172
4411
  });
4173
- var ProviderVerifyResult = import_zod12.z.object({
4174
- ok: import_zod12.z.boolean(),
4175
- error: import_zod12.z.string().nullable()
4412
+ var ProviderVerifyResult = import_zod13.z.object({
4413
+ ok: import_zod13.z.boolean(),
4414
+ error: import_zod13.z.string().nullable()
4176
4415
  });
4177
4416
 
4178
4417
  // src/contacts.ts
4179
- var import_zod13 = require("zod");
4180
- var Topic = import_zod13.z.object({
4418
+ var import_zod14 = require("zod");
4419
+ var Topic = import_zod14.z.object({
4181
4420
  id: Id,
4182
4421
  slug: Slug,
4183
- name: import_zod13.z.string().min(1).max(120),
4422
+ name: import_zod14.z.string().min(1).max(120),
4184
4423
  /** Shown on the hosted preference page. */
4185
- description: import_zod13.z.string().max(1e3).nullable(),
4424
+ description: import_zod14.z.string().max(1e3).nullable(),
4186
4425
  /** Translations of `name` and `description` per locale, for the hosted page. */
4187
- translations: import_zod13.z.record(
4188
- import_zod13.z.object({ name: import_zod13.z.string().min(1).max(120), description: import_zod13.z.string().max(1e3).nullable() })
4426
+ translations: import_zod14.z.record(
4427
+ import_zod14.z.object({ name: import_zod14.z.string().min(1).max(120), description: import_zod14.z.string().max(1e3).nullable() })
4189
4428
  ),
4190
4429
  created_at: Timestamp,
4191
4430
  updated_at: Timestamp
4192
4431
  });
4193
- var TopicCreate = import_zod13.z.object({
4432
+ var TopicCreate = import_zod14.z.object({
4194
4433
  slug: Slug,
4195
- name: import_zod13.z.string().min(1).max(120),
4196
- description: import_zod13.z.string().max(1e3).optional(),
4434
+ name: import_zod14.z.string().min(1).max(120),
4435
+ description: import_zod14.z.string().max(1e3).optional(),
4197
4436
  translations: Topic.shape.translations.optional()
4198
4437
  });
4199
4438
  var TopicUpdate = TopicCreate.omit({ slug: true }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
4200
- var Contact = import_zod13.z.object({
4439
+ var Contact = import_zod14.z.object({
4201
4440
  id: Id,
4202
- external_id: import_zod13.z.string().min(1).max(255).nullable(),
4441
+ external_id: import_zod14.z.string().min(1).max(255).nullable(),
4203
4442
  /** Stored lowercased, unique per workspace. */
4204
4443
  email: Email,
4205
- first_name: import_zod13.z.string().max(200).nullable(),
4206
- last_name: import_zod13.z.string().max(200).nullable(),
4207
- locale: import_zod13.z.string().min(2).max(35).nullable(),
4444
+ first_name: import_zod14.z.string().max(200).nullable(),
4445
+ last_name: import_zod14.z.string().max(200).nullable(),
4446
+ locale: import_zod14.z.string().min(2).max(35).nullable(),
4208
4447
  /**
4209
4448
  * The person's own time zone, an IANA name such as `Europe/Berlin` (A1).
4210
4449
  * Every wall clock an automation waits for is read in it, falling back to the
@@ -4212,65 +4451,65 @@ var Contact = import_zod13.z.object({
4212
4451
  */
4213
4452
  timezone: TimezoneName.nullable(),
4214
4453
  properties: Properties,
4215
- topics: import_zod13.z.array(Slug),
4454
+ topics: import_zod14.z.array(Slug),
4216
4455
  /** The slugs of the contact's tags (S4). */
4217
- tags: import_zod13.z.array(Slug),
4456
+ tags: import_zod14.z.array(Slug),
4218
4457
  created_at: Timestamp,
4219
4458
  updated_at: Timestamp
4220
4459
  });
4221
- var ContactUpsert = import_zod13.z.object({
4222
- external_id: import_zod13.z.string().min(1).max(255).optional(),
4460
+ var ContactUpsert = import_zod14.z.object({
4461
+ external_id: import_zod14.z.string().min(1).max(255).optional(),
4223
4462
  email: Email.optional(),
4224
- first_name: import_zod13.z.string().max(200).nullable().optional(),
4225
- last_name: import_zod13.z.string().max(200).nullable().optional(),
4226
- locale: import_zod13.z.string().min(2).max(35).nullable().optional(),
4463
+ first_name: import_zod14.z.string().max(200).nullable().optional(),
4464
+ last_name: import_zod14.z.string().max(200).nullable().optional(),
4465
+ locale: import_zod14.z.string().min(2).max(35).nullable().optional(),
4227
4466
  timezone: TimezoneName.nullable().optional(),
4228
4467
  properties: Properties.optional(),
4229
- topics: import_zod13.z.array(Slug).max(100).optional()
4468
+ topics: import_zod14.z.array(Slug).max(100).optional()
4230
4469
  }).refine((v) => v.external_id !== void 0 || v.email !== void 0, {
4231
4470
  message: "external_id or email is required",
4232
4471
  path: ["email"]
4233
4472
  });
4234
- var ContactUpsertResult = import_zod13.z.object({
4473
+ var ContactUpsertResult = import_zod14.z.object({
4235
4474
  contact: Contact,
4236
- created: import_zod13.z.boolean()
4475
+ created: import_zod14.z.boolean()
4237
4476
  });
4238
4477
  var ContactListQuery = PageQuery.extend({
4239
- email: import_zod13.z.string().min(1).max(254).optional(),
4240
- external_id: import_zod13.z.string().min(1).max(255).optional(),
4478
+ email: import_zod14.z.string().min(1).max(254).optional(),
4479
+ external_id: import_zod14.z.string().min(1).max(255).optional(),
4241
4480
  topic: Slug.optional()
4242
4481
  });
4243
- var ContactErased = import_zod13.z.object({
4244
- ok: import_zod13.z.literal(true),
4245
- erased_messages: import_zod13.z.number().int().min(0),
4246
- erased_recipients: import_zod13.z.number().int().min(0),
4247
- suppressions_kept: import_zod13.z.number().int().min(0)
4482
+ var ContactErased = import_zod14.z.object({
4483
+ ok: import_zod14.z.literal(true),
4484
+ erased_messages: import_zod14.z.number().int().min(0),
4485
+ erased_recipients: import_zod14.z.number().int().min(0),
4486
+ suppressions_kept: import_zod14.z.number().int().min(0)
4248
4487
  });
4249
4488
  var SUPPRESSION_REASONS = ["unsubscribed", "bounced", "complained", "manual"];
4250
- var SuppressionReason = import_zod13.z.enum(SUPPRESSION_REASONS);
4251
- var Suppression = import_zod13.z.object({
4489
+ var SuppressionReason = import_zod14.z.enum(SUPPRESSION_REASONS);
4490
+ var Suppression = import_zod14.z.object({
4252
4491
  id: Id,
4253
4492
  email: Email,
4254
4493
  reason: SuppressionReason,
4255
4494
  topic: Slug.nullable(),
4256
4495
  source_message_id: Id.nullable(),
4257
- note: import_zod13.z.string().max(1e3).nullable(),
4496
+ note: import_zod14.z.string().max(1e3).nullable(),
4258
4497
  created_at: Timestamp
4259
4498
  });
4260
- var SuppressionCreate = import_zod13.z.object({
4499
+ var SuppressionCreate = import_zod14.z.object({
4261
4500
  email: Email,
4262
- reason: import_zod13.z.enum(["manual", "unsubscribed"]),
4501
+ reason: import_zod14.z.enum(["manual", "unsubscribed"]),
4263
4502
  topic: Slug.nullable().optional(),
4264
- note: import_zod13.z.string().max(1e3).optional()
4503
+ note: import_zod14.z.string().max(1e3).optional()
4265
4504
  });
4266
4505
  var SuppressionListQuery = PageQuery.extend({
4267
- email: import_zod13.z.string().min(1).max(254).optional(),
4506
+ email: import_zod14.z.string().min(1).max(254).optional(),
4268
4507
  reason: SuppressionReason.optional(),
4269
4508
  topic: Slug.optional()
4270
4509
  });
4271
4510
 
4272
4511
  // src/webhooks.ts
4273
- var import_zod14 = require("zod");
4512
+ var import_zod15 = require("zod");
4274
4513
  var WEBHOOK_EVENT_TYPES = [
4275
4514
  "message.sent",
4276
4515
  "message.failed",
@@ -4314,23 +4553,23 @@ var WEBHOOK_EVENT_TYPES = [
4314
4553
  "template.updated",
4315
4554
  "template.deleted"
4316
4555
  ];
4317
- var WebhookEventType = import_zod14.z.enum(WEBHOOK_EVENT_TYPES);
4318
- var MessageEventBase = import_zod14.z.object({
4556
+ var WebhookEventType = import_zod15.z.enum(WEBHOOK_EVENT_TYPES);
4557
+ var MessageEventBase = import_zod15.z.object({
4319
4558
  message_id: Id,
4320
4559
  mailing_id: Id.nullable(),
4321
4560
  mailing_metadata: MailingMetadata.nullable(),
4322
4561
  recipient_id: Id.nullable(),
4323
4562
  contact_id: Id.nullable(),
4324
- external_id: import_zod14.z.string().nullable(),
4563
+ external_id: import_zod15.z.string().nullable(),
4325
4564
  email: Email,
4326
- subject: import_zod14.z.string(),
4565
+ subject: import_zod15.z.string(),
4327
4566
  topic: Slug.nullable(),
4328
- provider_message_id: import_zod14.z.string().nullable(),
4329
- is_test: import_zod14.z.boolean()
4567
+ provider_message_id: import_zod15.z.string().nullable(),
4568
+ is_test: import_zod15.z.boolean()
4330
4569
  });
4331
4570
  var MessageSentData = MessageEventBase.extend({
4332
4571
  /** The final HTML as sent, so the client can archive it beside its own records. */
4333
- html: import_zod14.z.string(),
4572
+ html: import_zod15.z.string(),
4334
4573
  sent_at: Timestamp,
4335
4574
  /**
4336
4575
  * The choice each insertion made (see `Message.insertions`); absent or null
@@ -4341,20 +4580,20 @@ var MessageSentData = MessageEventBase.extend({
4341
4580
  insertions: InsertionChoices.nullish()
4342
4581
  });
4343
4582
  var MessageFailedData = MessageEventBase.extend({
4344
- error: import_zod14.z.string(),
4583
+ error: import_zod15.z.string(),
4345
4584
  /** False when the provider rejected permanently; the recipient will not be retried. */
4346
- retryable: import_zod14.z.boolean(),
4585
+ retryable: import_zod15.z.boolean(),
4347
4586
  failed_at: Timestamp
4348
4587
  });
4349
4588
  var UNSUBSCRIBE_SOURCES = ["hosted_page", "one_click", "api", "dashboard", "signup_form"];
4350
- var ContactUnsubscribedData = import_zod14.z.object({
4589
+ var ContactUnsubscribedData = import_zod15.z.object({
4351
4590
  contact_id: Id.nullable(),
4352
- external_id: import_zod14.z.string().nullable(),
4591
+ external_id: import_zod15.z.string().nullable(),
4353
4592
  email: Email,
4354
4593
  /** The topic unsubscribed from; null means every topic. */
4355
4594
  topic: Slug.nullable(),
4356
4595
  mailing_id: Id.nullable(),
4357
- source: import_zod14.z.enum(UNSUBSCRIBE_SOURCES),
4596
+ source: import_zod15.z.enum(UNSUBSCRIBE_SOURCES),
4358
4597
  unsubscribed_at: Timestamp
4359
4598
  });
4360
4599
  var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: true }).extend({
@@ -4363,142 +4602,142 @@ var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: tr
4363
4602
  * breaker undid a `bounced` block it judged false (a `contact.bounced` for the
4364
4603
  * same address and mailing went out before); `topic` is null.
4365
4604
  */
4366
- source: import_zod14.z.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
4605
+ source: import_zod15.z.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
4367
4606
  resubscribed_at: Timestamp
4368
4607
  });
4369
- var ContactBouncedData = import_zod14.z.object({
4608
+ var ContactBouncedData = import_zod15.z.object({
4370
4609
  contact_id: Id.nullable(),
4371
- external_id: import_zod14.z.string().nullable(),
4610
+ external_id: import_zod15.z.string().nullable(),
4372
4611
  email: Email,
4373
4612
  /** `bounced` for a hard bounce, `complained` for a spam complaint. */
4374
- reason: import_zod14.z.enum(["bounced", "complained"]),
4613
+ reason: import_zod15.z.enum(["bounced", "complained"]),
4375
4614
  message_id: Id.nullable(),
4376
- diagnostic: import_zod14.z.string().nullable(),
4615
+ diagnostic: import_zod15.z.string().nullable(),
4377
4616
  bounced_at: Timestamp
4378
4617
  });
4379
- var MailingFinishedData = import_zod14.z.object({
4618
+ var MailingFinishedData = import_zod15.z.object({
4380
4619
  mailing_id: Id,
4381
4620
  mailing_metadata: MailingMetadata,
4382
- status: import_zod14.z.enum(["sent", "partially_failed", "cancelled"]),
4621
+ status: import_zod15.z.enum(["sent", "partially_failed", "cancelled"]),
4383
4622
  counts: MailingCounts,
4384
4623
  finished_at: Timestamp
4385
4624
  });
4386
- var ContactSubscribedData = import_zod14.z.object({
4625
+ var ContactSubscribedData = import_zod15.z.object({
4387
4626
  contact_id: Id,
4388
- external_id: import_zod14.z.string().nullable(),
4627
+ external_id: import_zod15.z.string().nullable(),
4389
4628
  email: Email,
4390
- topics: import_zod14.z.array(Slug),
4391
- source: import_zod14.z.enum(["signup_form", "api", "dashboard", "automation"]),
4629
+ topics: import_zod15.z.array(Slug),
4630
+ source: import_zod15.z.enum(["signup_form", "api", "dashboard", "automation"]),
4392
4631
  signup_form_id: Id.nullable(),
4393
- signup_form_version: import_zod14.z.number().int().min(1).nullable(),
4632
+ signup_form_version: import_zod15.z.number().int().min(1).nullable(),
4394
4633
  subscribed_at: Timestamp
4395
4634
  });
4396
- var ImportFinishedData = import_zod14.z.object({
4635
+ var ImportFinishedData = import_zod15.z.object({
4397
4636
  import_id: Id,
4398
- status: import_zod14.z.enum(["completed", "cancelled", "failed"]),
4637
+ status: import_zod15.z.enum(["completed", "cancelled", "failed"]),
4399
4638
  result: ImportReport.nullable(),
4400
- error: import_zod14.z.string().nullable(),
4639
+ error: import_zod15.z.string().nullable(),
4401
4640
  finished_at: Timestamp
4402
4641
  });
4403
- var MailingScheduledData = import_zod14.z.object({
4642
+ var MailingScheduledData = import_zod15.z.object({
4404
4643
  mailing_id: Id,
4405
4644
  mailing_metadata: MailingMetadata,
4406
4645
  scheduled_at: Timestamp.nullable()
4407
4646
  });
4408
- var MailingStartedData = import_zod14.z.object({
4647
+ var MailingStartedData = import_zod15.z.object({
4409
4648
  mailing_id: Id,
4410
4649
  mailing_metadata: MailingMetadata,
4411
- trigger: import_zod14.z.enum(["send", "schedule"]),
4412
- recipients: import_zod14.z.number().int().min(0),
4650
+ trigger: import_zod15.z.enum(["send", "schedule"]),
4651
+ recipients: import_zod15.z.number().int().min(0),
4413
4652
  started_at: Timestamp
4414
4653
  });
4415
- var MailingScheduleFailedData = import_zod14.z.object({
4654
+ var MailingScheduleFailedData = import_zod15.z.object({
4416
4655
  mailing_id: Id,
4417
4656
  mailing_metadata: MailingMetadata,
4418
- code: import_zod14.z.string(),
4419
- message: import_zod14.z.string(),
4657
+ code: import_zod15.z.string(),
4658
+ message: import_zod15.z.string(),
4420
4659
  failed_at: Timestamp
4421
4660
  });
4422
- var MailingAbWinnerSelectedData = import_zod14.z.object({
4661
+ var MailingAbWinnerSelectedData = import_zod15.z.object({
4423
4662
  mailing_id: Id,
4424
4663
  mailing_metadata: MailingMetadata,
4425
- winner: import_zod14.z.string(),
4426
- decided_by: import_zod14.z.enum(["metric", "manual"]),
4427
- variants: import_zod14.z.array(VariantAnalytics),
4664
+ winner: import_zod15.z.string(),
4665
+ decided_by: import_zod15.z.enum(["metric", "manual"]),
4666
+ variants: import_zod15.z.array(VariantAnalytics),
4428
4667
  decided_at: Timestamp
4429
4668
  });
4430
- var ContactTaggedData = import_zod14.z.object({
4669
+ var ContactTaggedData = import_zod15.z.object({
4431
4670
  contact_id: Id,
4432
- external_id: import_zod14.z.string().nullable(),
4671
+ external_id: import_zod15.z.string().nullable(),
4433
4672
  email: Email,
4434
4673
  /** Only the tags the contact did not already have. */
4435
- tags: import_zod14.z.array(Slug).min(1),
4436
- source: import_zod14.z.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4674
+ tags: import_zod15.z.array(Slug).min(1),
4675
+ source: import_zod15.z.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4437
4676
  tagged_at: Timestamp
4438
4677
  });
4439
- var ContactUpdatedData = import_zod14.z.object({
4678
+ var ContactUpdatedData = import_zod15.z.object({
4440
4679
  contact_id: Id,
4441
- external_id: import_zod14.z.string().nullable(),
4680
+ external_id: import_zod15.z.string().nullable(),
4442
4681
  email: Email,
4443
- changed: import_zod14.z.array(import_zod14.z.string()).min(1),
4682
+ changed: import_zod15.z.array(import_zod15.z.string()).min(1),
4444
4683
  properties: Properties,
4445
- source: import_zod14.z.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4684
+ source: import_zod15.z.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4446
4685
  updated_at: Timestamp
4447
4686
  });
4448
- var AutomationRunEventBase = import_zod14.z.object({
4687
+ var AutomationRunEventBase = import_zod15.z.object({
4449
4688
  automation_id: Id,
4450
- automation_name: import_zod14.z.string(),
4689
+ automation_name: import_zod15.z.string(),
4451
4690
  run_id: Id,
4452
- version: import_zod14.z.number().int().min(1),
4691
+ version: import_zod15.z.number().int().min(1),
4453
4692
  contact_id: Id,
4454
- external_id: import_zod14.z.string().nullable(),
4693
+ external_id: import_zod15.z.string().nullable(),
4455
4694
  email: Email
4456
4695
  });
4457
4696
  var AutomationRunStartedData = AutomationRunEventBase.extend({
4458
4697
  /** What let them in: a trigger kind, or `manual` for an explicit enrolment. */
4459
- trigger_kind: import_zod14.z.string(),
4698
+ trigger_kind: import_zod15.z.string(),
4460
4699
  entered_at: Timestamp
4461
4700
  });
4462
4701
  var AutomationRunCompletedData = AutomationRunEventBase.extend({
4463
- last_step_id: import_zod14.z.string().nullable(),
4702
+ last_step_id: import_zod15.z.string().nullable(),
4464
4703
  completed_at: Timestamp
4465
4704
  });
4466
4705
  var AutomationRunExitedData = AutomationRunEventBase.extend({
4467
4706
  reason: AutomationEndReason,
4468
- step_id: import_zod14.z.string().nullable(),
4707
+ step_id: import_zod15.z.string().nullable(),
4469
4708
  exited_at: Timestamp
4470
4709
  });
4471
4710
  var AutomationRunFailedData = AutomationRunEventBase.extend({
4472
- reason: import_zod14.z.string(),
4473
- step_id: import_zod14.z.string().nullable(),
4711
+ reason: import_zod15.z.string(),
4712
+ step_id: import_zod15.z.string().nullable(),
4474
4713
  failed_at: Timestamp
4475
4714
  });
4476
4715
  var AutomationWebhookData = AutomationRunEventBase.extend({
4477
- step_id: import_zod14.z.string(),
4716
+ step_id: import_zod15.z.string(),
4478
4717
  /** The step's own label, when it was given one, so a receiver can branch on a name. */
4479
- step_label: import_zod14.z.string().nullable(),
4718
+ step_label: import_zod15.z.string().nullable(),
4480
4719
  /** Whatever the step carries, verbatim. Null when it carries nothing. */
4481
4720
  payload: JsonValue.nullable(),
4482
4721
  fired_at: Timestamp
4483
4722
  });
4484
- var TemplateEventBase = import_zod14.z.object({
4723
+ var TemplateEventBase = import_zod15.z.object({
4485
4724
  template_id: Id,
4486
- name: import_zod14.z.string().min(1).max(200),
4487
- version: import_zod14.z.number().int().min(1),
4488
- source: import_zod14.z.enum(["api", "dashboard", "mjml_import"])
4725
+ name: import_zod15.z.string().min(1).max(200),
4726
+ version: import_zod15.z.number().int().min(1),
4727
+ source: import_zod15.z.enum(["api", "dashboard", "mjml_import"])
4489
4728
  });
4490
4729
  var TemplateCreatedData = TemplateEventBase.extend({ created_at: Timestamp });
4491
- var TemplateUpdatedData = TemplateEventBase.extend({ archived: import_zod14.z.boolean(), updated_at: Timestamp });
4730
+ var TemplateUpdatedData = TemplateEventBase.extend({ archived: import_zod15.z.boolean(), updated_at: Timestamp });
4492
4731
  var TemplateDeletedData = TemplateEventBase.extend({ deleted_at: Timestamp });
4493
- var envelope = (type, data) => import_zod14.z.object({
4732
+ var envelope = (type, data) => import_zod15.z.object({
4494
4733
  /** Unique per event: a receiver deduplicates on it (deliveries may repeat). */
4495
4734
  id: Id,
4496
- type: import_zod14.z.literal(type),
4735
+ type: import_zod15.z.literal(type),
4497
4736
  created_at: Timestamp,
4498
4737
  workspace_id: Id,
4499
4738
  data
4500
4739
  });
4501
- var WebhookEvent = import_zod14.z.discriminatedUnion("type", [
4740
+ var WebhookEvent = import_zod15.z.discriminatedUnion("type", [
4502
4741
  envelope("message.sent", MessageSentData),
4503
4742
  envelope("message.failed", MessageFailedData),
4504
4743
  envelope("contact.unsubscribed", ContactUnsubscribedData),
@@ -4522,16 +4761,16 @@ var WebhookEvent = import_zod14.z.discriminatedUnion("type", [
4522
4761
  envelope("template.updated", TemplateUpdatedData),
4523
4762
  envelope("template.deleted", TemplateDeletedData)
4524
4763
  ]);
4525
- var WebhookEndpoint = import_zod14.z.object({
4764
+ var WebhookEndpoint = import_zod15.z.object({
4526
4765
  id: Id,
4527
- url: import_zod14.z.string().url(),
4528
- description: import_zod14.z.string().max(500).nullable(),
4529
- events: import_zod14.z.array(WebhookEventType).min(1),
4530
- enabled: import_zod14.z.boolean(),
4766
+ url: import_zod15.z.string().url(),
4767
+ description: import_zod15.z.string().max(500).nullable(),
4768
+ events: import_zod15.z.array(WebhookEventType).min(1),
4769
+ enabled: import_zod15.z.boolean(),
4531
4770
  created_at: Timestamp,
4532
4771
  updated_at: Timestamp
4533
4772
  });
4534
- var WebhookUrl = import_zod14.z.string().url().refine((u) => {
4773
+ var WebhookUrl = import_zod15.z.string().url().refine((u) => {
4535
4774
  try {
4536
4775
  const url = new URL(u);
4537
4776
  if (url.protocol === "https:") return true;
@@ -4540,35 +4779,35 @@ var WebhookUrl = import_zod14.z.string().url().refine((u) => {
4540
4779
  return false;
4541
4780
  }
4542
4781
  }, "must be https (http only for localhost)");
4543
- var WebhookEndpointCreate = import_zod14.z.object({
4782
+ var WebhookEndpointCreate = import_zod15.z.object({
4544
4783
  url: WebhookUrl,
4545
- description: import_zod14.z.string().max(500).optional(),
4546
- events: import_zod14.z.array(WebhookEventType).min(1),
4547
- enabled: import_zod14.z.boolean().optional()
4784
+ description: import_zod15.z.string().max(500).optional(),
4785
+ events: import_zod15.z.array(WebhookEventType).min(1),
4786
+ enabled: import_zod15.z.boolean().optional()
4548
4787
  });
4549
- var WebhookEndpointUpdate = import_zod14.z.object({
4788
+ var WebhookEndpointUpdate = import_zod15.z.object({
4550
4789
  url: WebhookUrl,
4551
- description: import_zod14.z.string().max(500).nullable(),
4552
- events: import_zod14.z.array(WebhookEventType).min(1),
4553
- enabled: import_zod14.z.boolean()
4790
+ description: import_zod15.z.string().max(500).nullable(),
4791
+ events: import_zod15.z.array(WebhookEventType).min(1),
4792
+ enabled: import_zod15.z.boolean()
4554
4793
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
4555
- var WebhookEndpointWithSecret = import_zod14.z.object({
4794
+ var WebhookEndpointWithSecret = import_zod15.z.object({
4556
4795
  endpoint: WebhookEndpoint,
4557
- secret: import_zod14.z.string().min(32)
4796
+ secret: import_zod15.z.string().min(32)
4558
4797
  });
4559
4798
  var WEBHOOK_DELIVERY_STATUSES = ["pending", "succeeded", "failed"];
4560
- var WebhookDeliveryStatus = import_zod14.z.enum(WEBHOOK_DELIVERY_STATUSES);
4799
+ var WebhookDeliveryStatus = import_zod15.z.enum(WEBHOOK_DELIVERY_STATUSES);
4561
4800
  var WEBHOOK_MAX_ATTEMPTS = 8;
4562
4801
  var WEBHOOK_RETRY_DELAYS_SECONDS = [30, 120, 600, 1800, 3600, 7200, 21600];
4563
- var WebhookDelivery = import_zod14.z.object({
4802
+ var WebhookDelivery = import_zod15.z.object({
4564
4803
  id: Id,
4565
4804
  endpoint_id: Id,
4566
4805
  event_id: Id,
4567
4806
  event_type: WebhookEventType,
4568
4807
  status: WebhookDeliveryStatus,
4569
- attempts: import_zod14.z.number().int().min(0),
4570
- last_status_code: import_zod14.z.number().int().min(100).max(599).nullable(),
4571
- last_error: import_zod14.z.string().nullable(),
4808
+ attempts: import_zod15.z.number().int().min(0),
4809
+ last_status_code: import_zod15.z.number().int().min(100).max(599).nullable(),
4810
+ last_error: import_zod15.z.string().nullable(),
4572
4811
  next_attempt_at: Timestamp.nullable(),
4573
4812
  delivered_at: Timestamp.nullable(),
4574
4813
  created_at: Timestamp
@@ -4577,7 +4816,7 @@ var WebhookDeliveryListQuery = PageQuery.extend({
4577
4816
  status: WebhookDeliveryStatus.optional(),
4578
4817
  event_type: WebhookEventType.optional()
4579
4818
  });
4580
- var WebhookDeliveryParams = import_zod14.z.object({ id: Id, delivery_id: Id });
4819
+ var WebhookDeliveryParams = import_zod15.z.object({ id: Id, delivery_id: Id });
4581
4820
 
4582
4821
  // src/webhook-signing.ts
4583
4822
  var WEBHOOK_SIGNATURE_HEADER = "x-mail-signature";
@@ -4644,79 +4883,79 @@ async function verifyWebhook(input) {
4644
4883
  }
4645
4884
 
4646
4885
  // src/billing.ts
4647
- var import_zod15 = require("zod");
4886
+ var import_zod16 = require("zod");
4648
4887
  var PLAN_IDS = ["free", "starter", "growth", "design_partner"];
4649
- var PlanId = import_zod15.z.enum(PLAN_IDS);
4650
- var PlanLimits = import_zod15.z.object({
4651
- monthly_messages: import_zod15.z.number().int().min(0).nullable(),
4652
- contacts: import_zod15.z.number().int().min(0).nullable(),
4653
- members: import_zod15.z.number().int().min(1).nullable(),
4654
- providers: import_zod15.z.number().int().min(1).nullable(),
4655
- webhook_endpoints: import_zod15.z.number().int().min(0).nullable(),
4888
+ var PlanId = import_zod16.z.enum(PLAN_IDS);
4889
+ var PlanLimits = import_zod16.z.object({
4890
+ monthly_messages: import_zod16.z.number().int().min(0).nullable(),
4891
+ contacts: import_zod16.z.number().int().min(0).nullable(),
4892
+ members: import_zod16.z.number().int().min(1).nullable(),
4893
+ providers: import_zod16.z.number().int().min(1).nullable(),
4894
+ webhook_endpoints: import_zod16.z.number().int().min(0).nullable(),
4656
4895
  /** Automations that may be live (active or paused) at once (A1). */
4657
- active_automations: import_zod15.z.number().int().min(0).nullable(),
4896
+ active_automations: import_zod16.z.number().int().min(0).nullable(),
4658
4897
  /** Steps one automation may hold. Null is the flow's own cap, not unlimited. */
4659
- automation_steps: import_zod15.z.number().int().min(1).nullable()
4898
+ automation_steps: import_zod16.z.number().int().min(1).nullable()
4660
4899
  });
4661
- var PlanFeatures = import_zod15.z.object({
4900
+ var PlanFeatures = import_zod16.z.object({
4662
4901
  /** A/B tests of subject and content on a mailing (S4). */
4663
- ab_testing: import_zod15.z.boolean(),
4902
+ ab_testing: import_zod16.z.boolean(),
4664
4903
  /** Open and click tracking, still off until a workspace turns it on (`settings.tracking_enabled`). */
4665
- tracking: import_zod15.z.boolean(),
4904
+ tracking: import_zod16.z.boolean(),
4666
4905
  /** Sending and hosting pages on the workspace's own domain (a later phase). */
4667
- custom_domains: import_zod15.z.boolean(),
4906
+ custom_domains: import_zod16.z.boolean(),
4668
4907
  /** Automations: flows a person walks through step by step (A1). */
4669
- automations: import_zod15.z.boolean()
4908
+ automations: import_zod16.z.boolean()
4670
4909
  });
4671
4910
  var PLAN_FEATURES = ["ab_testing", "tracking", "custom_domains", "automations"];
4672
- var Plan = import_zod15.z.object({
4911
+ var Plan = import_zod16.z.object({
4673
4912
  id: PlanId,
4674
- name: import_zod15.z.string().min(1),
4913
+ name: import_zod16.z.string().min(1),
4675
4914
  /** Price in the smallest currency unit per month; null for plans not sold. */
4676
- monthly_price_cents: import_zod15.z.number().int().min(0).nullable(),
4677
- currency: import_zod15.z.string().length(3),
4915
+ monthly_price_cents: import_zod16.z.number().int().min(0).nullable(),
4916
+ currency: import_zod16.z.string().length(3),
4678
4917
  limits: PlanLimits,
4679
4918
  features: PlanFeatures
4680
4919
  });
4681
- var CatalogPlan = Plan.extend({ sellable: import_zod15.z.boolean() });
4682
- var Subscription = import_zod15.z.object({
4920
+ var CatalogPlan = Plan.extend({ sellable: import_zod16.z.boolean() });
4921
+ var Subscription = import_zod16.z.object({
4683
4922
  workspace_id: Id,
4684
4923
  plan: PlanId,
4685
- status: import_zod15.z.enum(["active", "trialing", "past_due", "cancelled"]),
4924
+ status: import_zod16.z.enum(["active", "trialing", "past_due", "cancelled"]),
4686
4925
  current_period_start: Timestamp,
4687
4926
  current_period_end: Timestamp,
4688
- cancel_at_period_end: import_zod15.z.boolean(),
4927
+ cancel_at_period_end: import_zod16.z.boolean(),
4689
4928
  /**
4690
4929
  * A design partner outside billing (plan `design_partner`, no limits, no
4691
4930
  * checkout). Set only by an operator, never through the API.
4692
4931
  */
4693
- billing_exempt: import_zod15.z.boolean()
4932
+ billing_exempt: import_zod16.z.boolean()
4694
4933
  });
4695
4934
  var USAGE_METRICS = ["messages", "contacts", "members", "providers", "webhook_endpoints", "active_automations"];
4696
- var UsageMetric = import_zod15.z.enum(USAGE_METRICS);
4935
+ var UsageMetric = import_zod16.z.enum(USAGE_METRICS);
4697
4936
  var USAGE_WARNING_RATIO = 0.8;
4698
- var UsageWarning = import_zod15.z.object({
4937
+ var UsageWarning = import_zod16.z.object({
4699
4938
  metric: UsageMetric,
4700
- used: import_zod15.z.number().int().min(0),
4701
- limit: import_zod15.z.number().int().min(0),
4939
+ used: import_zod16.z.number().int().min(0),
4940
+ limit: import_zod16.z.number().int().min(0),
4702
4941
  /** `approaching`: at or above USAGE_WARNING_RATIO of the limit; `reached`: at or above the limit. */
4703
- level: import_zod15.z.enum(["approaching", "reached"])
4942
+ level: import_zod16.z.enum(["approaching", "reached"])
4704
4943
  });
4705
- var Usage = import_zod15.z.object({
4944
+ var Usage = import_zod16.z.object({
4706
4945
  plan: PlanId,
4707
4946
  period_start: Timestamp,
4708
4947
  period_end: Timestamp,
4709
- metrics: import_zod15.z.record(UsageMetric, import_zod15.z.object({ used: import_zod15.z.number().int().min(0), limit: import_zod15.z.number().int().min(0).nullable() })),
4710
- warnings: import_zod15.z.array(UsageWarning)
4948
+ metrics: import_zod16.z.record(UsageMetric, import_zod16.z.object({ used: import_zod16.z.number().int().min(0), limit: import_zod16.z.number().int().min(0).nullable() })),
4949
+ warnings: import_zod16.z.array(UsageWarning)
4711
4950
  });
4712
- var CheckoutRequest = import_zod15.z.object({
4713
- plan: import_zod15.z.enum(["starter", "growth"]),
4714
- success_url: import_zod15.z.string().url(),
4715
- cancel_url: import_zod15.z.string().url()
4951
+ var CheckoutRequest = import_zod16.z.object({
4952
+ plan: import_zod16.z.enum(["starter", "growth"]),
4953
+ success_url: import_zod16.z.string().url(),
4954
+ cancel_url: import_zod16.z.string().url()
4716
4955
  });
4717
- var CheckoutSession = import_zod15.z.object({ url: import_zod15.z.string().url() });
4718
- var PortalRequest = import_zod15.z.object({ return_url: import_zod15.z.string().url() });
4719
- var PortalSession = import_zod15.z.object({ url: import_zod15.z.string().url() });
4956
+ var CheckoutSession = import_zod16.z.object({ url: import_zod16.z.string().url() });
4957
+ var PortalRequest = import_zod16.z.object({ return_url: import_zod16.z.string().url() });
4958
+ var PortalSession = import_zod16.z.object({ url: import_zod16.z.string().url() });
4720
4959
  var USAGE_WARNING_HEADER = "x-mail-usage-warning";
4721
4960
  function formatUsageWarningHeader(warnings) {
4722
4961
  if (warnings.length === 0) return null;
@@ -4736,7 +4975,7 @@ function parseUsageWarningHeader(value) {
4736
4975
  }
4737
4976
 
4738
4977
  // src/routes.ts
4739
- var import_zod16 = require("zod");
4978
+ var import_zod17 = require("zod");
4740
4979
  var list = (item) => page(item);
4741
4980
  var foundationRoutes = {
4742
4981
  "workspaces.create": {
@@ -4964,7 +5203,7 @@ var templateRoutes = {
4964
5203
  path: "/v1/templates/:id/export",
4965
5204
  params: IdParams,
4966
5205
  query: TemplateExportQuery,
4967
- response: import_zod16.z.string(),
5206
+ response: import_zod17.z.string(),
4968
5207
  responseType: "text",
4969
5208
  status: 200,
4970
5209
  access: "read",
@@ -5288,7 +5527,7 @@ var sendingRoutes = {
5288
5527
  path: "/v1/mailings/:id/export",
5289
5528
  params: IdParams,
5290
5529
  query: MailingExportQuery,
5291
- response: import_zod16.z.string(),
5530
+ response: import_zod17.z.string(),
5292
5531
  responseType: "text",
5293
5532
  status: 200,
5294
5533
  access: "read",
@@ -5334,6 +5573,21 @@ var sendingRoutes = {
5334
5573
  access: "write",
5335
5574
  phase: "S2"
5336
5575
  },
5576
+ /**
5577
+ * A dry run: what each given recipient would be sent (every value's text and
5578
+ * the layer it comes from, each insertion's choice, the problems found),
5579
+ * without adding anybody. Reads only, in any state of the mailing.
5580
+ */
5581
+ "mailings.resolve": {
5582
+ method: "POST",
5583
+ path: "/v1/mailings/:id/resolve",
5584
+ params: IdParams,
5585
+ body: MailingResolveRequest,
5586
+ response: MailingResolveResult,
5587
+ status: 200,
5588
+ access: "read",
5589
+ phase: "S2"
5590
+ },
5337
5591
  "mailings.send": {
5338
5592
  method: "POST",
5339
5593
  path: "/v1/mailings/:id/send",
@@ -5521,7 +5775,7 @@ var platformRoutes = {
5521
5775
  "contactProperties.list": {
5522
5776
  method: "GET",
5523
5777
  path: "/v1/contact-properties",
5524
- response: import_zod16.z.object({ data: import_zod16.z.array(ContactPropertyDefinition) }),
5778
+ response: import_zod17.z.object({ data: import_zod17.z.array(ContactPropertyDefinition) }),
5525
5779
  status: 200,
5526
5780
  access: "read",
5527
5781
  phase: "S4"
@@ -5820,7 +6074,7 @@ var billingRoutes = {
5820
6074
  "billing.plans": {
5821
6075
  method: "GET",
5822
6076
  path: "/v1/billing/plans",
5823
- response: import_zod16.z.object({ data: import_zod16.z.array(CatalogPlan) }),
6077
+ response: import_zod17.z.object({ data: import_zod17.z.array(CatalogPlan) }),
5824
6078
  status: 200,
5825
6079
  access: "read",
5826
6080
  phase: "S5"
@@ -5962,7 +6216,7 @@ var automationRoutes = {
5962
6216
  method: "POST",
5963
6217
  path: "/v1/automations/:id/pause",
5964
6218
  params: IdParams,
5965
- body: import_zod16.z.object({}).strict(),
6219
+ body: import_zod17.z.object({}).strict(),
5966
6220
  response: Automation,
5967
6221
  status: 200,
5968
6222
  access: "write",
@@ -5972,7 +6226,7 @@ var automationRoutes = {
5972
6226
  method: "POST",
5973
6227
  path: "/v1/automations/:id/resume",
5974
6228
  params: IdParams,
5975
- body: import_zod16.z.object({}).strict(),
6229
+ body: import_zod17.z.object({}).strict(),
5976
6230
  response: Automation,
5977
6231
  status: 200,
5978
6232
  access: "write",
@@ -5982,7 +6236,7 @@ var automationRoutes = {
5982
6236
  method: "POST",
5983
6237
  path: "/v1/automations/:id/archive",
5984
6238
  params: IdParams,
5985
- body: import_zod16.z.object({}).strict(),
6239
+ body: import_zod17.z.object({}).strict(),
5986
6240
  response: Automation,
5987
6241
  status: 200,
5988
6242
  access: "write",
@@ -6099,6 +6353,12 @@ var routes = {
6099
6353
  ...billingRoutes,
6100
6354
  ...automationRoutes
6101
6355
  };
6356
+ var TRUSTED_APP_OPERATIONS = {
6357
+ booking: ["workspaces.list", "workspace.update", "providers.list", "apiKeys.create", "apiKeys.revoke"]
6358
+ };
6359
+ function trustedAppMayCall(app, id) {
6360
+ return TRUSTED_APP_OPERATIONS[app].includes(id);
6361
+ }
6102
6362
  function acceptsIdempotencyKey(route) {
6103
6363
  return route.method !== "GET";
6104
6364
  }
@@ -6116,13 +6376,13 @@ function matchRoute(method, pathname) {
6116
6376
  for (const [id, route] of Object.entries(routes)) {
6117
6377
  if (route.method !== method) continue;
6118
6378
  const names = [];
6119
- const pattern2 = new RegExp(
6379
+ const pattern3 = new RegExp(
6120
6380
  "^" + route.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/:([a-z_]+)/g, (_, name) => {
6121
6381
  names.push(name);
6122
6382
  return "([^/]+)";
6123
6383
  }) + "$"
6124
6384
  );
6125
- const match = pattern2.exec(pathname);
6385
+ const match = pattern3.exec(pathname);
6126
6386
  if (!match) continue;
6127
6387
  const params = {};
6128
6388
  names.forEach((name, i) => {
@@ -6323,6 +6583,7 @@ function matchRoute(method, pathname) {
6323
6583
  InviteListQuery,
6324
6584
  InviteStatus,
6325
6585
  JsonValue,
6586
+ LETTER_ONLY_MERGE_FIELDS,
6326
6587
  LETTER_RECIPIENT_REFUSAL,
6327
6588
  LIST_UNSUBSCRIBE_POST_VALUE,
6328
6589
  LOCALE_TAG_PATTERN,
@@ -6391,7 +6652,10 @@ function matchRoute(method, pathname) {
6391
6652
  MailingLanguageReport,
6392
6653
  MailingLanguageStatus,
6393
6654
  MailingListQuery,
6655
+ MailingMerge,
6394
6656
  MailingMetadata,
6657
+ MailingResolveRequest,
6658
+ MailingResolveResult,
6395
6659
  MailingRetryFailedRequest,
6396
6660
  MailingScheduleFailedData,
6397
6661
  MailingScheduleRequest,
@@ -6416,6 +6680,8 @@ function matchRoute(method, pathname) {
6416
6680
  MessageOutcome,
6417
6681
  MessageSentData,
6418
6682
  MessageSummary,
6683
+ MessageValues,
6684
+ NAME_ON_BROADCAST_REFUSAL,
6419
6685
  NotifyRecipients,
6420
6686
  NotifyStep,
6421
6687
  ON_BEHALF_OF_HEADER,
@@ -6451,6 +6717,8 @@ function matchRoute(method, pathname) {
6451
6717
  REQUEST_ID_HEADER,
6452
6718
  RESEND_EVENT_TYPES,
6453
6719
  RESERVED_MERGE_FIELDS,
6720
+ RESOLVE_PROBLEMS,
6721
+ RESOLVE_REJECTIONS,
6454
6722
  RETRYABLE_ERRORS,
6455
6723
  RETRY_AFTER_HEADER,
6456
6724
  RE_ENTRY_MODES,
@@ -6463,6 +6731,9 @@ function matchRoute(method, pathname) {
6463
6731
  RecipientStatus,
6464
6732
  RemoteImage,
6465
6733
  ResendSigningSecret,
6734
+ ResolveProblem,
6735
+ ResolvedRecipient,
6736
+ ResolvedValue,
6466
6737
  SERVICE_FILLED_MERGE_FIELDS,
6467
6738
  SIGNUP_FORM_FIELDS,
6468
6739
  SKIP_REASONS,
@@ -6499,6 +6770,8 @@ function matchRoute(method, pathname) {
6499
6770
  TEMPLATE_SORTS,
6500
6771
  TEMPLATE_SORT_DEFAULT_ORDER,
6501
6772
  TERMINAL_MAILING_STATUSES,
6773
+ TRUSTED_APPS,
6774
+ TRUSTED_APP_OPERATIONS,
6502
6775
  Tag,
6503
6776
  TagAssignment,
6504
6777
  TagCreate,
@@ -6544,15 +6817,19 @@ function matchRoute(method, pathname) {
6544
6817
  TrackingSettings,
6545
6818
  TranslationInsertion,
6546
6819
  TranslationInsertions,
6820
+ TrustedApp,
6547
6821
  UNSUBSCRIBE_PATH_PREFIX,
6548
6822
  UNSUBSCRIBE_SOURCES,
6549
6823
  USAGE_METRICS,
6550
6824
  USAGE_WARNING_HEADER,
6551
6825
  USAGE_WARNING_RATIO,
6826
+ UnfilledLink,
6552
6827
  Usage,
6553
6828
  UsageMetric,
6554
6829
  UsageWarning,
6830
+ VALUE_LAYERS,
6555
6831
  ValidationIssue,
6832
+ ValueLayer,
6556
6833
  VariantAnalytics,
6557
6834
  WEBHOOK_DELIVERY_STATUSES,
6558
6835
  WEBHOOK_EVENT_ID_HEADER,
@@ -6616,6 +6893,7 @@ function matchRoute(method, pathname) {
6616
6893
  editMainInsertions,
6617
6894
  effectivePreviewPicks,
6618
6895
  emptyFlow,
6896
+ emptyLinkValues,
6619
6897
  errorBody,
6620
6898
  escapeMergeHtml,
6621
6899
  exportFilename,
@@ -6646,6 +6924,8 @@ function matchRoute(method, pathname) {
6646
6924
  languageInsertions,
6647
6925
  languageName,
6648
6926
  languageTabs,
6927
+ letterOnlyValues,
6928
+ linkTokens,
6649
6929
  mainInsertionText,
6650
6930
  matchLocale,
6651
6931
  matchRoute,
@@ -6666,6 +6946,8 @@ function matchRoute(method, pathname) {
6666
6946
  previewInsertions,
6667
6947
  previewPersonalization,
6668
6948
  primaryLanguage,
6949
+ printedFields,
6950
+ rawMergeValue,
6669
6951
  reachable,
6670
6952
  readyWithoutInsertions,
6671
6953
  readyWithoutSubject,
@@ -6682,6 +6964,7 @@ function matchRoute(method, pathname) {
6682
6964
  renameTokenInDocument,
6683
6965
  renameTokenInText,
6684
6966
  resolveInsertions,
6967
+ resolveValue,
6685
6968
  restorePatch,
6686
6969
  routes,
6687
6970
  sameJson,
@@ -6705,8 +6988,11 @@ function matchRoute(method, pathname) {
6705
6988
  translationInsertionProblems,
6706
6989
  translationTextFromInput,
6707
6990
  triggerKey,
6991
+ trustedAppMayCall,
6708
6992
  unknownRefusedInsertions,
6709
6993
  unplacedInsertions,
6710
6994
  validateAutomation,
6995
+ valueNames,
6996
+ valuesRead,
6711
6997
  verifyWebhook
6712
6998
  });