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