@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.mjs CHANGED
@@ -77,6 +77,12 @@ var ERROR_STATUS = {
77
77
  invalid_mjml: 422,
78
78
  missing_unsubscribe_url: 422,
79
79
  mailing_not_ready: 422,
80
+ /**
81
+ * A value placed inside a link's address comes out empty for at least one
82
+ * recipient, so the mailing does not start; `details.values` lists each such
83
+ * value with how many recipients it is empty for.
84
+ */
85
+ unfilled_link: 422,
80
86
  unknown_topic: 422,
81
87
  unknown_provider: 422,
82
88
  /**
@@ -145,10 +151,10 @@ var API_VERSION_PREFIX = "/v1";
145
151
  var HEALTH_PATH = "/healthz";
146
152
 
147
153
  // src/workspace.ts
148
- import { z as z10 } from "zod";
154
+ import { z as z11 } from "zod";
149
155
 
150
156
  // src/automations.ts
151
- import { z as z9 } from "zod";
157
+ import { z as z10 } from "zod";
152
158
 
153
159
  // src/templates.ts
154
160
  import { z as z5 } from "zod";
@@ -169,11 +175,11 @@ var RESERVED_MERGE_FIELDS = {
169
175
  };
170
176
  var MERGE_FIELD_PATTERN = /\{\{\s*([a-z][a-z0-9_]*)\s*(?:\|([^}]*))?\}\}/g;
171
177
  function findMergeFields(html) {
172
- const uses = [];
178
+ const uses2 = [];
173
179
  for (const match of html.matchAll(MERGE_FIELD_PATTERN)) {
174
- uses.push({ name: match[1], fallback: match[2] === void 0 ? null : match[2].trim() });
180
+ uses2.push({ name: match[1], fallback: match[2] === void 0 ? null : match[2].trim() });
175
181
  }
176
- return uses;
182
+ return uses2;
177
183
  }
178
184
  function missingRequiredMergeFields(html) {
179
185
  const used = new Set(findMergeFields(html).map((u) => u.name));
@@ -856,10 +862,10 @@ function exportFilename(name, format) {
856
862
  }
857
863
 
858
864
  // src/platform.ts
859
- import { z as z8 } from "zod";
865
+ import { z as z9 } from "zod";
860
866
 
861
867
  // src/mailings.ts
862
- import { z as z7 } from "zod";
868
+ import { z as z8 } from "zod";
863
869
 
864
870
  // src/ab-test.ts
865
871
  import { z as z6 } from "zod";
@@ -910,6 +916,167 @@ function testGroupSize(total, fraction, variants) {
910
916
  return Math.min(total, Math.max(variants, Math.ceil(total * fraction)));
911
917
  }
912
918
 
919
+ // src/values.ts
920
+ import { z as z7 } from "zod";
921
+ var MAX_MERGE_DEFAULTS = 50;
922
+ var MAX_MERGE_DEFAULT_LENGTH = 2e3;
923
+ var MergeFieldName = z7.string().regex(/^[a-z][a-z0-9_]*$/, "a merge-field name: lowercase letters, digits and underscores, starting with a letter").max(64);
924
+ var MergeDefaultValue = z7.union([z7.string().max(MAX_MERGE_DEFAULT_LENGTH), z7.number().finite(), z7.boolean()]);
925
+ var MailingMerge = z7.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)), {
926
+ message: `the service fills ${SERVICE_FILLED_MERGE_FIELDS.join(" and ")}; a mailing cannot set them`
927
+ });
928
+ var LETTER_ONLY_MERGE_FIELDS = ["first_name", "last_name"];
929
+ var NAME_ON_BROADCAST_REFUSAL = "name_on_broadcast";
930
+ function letterOnlyValues(merge) {
931
+ return LETTER_ONLY_MERGE_FIELDS.filter((name) => ownEntry(merge, name) !== void 0);
932
+ }
933
+ var VALUE_LAYERS = ["recipient", "mailing", "contact", "workspace", "fallback", "empty"];
934
+ var ValueLayer = z7.enum(VALUE_LAYERS);
935
+ var ResolvedValue = z7.object({ text: z7.string(), layer: ValueLayer });
936
+ var MessageValues = z7.record(ResolvedValue);
937
+ function scalarText(value) {
938
+ if (typeof value === "string") return value;
939
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
940
+ if (typeof value === "boolean") return String(value);
941
+ return null;
942
+ }
943
+ function isNameField(name) {
944
+ return name === "first_name" || name === "last_name";
945
+ }
946
+ function rawMergeValue(name, sources) {
947
+ const own = ownEntry(sources.recipient, name);
948
+ if (scalarText(own) !== null) return { value: own, layer: "recipient" };
949
+ const held = ownEntry(sources.mailing, name);
950
+ if (scalarText(held) !== null) return { value: held, layer: "mailing" };
951
+ if (isNameField(name)) {
952
+ const stored = sources.contact?.[name];
953
+ return typeof stored === "string" ? { value: stored, layer: "contact" } : null;
954
+ }
955
+ const property = ownEntry(sources.contact?.properties, name);
956
+ if (scalarText(property) !== null) return { value: property, layer: "contact" };
957
+ const byDefault = ownEntry(sources.workspace, name);
958
+ return scalarText(byDefault) !== null ? { value: byDefault, layer: "workspace" } : null;
959
+ }
960
+ function resolveValue(name, fallback, sources) {
961
+ const found = rawMergeValue(name, sources);
962
+ const text = found === null ? null : scalarText(found.value);
963
+ if (found !== null && text !== null && text.trim() !== "") return { text, layer: found.layer };
964
+ const instead = fallback?.trim() ?? "";
965
+ return instead === "" ? { text: "", layer: "empty" } : { text: instead, layer: "fallback" };
966
+ }
967
+ function pattern2() {
968
+ return new RegExp(MERGE_FIELD_PATTERN.source, "g");
969
+ }
970
+ function isServiceFilled(name) {
971
+ return SERVICE_FILLED_MERGE_FIELDS.includes(name);
972
+ }
973
+ function uses(text) {
974
+ return [...text.matchAll(pattern2())].map((m) => ({ name: m[1], fallback: m[2] === void 0 ? null : m[2].trim() }));
975
+ }
976
+ function valueNames(texts, insertions) {
977
+ const names = [];
978
+ const add = (name) => {
979
+ if (!isServiceFilled(name) && !names.includes(name)) names.push(name);
980
+ };
981
+ for (const text of texts) {
982
+ for (const use of uses(text ?? "")) {
983
+ const def = ownEntry(insertions, use.name);
984
+ if (!def) {
985
+ add(use.name);
986
+ continue;
987
+ }
988
+ add(def.by);
989
+ for (const inner of [...Object.values(def.choices), def.filled ?? "", def.otherwise]) for (const u of uses(inner)) add(u.name);
990
+ }
991
+ }
992
+ return names;
993
+ }
994
+ function printedFields(texts, insertions, chosen2) {
995
+ const out = [];
996
+ const add = (use) => {
997
+ if (isServiceFilled(use.name)) return;
998
+ if (!out.some((o) => o.name === use.name && o.fallback === use.fallback)) out.push(use);
999
+ };
1000
+ for (const text of texts) {
1001
+ for (const use of uses(text ?? "")) {
1002
+ if (!ownEntry(insertions, use.name)) add(use);
1003
+ else for (const inner of uses(ownEntry(chosen2, use.name)?.text ?? "")) add(inner);
1004
+ }
1005
+ }
1006
+ return out;
1007
+ }
1008
+ function valuesRead(texts, insertions, chosen2, resolve) {
1009
+ const out = {};
1010
+ const read = (use) => {
1011
+ if (isServiceFilled(use.name)) return;
1012
+ const value = resolve(use.name, use.fallback);
1013
+ const seen = ownEntry(out, use.name);
1014
+ if (seen === void 0 || value.layer === "empty" && seen.layer !== "empty") out[use.name] = value;
1015
+ };
1016
+ for (const text of texts) {
1017
+ for (const use of uses(text ?? "")) {
1018
+ const def = ownEntry(insertions, use.name);
1019
+ if (!def) {
1020
+ read(use);
1021
+ continue;
1022
+ }
1023
+ read({ name: def.by, fallback: null });
1024
+ for (const inner of uses(ownEntry(chosen2, use.name)?.text ?? "")) read(inner);
1025
+ }
1026
+ }
1027
+ return out;
1028
+ }
1029
+ var HREF = /\bhref\s*=\s*(?:"([^"]*)"|'([^']*)')/gi;
1030
+ function linkTokens(html) {
1031
+ const out = [];
1032
+ for (const match of html.matchAll(HREF)) {
1033
+ for (const use of uses(match[1] ?? match[2] ?? "")) {
1034
+ if (isServiceFilled(use.name)) continue;
1035
+ if (!out.some((o) => o.name === use.name && o.fallback === use.fallback)) out.push(use);
1036
+ }
1037
+ }
1038
+ return out;
1039
+ }
1040
+ function emptyLinkValues(tokens, p) {
1041
+ const empty = [];
1042
+ for (const token of tokens) {
1043
+ const ins = ownEntry(p.insertions, token.name);
1044
+ const text = ins ? ins.text.replace(pattern2(), (_m, name, fallback) => p.value(name, fallback)) : p.value(token.name, token.fallback ?? void 0);
1045
+ if (text.trim() === "" && !empty.includes(token.name)) empty.push(token.name);
1046
+ }
1047
+ return empty;
1048
+ }
1049
+ var UnfilledLink = z7.object({
1050
+ /** The value, or the insertion, that comes out empty. */
1051
+ value: z7.string(),
1052
+ /** How many recipients it is empty for. */
1053
+ recipients: z7.number().int().min(1)
1054
+ });
1055
+ var RESOLVE_PROBLEMS = ["unfilled_link", "empty_value", "insertion_miss"];
1056
+ var ResolveProblem = z7.object({
1057
+ kind: z7.enum(RESOLVE_PROBLEMS),
1058
+ severity: z7.enum(["blocking", "note"]),
1059
+ value: z7.string(),
1060
+ message: z7.string()
1061
+ });
1062
+ var ResolvedRecipient = z7.object({
1063
+ /** The recipient's index in the request; null for the reader with nothing of their own. */
1064
+ index: z7.number().int().min(0).nullable(),
1065
+ /** The address the message would go to; null for the reader with nothing of their own. */
1066
+ email: Email.nullable(),
1067
+ /** The contact found for the recipient; null when the address has none yet (a send creates it, empty). */
1068
+ contact_id: Id.nullable(),
1069
+ /** The language version this recipient would get. */
1070
+ locale: LocaleTag,
1071
+ /** The subject line as they would read it. */
1072
+ subject: z7.string(),
1073
+ values: MessageValues,
1074
+ /** The choice each insertion would make; null when the content has none. */
1075
+ insertions: InsertionChoices.nullable(),
1076
+ problems: z7.array(ResolveProblem)
1077
+ });
1078
+ var RESOLVE_REJECTIONS = ["unknown_contact", "duplicate_in_batch"];
1079
+
913
1080
  // src/mailings.ts
914
1081
  var MAILING_STATUSES = [
915
1082
  "draft",
@@ -920,9 +1087,9 @@ var MAILING_STATUSES = [
920
1087
  "partially_failed",
921
1088
  "cancelled"
922
1089
  ];
923
- var MailingStatus = z7.enum(MAILING_STATUSES);
1090
+ var MailingStatus = z8.enum(MAILING_STATUSES);
924
1091
  var MAILING_ACTIONS = ["send", "schedule", "unschedule", "pause", "resume", "cancel", "retry-failed"];
925
- var MailingAction = z7.enum(MAILING_ACTIONS);
1092
+ var MailingAction = z8.enum(MAILING_ACTIONS);
926
1093
  var MAILING_TRANSITIONS = {
927
1094
  draft: ["send", "schedule", "cancel"],
928
1095
  scheduled: ["send", "schedule", "unschedule", "cancel"],
@@ -937,23 +1104,23 @@ function canTransition(status, action) {
937
1104
  }
938
1105
  var EDITABLE_MAILING_STATUSES = ["draft", "scheduled"];
939
1106
  var TERMINAL_MAILING_STATUSES = ["sent", "cancelled"];
940
- var MailingMetadata = z7.record(z7.string().max(500)).refine((v) => Object.keys(v).length <= 20, "at most 20 keys").refine((v) => Object.keys(v).every((k) => k.length >= 1 && k.length <= 64), "keys are 1 to 64 characters");
941
- var MailingCounts = z7.object({
942
- total: z7.number().int().min(0),
943
- queued: z7.number().int().min(0),
944
- sending: z7.number().int().min(0),
945
- sent: z7.number().int().min(0),
946
- failed: z7.number().int().min(0),
947
- skipped: z7.number().int().min(0)
1107
+ var MailingMetadata = z8.record(z8.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");
1108
+ var MailingCounts = z8.object({
1109
+ total: z8.number().int().min(0),
1110
+ queued: z8.number().int().min(0),
1111
+ sending: z8.number().int().min(0),
1112
+ sent: z8.number().int().min(0),
1113
+ failed: z8.number().int().min(0),
1114
+ skipped: z8.number().int().min(0)
948
1115
  });
949
1116
  var MAILING_KINDS = ["broadcast", "automation", "notification"];
950
- var MailingKind = z7.enum(MAILING_KINDS);
951
- var Mailing = z7.object({
1117
+ var MailingKind = z8.enum(MAILING_KINDS);
1118
+ var Mailing = z8.object({
952
1119
  id: Id,
953
1120
  kind: MailingKind,
954
- name: z7.string().max(200).nullable(),
955
- subject: z7.string().min(1).max(998),
956
- preheader: z7.string().max(500).nullable(),
1121
+ name: z8.string().max(200).nullable(),
1122
+ subject: z8.string().min(1).max(998),
1123
+ preheader: z8.string().max(500).nullable(),
957
1124
  /**
958
1125
  * The template the document was taken from, if any. The snapshot is what is
959
1126
  * sent in the main language; the template's other language versions are
@@ -995,6 +1162,12 @@ var Mailing = z7.object({
995
1162
  status: MailingStatus,
996
1163
  counts: MailingCounts,
997
1164
  metadata: MailingMetadata,
1165
+ /**
1166
+ * The values held on this mailing (see `MailingMerge`): the same for
1167
+ * everyone who gets it, above the contact's stored name and properties and
1168
+ * the workspace's defaults, below the recipient's own. Empty by default.
1169
+ */
1170
+ merge: MailingMerge.default({}),
998
1171
  scheduled_at: Timestamp.nullable(),
999
1172
  /** The A/B test on subject or content (S4), null when there is none. */
1000
1173
  ab_test: AbTestState.nullable(),
@@ -1006,15 +1179,15 @@ var Mailing = z7.object({
1006
1179
  * recipients refused as dead addresses in one run (see the provider's
1007
1180
  * `rejections.anomaly`). Resuming clears it and starts a new run.
1008
1181
  */
1009
- pause_reason: z7.string().nullable().default(null),
1182
+ pause_reason: z8.string().nullable().default(null),
1010
1183
  created_at: Timestamp,
1011
1184
  updated_at: Timestamp
1012
1185
  });
1013
1186
  var MailingSummary = Mailing.omit({ document: true });
1014
1187
  var MailingContent = {
1015
- name: z7.string().max(200).optional(),
1016
- subject: z7.string().min(1).max(998),
1017
- preheader: z7.string().max(500).optional(),
1188
+ name: z8.string().max(200).optional(),
1189
+ subject: z8.string().min(1).max(998),
1190
+ preheader: z8.string().max(500).optional(),
1018
1191
  /** See `Mailing.send_locale`. */
1019
1192
  send_locale: LocaleTag.nullable().optional(),
1020
1193
  /**
@@ -1025,9 +1198,11 @@ var MailingContent = {
1025
1198
  */
1026
1199
  topic: Slug.nullable().optional(),
1027
1200
  provider_id: Id,
1028
- metadata: MailingMetadata.optional()
1201
+ metadata: MailingMetadata.optional(),
1202
+ /** See `Mailing.merge`. `first_name` and `last_name` only on a letter (no topic). */
1203
+ merge: MailingMerge.optional()
1029
1204
  };
1030
- var MailingCreate = z7.object({
1205
+ var MailingCreate = z8.object({
1031
1206
  ...MailingContent,
1032
1207
  subject: MailingContent.subject.optional(),
1033
1208
  document: TemplateDocument.optional(),
@@ -1043,15 +1218,22 @@ var MailingCreate = z7.object({
1043
1218
  message: "a mailing made from a document needs a subject",
1044
1219
  path: ["subject"]
1045
1220
  });
1046
- var MailingUpdate = z7.object({
1047
- name: z7.string().max(200).nullable().optional(),
1221
+ var MailingUpdate = z8.object({
1222
+ name: z8.string().max(200).nullable().optional(),
1048
1223
  subject: MailingContent.subject.optional(),
1049
- preheader: z7.string().max(500).nullable().optional(),
1224
+ preheader: z8.string().max(500).nullable().optional(),
1050
1225
  /** Null turns a draft into a letter, which it can only be with at most one recipient. */
1051
1226
  topic: Slug.nullable().optional(),
1052
1227
  send_locale: LocaleTag.nullable().optional(),
1053
1228
  provider_id: Id.optional(),
1054
1229
  metadata: MailingMetadata.optional(),
1230
+ /**
1231
+ * Replaces the mailing's values whole (see `Mailing.merge`). Giving a
1232
+ * mailing that holds `first_name` or `last_name` a topic is refused
1233
+ * (`name_on_broadcast`) unless the same call replaces its values without
1234
+ * them.
1235
+ */
1236
+ merge: MailingMerge.optional(),
1055
1237
  document: TemplateDocument.optional()
1056
1238
  }).refine((v) => Object.keys(v).length > 0, "at least one field");
1057
1239
  var MailingListQuery = PageQuery.extend({
@@ -1060,30 +1242,30 @@ var MailingListQuery = PageQuery.extend({
1060
1242
  kind: MailingKind.optional(),
1061
1243
  automation_id: Id.optional()
1062
1244
  });
1063
- var MailingSendRequest = z7.object({}).strict();
1064
- var MailingRetryFailedRequest = z7.object({
1245
+ var MailingSendRequest = z8.object({}).strict();
1246
+ var MailingRetryFailedRequest = z8.object({
1065
1247
  /**
1066
1248
  * Also requeue recipients whose outcome is unknown after a crash. They may
1067
1249
  * already have received the message, so this is a human's decision, never a
1068
1250
  * default.
1069
1251
  */
1070
- include_outcome_unknown: z7.boolean().optional()
1252
+ include_outcome_unknown: z8.boolean().optional()
1071
1253
  }).strict();
1072
- var MailingActionRequest = z7.object({}).strict();
1073
- var MailingTestRequest = z7.object({
1254
+ var MailingActionRequest = z8.object({}).strict();
1255
+ var MailingTestRequest = z8.object({
1074
1256
  to: Email,
1075
1257
  merge: Properties.optional(),
1076
1258
  locale: LocaleTag.optional()
1077
1259
  });
1078
- var MailingTestResult = z7.object({
1260
+ var MailingTestResult = z8.object({
1079
1261
  message_id: Id,
1080
- provider_message_id: z7.string().nullable()
1262
+ provider_message_id: z8.string().nullable()
1081
1263
  });
1082
1264
  var RECIPIENT_STATUSES = ["queued", "sending", "sent", "failed", "skipped"];
1083
- var RecipientStatus = z7.enum(RECIPIENT_STATUSES);
1265
+ var RecipientStatus = z8.enum(RECIPIENT_STATUSES);
1084
1266
  var SKIP_REASONS = ["suppressed", "not_subscribed", "contact_erased", "cancelled", "outcome_unknown"];
1085
- var SkipReason = z7.enum(SKIP_REASONS);
1086
- var Recipient = z7.object({
1267
+ var SkipReason = z8.enum(SKIP_REASONS);
1268
+ var Recipient = z8.object({
1087
1269
  id: Id,
1088
1270
  mailing_id: Id,
1089
1271
  contact_id: Id.nullable(),
@@ -1091,55 +1273,55 @@ var Recipient = z7.object({
1091
1273
  merge: Properties,
1092
1274
  status: RecipientStatus,
1093
1275
  skip_reason: SkipReason.nullable(),
1094
- attempts: z7.number().int().min(0),
1276
+ attempts: z8.number().int().min(0),
1095
1277
  message_id: Id.nullable(),
1096
- last_error: z7.string().nullable(),
1278
+ last_error: z8.string().nullable(),
1097
1279
  created_at: Timestamp,
1098
1280
  updated_at: Timestamp
1099
1281
  });
1100
1282
  var MAX_RECIPIENTS_PER_BATCH = 1e3;
1101
1283
  var MAX_LETTER_RECIPIENTS = 1;
1102
1284
  var LETTER_RECIPIENT_REFUSAL = "letter_has_one_recipient";
1103
- var RecipientInput = z7.object({
1285
+ var RecipientInput = z8.object({
1104
1286
  contact_id: Id.optional(),
1105
- external_id: z7.string().min(1).max(255).optional(),
1287
+ external_id: z8.string().min(1).max(255).optional(),
1106
1288
  email: Email.optional(),
1107
1289
  merge: Properties.optional()
1108
1290
  }).refine((v) => v.contact_id !== void 0 || v.external_id !== void 0 || v.email !== void 0, {
1109
1291
  message: "contact_id, external_id or email is required",
1110
1292
  path: ["email"]
1111
1293
  });
1112
- var RecipientBatch = z7.object({
1113
- recipients: z7.array(RecipientInput).min(1).max(MAX_RECIPIENTS_PER_BATCH)
1294
+ var RecipientBatch = z8.object({
1295
+ recipients: z8.array(RecipientInput).min(1).max(MAX_RECIPIENTS_PER_BATCH)
1114
1296
  });
1115
1297
  var RECIPIENT_REJECTIONS = ["unknown_contact", "duplicate_in_batch"];
1116
- var RecipientBatchResult = z7.object({
1298
+ var RecipientBatchResult = z8.object({
1117
1299
  /** Newly queued. */
1118
- added: z7.number().int().min(0),
1300
+ added: z8.number().int().min(0),
1119
1301
  /** Already on the mailing from an earlier batch: left unchanged. */
1120
- already_present: z7.number().int().min(0),
1302
+ already_present: z8.number().int().min(0),
1121
1303
  /** Items not added, by their index in the request. */
1122
- rejected: z7.array(z7.object({ index: z7.number().int().min(0), reason: z7.enum(RECIPIENT_REJECTIONS) }))
1304
+ rejected: z8.array(z8.object({ index: z8.number().int().min(0), reason: z8.enum(RECIPIENT_REJECTIONS) }))
1123
1305
  });
1124
1306
  var RecipientListQuery = PageQuery.extend({
1125
1307
  status: RecipientStatus.optional(),
1126
1308
  skip_reason: SkipReason.optional()
1127
1309
  });
1128
1310
  var MESSAGE_OUTCOMES = ["sent", "failed"];
1129
- var MessageOutcome = z7.enum(MESSAGE_OUTCOMES);
1130
- var MessageSummary = z7.object({
1311
+ var MessageOutcome = z8.enum(MESSAGE_OUTCOMES);
1312
+ var MessageSummary = z8.object({
1131
1313
  id: Id,
1132
1314
  mailing_id: Id.nullable(),
1133
1315
  recipient_id: Id.nullable(),
1134
1316
  contact_id: Id.nullable(),
1135
1317
  to: Email,
1136
- subject: z7.string(),
1318
+ subject: z8.string(),
1137
1319
  provider_id: Id,
1138
- provider_message_id: z7.string().nullable(),
1320
+ provider_message_id: z8.string().nullable(),
1139
1321
  outcome: MessageOutcome,
1140
- error: z7.string().nullable(),
1141
- is_test: z7.boolean(),
1142
- recipient_count: z7.number().int().min(1),
1322
+ error: z8.string().nullable(),
1323
+ is_test: z8.boolean(),
1324
+ recipient_count: z8.number().int().min(1),
1143
1325
  /** The language version the message was sent in; null for messages archived before languages existed. */
1144
1326
  locale: LocaleTag.nullable(),
1145
1327
  /**
@@ -1149,24 +1331,32 @@ var MessageSummary = z7.object({
1149
1331
  * "otherwise" text. Null when the message had no insertions.
1150
1332
  */
1151
1333
  insertions: InsertionChoices.nullable(),
1334
+ /**
1335
+ * The values the message was written with, by name: the text each one
1336
+ * printed and the layer it came from (see `MessageValues`), recorded when it
1337
+ * was sent, so a later change to a default never rewrites what a reader got.
1338
+ * Null for a message archived before values were recorded, and for a signup
1339
+ * form's confirmation, which belongs to no mailing.
1340
+ */
1341
+ values: MessageValues.nullable().default(null),
1152
1342
  created_at: Timestamp
1153
1343
  });
1154
- var Message = MessageSummary.extend({ html: z7.string() });
1155
- var MailingLanguageStatus = z7.enum(["main", "ready", "draft", "not_a_workspace_language"]);
1156
- var MailingLanguage = z7.object({
1344
+ var Message = MessageSummary.extend({ html: z8.string() });
1345
+ var MailingLanguageStatus = z8.enum(["main", "ready", "draft", "not_a_workspace_language"]);
1346
+ var MailingLanguage = z8.object({
1157
1347
  locale: LocaleTag,
1158
1348
  status: MailingLanguageStatus,
1159
1349
  /** Queued recipients who will get this version. */
1160
- planned: z7.number().int().min(0),
1350
+ planned: z8.number().int().min(0),
1161
1351
  /** Messages already sent in this language (tests excluded). */
1162
- sent: z7.number().int().min(0)
1352
+ sent: z8.number().int().min(0)
1163
1353
  });
1164
- var MailingLanguageReport = z7.object({
1354
+ var MailingLanguageReport = z8.object({
1165
1355
  main_locale: LocaleTag,
1166
1356
  send_locale: LocaleTag.nullable(),
1167
- languages: z7.array(MailingLanguage),
1168
- fallback: z7.array(z7.object({ wanted: z7.string(), planned: z7.number().int().min(1) })),
1169
- no_language: z7.number().int().min(0),
1357
+ languages: z8.array(MailingLanguage),
1358
+ fallback: z8.array(z8.object({ wanted: z8.string(), planned: z8.number().int().min(1) })),
1359
+ no_language: z8.number().int().min(0),
1170
1360
  /**
1171
1361
  * Values that no choice of an insertion takes, so the "otherwise" text goes
1172
1362
  * out (docs/plans/2026-09-25-translated-insertions.md, decision 3): per
@@ -1175,41 +1365,56 @@ var MailingLanguageReport = z7.object({
1175
1365
  * template's keys never produces one; a non-empty list means the client and
1176
1366
  * the template have drifted apart.
1177
1367
  */
1178
- insertion_misses: z7.array(
1179
- z7.object({
1180
- insertion: z7.string(),
1181
- value: z7.string(),
1182
- planned: z7.number().int().min(0),
1183
- sent: z7.number().int().min(0)
1368
+ insertion_misses: z8.array(
1369
+ z8.object({
1370
+ insertion: z8.string(),
1371
+ value: z8.string(),
1372
+ planned: z8.number().int().min(0),
1373
+ sent: z8.number().int().min(0)
1184
1374
  })
1185
1375
  )
1186
1376
  });
1377
+ var MailingResolveRequest = z8.object({
1378
+ recipients: z8.array(RecipientInput).max(MAX_RECIPIENTS_PER_BATCH).optional()
1379
+ });
1380
+ var MailingResolveResult = z8.object({
1381
+ /** Every value the mailing's content can read, in order of first appearance, without `email` and `unsubscribe_url`. */
1382
+ names: z8.array(z8.string()),
1383
+ /** The values and insertions placed inside a link's address: one of them empty for anybody refuses the send. */
1384
+ link_values: z8.array(z8.string()),
1385
+ /** One entry per resolved recipient, in the request's order; a single entry with `index: null` when none were given. */
1386
+ recipients: z8.array(ResolvedRecipient),
1387
+ /** Items not resolved, by their index in the request, for the reasons `mailings.addRecipients` rejects one. */
1388
+ rejected: z8.array(z8.object({ index: z8.number().int().min(0), reason: z8.enum(RESOLVE_REJECTIONS) })),
1389
+ /** What would refuse `mailings.send` for these recipients, as its `unfilled_link` refusal lists it; empty means none. */
1390
+ blocking: z8.array(UnfilledLink)
1391
+ });
1187
1392
  var MessageListQuery = PageQuery.extend({
1188
1393
  mailing_id: Id.optional(),
1189
1394
  outcome: MessageOutcome.optional()
1190
1395
  });
1191
1396
 
1192
1397
  // src/platform.ts
1193
- var Tag = z8.object({
1398
+ var Tag = z9.object({
1194
1399
  id: Id,
1195
1400
  slug: Slug,
1196
- name: z8.string().min(1).max(120),
1197
- contact_count: z8.number().int().min(0),
1401
+ name: z9.string().min(1).max(120),
1402
+ contact_count: z9.number().int().min(0),
1198
1403
  created_at: Timestamp
1199
1404
  });
1200
- var TagCreate = z8.object({ slug: Slug, name: z8.string().min(1).max(120) });
1201
- var TagAssignment = z8.object({
1202
- contact_ids: z8.array(Id).min(1).max(1e3)
1405
+ var TagCreate = z9.object({ slug: Slug, name: z9.string().min(1).max(120) });
1406
+ var TagAssignment = z9.object({
1407
+ contact_ids: z9.array(Id).min(1).max(1e3)
1203
1408
  });
1204
1409
  var CONTACT_PROPERTY_TYPES = ["string", "number", "boolean", "date"];
1205
- var ContactPropertyType = z8.enum(CONTACT_PROPERTY_TYPES);
1206
- var ContactPropertyKey = z8.string().regex(/^[A-Za-z0-9_.-]{1,64}$/, "letters, digits, dot, underscore and hyphen, 1 to 64");
1207
- var ContactPropertyDefinition = z8.object({
1410
+ var ContactPropertyType = z9.enum(CONTACT_PROPERTY_TYPES);
1411
+ var ContactPropertyKey = z9.string().regex(/^[A-Za-z0-9_.-]{1,64}$/, "letters, digits, dot, underscore and hyphen, 1 to 64");
1412
+ var ContactPropertyDefinition = z9.object({
1208
1413
  key: ContactPropertyKey,
1209
- label: z8.string().min(1).max(120),
1414
+ label: z9.string().min(1).max(120),
1210
1415
  type: ContactPropertyType
1211
1416
  });
1212
- var ContactPropertyParams = z8.object({ key: ContactPropertyKey });
1417
+ var ContactPropertyParams = z9.object({ key: ContactPropertyKey });
1213
1418
  var FILTER_OPERATORS = [
1214
1419
  "eq",
1215
1420
  "neq",
@@ -1225,8 +1430,8 @@ var FILTER_OPERATORS = [
1225
1430
  "in",
1226
1431
  "not_in"
1227
1432
  ];
1228
- var FilterOperator = z8.enum(FILTER_OPERATORS);
1229
- var FilterField = z8.string().regex(
1433
+ var FilterOperator = z9.enum(FILTER_OPERATORS);
1434
+ var FilterField = z9.string().regex(
1230
1435
  /^(email|first_name|last_name|locale|created_at|tag|topic|engagement:(opened|clicked)|property:[A-Za-z0-9_.-]{1,64})$/,
1231
1436
  "unknown filter field"
1232
1437
  );
@@ -1242,18 +1447,18 @@ var FILTER_FIELD_OPERATORS = {
1242
1447
  property: FILTER_OPERATORS
1243
1448
  };
1244
1449
  var MAX_FILTER_DEPTH = 5;
1245
- var FilterCondition = z8.object({ field: FilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1450
+ var FilterCondition = z9.object({ field: FilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1246
1451
  message: "exists and not_exists take no value; every other operator needs one",
1247
1452
  path: ["value"]
1248
1453
  }).refine((c) => c.op !== "in" && c.op !== "not_in" || Array.isArray(c.value), {
1249
1454
  message: "in and not_in take an array",
1250
1455
  path: ["value"]
1251
1456
  });
1252
- var SegmentFilter = z8.lazy(
1253
- () => z8.union([
1254
- z8.object({ and: z8.array(SegmentFilter).min(1).max(50) }).strict(),
1255
- z8.object({ or: z8.array(SegmentFilter).min(1).max(50) }).strict(),
1256
- z8.object({ not: SegmentFilter }).strict(),
1457
+ var SegmentFilter = z9.lazy(
1458
+ () => z9.union([
1459
+ z9.object({ and: z9.array(SegmentFilter).min(1).max(50) }).strict(),
1460
+ z9.object({ or: z9.array(SegmentFilter).min(1).max(50) }).strict(),
1461
+ z9.object({ not: SegmentFilter }).strict(),
1257
1462
  FilterCondition
1258
1463
  ])
1259
1464
  );
@@ -1341,42 +1546,42 @@ function untypedValueProblem(c, every) {
1341
1546
  if (orderOp) return every(isFilterNumber, "numbers (define the property to compare dates)");
1342
1547
  return every((v) => isScalar(v) || v === null, "strings, numbers, booleans or null");
1343
1548
  }
1344
- var Segment = z8.object({
1549
+ var Segment = z9.object({
1345
1550
  id: Id,
1346
- name: z8.string().min(1).max(120),
1551
+ name: z9.string().min(1).max(120),
1347
1552
  filter: SegmentFilter,
1348
1553
  /** Computed on read. */
1349
- contact_count: z8.number().int().min(0),
1554
+ contact_count: z9.number().int().min(0),
1350
1555
  created_at: Timestamp,
1351
1556
  updated_at: Timestamp
1352
1557
  });
1353
- var SegmentCreate = z8.object({ name: z8.string().min(1).max(120), filter: BoundedSegmentFilter });
1354
- var SegmentPreviewRequest = z8.object({ filter: BoundedSegmentFilter });
1355
- var SegmentPreview = z8.object({
1356
- contact_count: z8.number().int().min(0),
1558
+ var SegmentCreate = z9.object({ name: z9.string().min(1).max(120), filter: BoundedSegmentFilter });
1559
+ var SegmentPreviewRequest = z9.object({ filter: BoundedSegmentFilter });
1560
+ var SegmentPreview = z9.object({
1561
+ contact_count: z9.number().int().min(0),
1357
1562
  /** Up to five matching contacts, for a human to sanity-check the filter. */
1358
- sample: z8.array(z8.object({ id: Id, email: Email })).max(5)
1563
+ sample: z9.array(z9.object({ id: Id, email: Email })).max(5)
1359
1564
  });
1360
- var MailingAudienceFromSegment = z8.object({ segment_id: Id });
1565
+ var MailingAudienceFromSegment = z9.object({ segment_id: Id });
1361
1566
  var SIGNUP_FORM_FIELDS = ["first_name", "last_name"];
1362
1567
  var HOSTED_PAGE_LOCALES = ["en", "de", "it", "fr", "es"];
1363
- var SignupFormTranslation = z8.object({
1364
- title: z8.string().min(1).max(120),
1365
- consent_text: z8.string().min(1).max(2e3)
1568
+ var SignupFormTranslation = z9.object({
1569
+ title: z9.string().min(1).max(120),
1570
+ consent_text: z9.string().min(1).max(2e3)
1366
1571
  });
1367
- var SignupForm = z8.object({
1572
+ var SignupForm = z9.object({
1368
1573
  id: Id,
1369
- name: z8.string().min(1).max(120),
1574
+ name: z9.string().min(1).max(120),
1370
1575
  /** The heading of the hosted page. */
1371
- title: z8.string().min(1).max(120),
1576
+ title: z9.string().min(1).max(120),
1372
1577
  /** What the person agrees to, shown above the button and recorded with the confirmation. */
1373
- consent_text: z8.string().min(1).max(2e3),
1374
- translations: z8.record(SignupFormTranslation),
1375
- topics: z8.array(Slug).min(1),
1376
- tags: z8.array(Slug),
1578
+ consent_text: z9.string().min(1).max(2e3),
1579
+ translations: z9.record(SignupFormTranslation),
1580
+ topics: z9.array(Slug).min(1),
1581
+ tags: z9.array(Slug),
1377
1582
  /** Fields shown besides email. */
1378
- fields: z8.array(z8.enum(SIGNUP_FORM_FIELDS)),
1379
- double_opt_in: z8.literal(true),
1583
+ fields: z9.array(z9.enum(SIGNUP_FORM_FIELDS)),
1584
+ double_opt_in: z9.literal(true),
1380
1585
  /** The provider the confirmation mail is sent through. */
1381
1586
  provider_id: Id,
1382
1587
  /**
@@ -1385,11 +1590,11 @@ var SignupForm = z8.object({
1385
1590
  */
1386
1591
  confirmation_template_id: Id.nullable(),
1387
1592
  /** Where the person lands after confirming. Null shows the hosted confirmation page. */
1388
- redirect_url: z8.string().url().nullable(),
1593
+ redirect_url: z9.string().url().nullable(),
1389
1594
  /** Origins allowed to embed the form and call the submission route from a browser. */
1390
- allowed_origins: z8.array(z8.string().url()).max(20),
1595
+ allowed_origins: z9.array(z9.string().url()).max(20),
1391
1596
  /** Bumped on every change; recorded with each confirmation. */
1392
- version: z8.number().int().min(1),
1597
+ version: z9.number().int().min(1),
1393
1598
  created_at: Timestamp,
1394
1599
  updated_at: Timestamp
1395
1600
  });
@@ -1404,56 +1609,56 @@ var SignupFormCreate = SignupForm.omit({
1404
1609
  tags: SignupForm.shape.tags.optional(),
1405
1610
  fields: SignupForm.shape.fields.optional(),
1406
1611
  confirmation_template_id: Id.nullable().optional(),
1407
- redirect_url: z8.string().url().nullable().optional(),
1612
+ redirect_url: z9.string().url().nullable().optional(),
1408
1613
  allowed_origins: SignupForm.shape.allowed_origins.optional()
1409
1614
  });
1410
- var SignupFormEmbed = z8.object({
1411
- hosted_url: z8.string().url(),
1615
+ var SignupFormEmbed = z9.object({
1616
+ hosted_url: z9.string().url(),
1412
1617
  /** A plain HTML form posting to the hosted page; works without JavaScript. */
1413
- html: z8.string(),
1618
+ html: z9.string(),
1414
1619
  /** A small optional script that adds the time check and submits in place. */
1415
- script_url: z8.string().url(),
1620
+ script_url: z9.string().url(),
1416
1621
  /** Where a browser fetches a fresh `form_token` from (GET, public, CORS for `allowed_origins`). */
1417
- token_url: z8.string().url()
1622
+ token_url: z9.string().url()
1418
1623
  });
1419
- var SignupSubmission = z8.object({
1624
+ var SignupSubmission = z9.object({
1420
1625
  email: Email,
1421
- first_name: z8.string().max(200).optional(),
1422
- last_name: z8.string().max(200).optional(),
1423
- locale: z8.string().min(2).max(35).optional(),
1626
+ first_name: z9.string().max(200).optional(),
1627
+ last_name: z9.string().max(200).optional(),
1628
+ locale: z9.string().min(2).max(35).optional(),
1424
1629
  /** Honeypot: must be empty. */
1425
- website: z8.string().max(0).optional(),
1630
+ website: z9.string().max(0).optional(),
1426
1631
  /**
1427
1632
  * The signed render time from the form's token URL: a submission sooner than a
1428
1633
  * human could fill the form, or long after, is refused.
1429
1634
  */
1430
- form_token: z8.string().min(1).max(512)
1635
+ form_token: z9.string().min(1).max(512)
1431
1636
  });
1432
1637
  var IMPORT_STATUSES = ["uploaded", "validating", "validated", "committing", "completed", "failed", "cancelled"];
1433
- var ImportStatus = z8.enum(IMPORT_STATUSES);
1638
+ var ImportStatus = z9.enum(IMPORT_STATUSES);
1434
1639
  var IMPORT_TERMINAL_STATUSES = ["completed", "failed", "cancelled"];
1435
- var ImportColumnMapping = z8.record(
1436
- z8.string().regex(/^(email|external_id|first_name|last_name|locale|property:[A-Za-z0-9_.-]{1,64}|ignore)$/)
1640
+ var ImportColumnMapping = z9.record(
1641
+ z9.string().regex(/^(email|external_id|first_name|last_name|locale|property:[A-Za-z0-9_.-]{1,64}|ignore)$/)
1437
1642
  );
1438
1643
  var IMPORT_FILE_FIELD = "file";
1439
1644
  var MAX_IMPORT_BYTES = 50 * 1024 * 1024;
1440
1645
  var MAX_IMPORT_ROWS = 2e5;
1441
- var ImportMappingRequest = z8.object({
1646
+ var ImportMappingRequest = z9.object({
1442
1647
  /** CSV header -> contact field. Exactly one column maps to `email`. */
1443
1648
  mapping: ImportColumnMapping.refine(
1444
1649
  (m) => Object.values(m).filter((v) => v === "email").length === 1,
1445
1650
  "exactly one column maps to email"
1446
1651
  ),
1447
- topics: z8.array(Slug).max(100),
1448
- tags: z8.array(Slug).max(100),
1652
+ topics: z9.array(Slug).max(100),
1653
+ tags: z9.array(Slug).max(100),
1449
1654
  /** Existing contacts get the mapped fields overwritten; false only adds topics, tags and missing fields. */
1450
- update_existing: z8.boolean().optional(),
1655
+ update_existing: z9.boolean().optional(),
1451
1656
  /** The importer states the people consented; the service records who said so and when. */
1452
- consent_confirmed: z8.literal(true)
1657
+ consent_confirmed: z9.literal(true)
1453
1658
  });
1454
- var ImportCommitRequest = z8.object({ mapping_version: z8.number().int().min(1) });
1659
+ var ImportCommitRequest = z9.object({ mapping_version: z9.number().int().min(1) });
1455
1660
  var IMPORT_ROW_OUTCOMES = ["created", "updated", "unchanged", "suppressed", "skipped"];
1456
- var ImportRowOutcome = z8.enum(IMPORT_ROW_OUTCOMES);
1661
+ var ImportRowOutcome = z9.enum(IMPORT_ROW_OUTCOMES);
1457
1662
  var IMPORT_SKIP_REASONS = [
1458
1663
  "missing_email",
1459
1664
  "invalid_email",
@@ -1462,90 +1667,90 @@ var IMPORT_SKIP_REASONS = [
1462
1667
  "external_id_conflict",
1463
1668
  "wrong_column_count"
1464
1669
  ];
1465
- var ImportSkipReason = z8.enum(IMPORT_SKIP_REASONS);
1466
- var ImportReport = z8.object({
1467
- created: z8.number().int().min(0),
1468
- updated: z8.number().int().min(0),
1469
- unchanged: z8.number().int().min(0),
1470
- suppressed: z8.number().int().min(0),
1471
- skipped: z8.number().int().min(0),
1472
- skipped_by_reason: z8.record(ImportSkipReason, z8.number().int().min(0)),
1670
+ var ImportSkipReason = z9.enum(IMPORT_SKIP_REASONS);
1671
+ var ImportReport = z9.object({
1672
+ created: z9.number().int().min(0),
1673
+ updated: z9.number().int().min(0),
1674
+ unchanged: z9.number().int().min(0),
1675
+ suppressed: z9.number().int().min(0),
1676
+ skipped: z9.number().int().min(0),
1677
+ skipped_by_reason: z9.record(ImportSkipReason, z9.number().int().min(0)),
1473
1678
  /** Rows whose contact was subscribed without some topic, because the address is blocked for it. */
1474
- topics_withheld: z8.number().int().min(0)
1679
+ topics_withheld: z9.number().int().min(0)
1475
1680
  });
1476
- var ImportJob = z8.object({
1681
+ var ImportJob = z9.object({
1477
1682
  id: Id,
1478
1683
  status: ImportStatus,
1479
- file_name: z8.string().max(255).nullable(),
1480
- file_bytes: z8.number().int().min(0),
1481
- total_rows: z8.number().int().min(0),
1684
+ file_name: z9.string().max(255).nullable(),
1685
+ file_bytes: z9.number().int().min(0),
1686
+ total_rows: z9.number().int().min(0),
1482
1687
  /** The header row, as in the file. */
1483
- columns: z8.array(z8.string()),
1688
+ columns: z9.array(z9.string()),
1484
1689
  /** The first rows, for the mapping screen. */
1485
- sample: z8.array(z8.array(z8.string())).max(5),
1690
+ sample: z9.array(z9.array(z9.string())).max(5),
1486
1691
  /** A mapping guessed from the headers, for the mapping screen to start from. */
1487
1692
  suggested_mapping: ImportColumnMapping,
1488
1693
  mapping: ImportColumnMapping.nullable(),
1489
- mapping_version: z8.number().int().min(0),
1490
- topics: z8.array(Slug),
1491
- tags: z8.array(Slug),
1492
- update_existing: z8.boolean(),
1694
+ mapping_version: z9.number().int().min(0),
1695
+ topics: z9.array(Slug),
1696
+ tags: z9.array(Slug),
1697
+ update_existing: z9.boolean(),
1493
1698
  /** The dry run of the current mapping; null before one finished. */
1494
1699
  dry_run: ImportReport.nullable(),
1495
1700
  /** What the commit has written so far; null before it started. */
1496
1701
  result: ImportReport.nullable(),
1497
1702
  /** Rows the current phase (dry run or commit) has processed. */
1498
- processed_rows: z8.number().int().min(0),
1703
+ processed_rows: z9.number().int().min(0),
1499
1704
  /** Why a `failed` import failed. */
1500
- error: z8.string().nullable(),
1705
+ error: z9.string().nullable(),
1501
1706
  created_at: Timestamp,
1502
1707
  updated_at: Timestamp,
1503
1708
  finished_at: Timestamp.nullable()
1504
1709
  });
1505
- var ImportRow = z8.object({
1710
+ var ImportRow = z9.object({
1506
1711
  /** The line in the file, 1 being the first line after the header. */
1507
- row: z8.number().int().min(1),
1508
- email: z8.string().nullable(),
1712
+ row: z9.number().int().min(1),
1713
+ email: z9.string().nullable(),
1509
1714
  outcome: ImportRowOutcome,
1510
1715
  reason: ImportSkipReason.nullable(),
1511
1716
  /** A human explanation for a skipped row (which value, which column). */
1512
- message: z8.string().nullable(),
1717
+ message: z9.string().nullable(),
1513
1718
  contact_id: Id.nullable()
1514
1719
  });
1515
1720
  var ImportRowListQuery = PageQuery.extend({ outcome: ImportRowOutcome.optional() });
1516
- var MailingScheduleRequest = z8.object({ send_at: Timestamp });
1517
- var TrackingSettings = z8.object({ opens: z8.boolean(), clicks: z8.boolean() });
1518
- var VariantAnalytics = z8.object({
1519
- key: z8.string(),
1520
- sent: z8.number().int().min(0),
1521
- unique_opens: z8.number().int().min(0).nullable(),
1522
- unique_clicks: z8.number().int().min(0).nullable()
1523
- });
1524
- var MailingAnalytics = z8.object({
1721
+ var MailingScheduleRequest = z9.object({ send_at: Timestamp });
1722
+ var TrackingSettings = z9.object({ opens: z9.boolean(), clicks: z9.boolean() });
1723
+ var VariantAnalytics = z9.object({
1724
+ key: z9.string(),
1725
+ sent: z9.number().int().min(0),
1726
+ unique_opens: z9.number().int().min(0).nullable(),
1727
+ unique_clicks: z9.number().int().min(0).nullable()
1728
+ });
1729
+ var MailingAnalytics = z9.object({
1525
1730
  mailing_id: Id,
1526
1731
  counts: MailingCounts,
1527
1732
  /** What was tracked for this mailing, fixed when it started; null before it started. */
1528
1733
  tracking: TrackingSettings.nullable(),
1529
1734
  /** Unique recipients with a human open. Null when opens were not tracked. */
1530
- unique_opens: z8.number().int().min(0).nullable(),
1735
+ unique_opens: z9.number().int().min(0).nullable(),
1531
1736
  /**
1532
1737
  * Recipients whose only opens came from Apple Mail Privacy Protection, which
1533
1738
  * loads every image on delivery: counted apart, never as human opens.
1534
1739
  */
1535
- apple_mpp_opens: z8.number().int().min(0).nullable(),
1740
+ apple_mpp_opens: z9.number().int().min(0).nullable(),
1536
1741
  /** Opens and clicks from security scanners and prefetchers, filtered out of the unique counts. */
1537
- machine_events: z8.number().int().min(0).nullable(),
1538
- unique_clicks: z8.number().int().min(0).nullable(),
1539
- unsubscribes: z8.number().int().min(0),
1540
- bounces: z8.number().int().min(0),
1541
- complaints: z8.number().int().min(0),
1542
- links: z8.array(z8.object({ url: z8.string(), unique_clicks: z8.number().int().min(0) })).nullable(),
1543
- variants: z8.array(VariantAnalytics).nullable()
1742
+ machine_events: z9.number().int().min(0).nullable(),
1743
+ unique_clicks: z9.number().int().min(0).nullable(),
1744
+ unsubscribes: z9.number().int().min(0),
1745
+ bounces: z9.number().int().min(0),
1746
+ complaints: z9.number().int().min(0),
1747
+ links: z9.array(z9.object({ url: z9.string(), unique_clicks: z9.number().int().min(0) })).nullable(),
1748
+ variants: z9.array(VariantAnalytics).nullable()
1544
1749
  });
1545
1750
 
1546
1751
  // src/automations.ts
1547
1752
  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})$/;
1548
- var AutomationFilterField = z9.string().regex(AUTOMATION_FILTER_FIELD_PATTERN, "unknown filter field");
1753
+ var AutomationFilterField = z10.string().regex(AUTOMATION_FILTER_FIELD_PATTERN, "unknown filter field");
1549
1754
  var AUTOMATION_FILTER_FIELD_OPERATORS = {
1550
1755
  ...FILTER_FIELD_OPERATORS,
1551
1756
  segment: ["eq", "neq", "in", "not_in"],
@@ -1555,18 +1760,18 @@ var AUTOMATION_FILTER_FIELD_OPERATORS = {
1555
1760
  step: ["eq", "neq"]
1556
1761
  };
1557
1762
  var automationFilterFamily = filterFieldFamily;
1558
- var AutomationFilterCondition = z9.object({ field: AutomationFilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1763
+ var AutomationFilterCondition = z10.object({ field: AutomationFilterField, op: FilterOperator, value: JsonValue.optional() }).strict().refine((c) => (c.op === "exists" || c.op === "not_exists") === (c.value === void 0), {
1559
1764
  message: "exists and not_exists take no value; every other operator needs one",
1560
1765
  path: ["value"]
1561
1766
  }).refine((c) => c.op !== "in" && c.op !== "not_in" || Array.isArray(c.value), {
1562
1767
  message: "in and not_in take an array",
1563
1768
  path: ["value"]
1564
1769
  });
1565
- var AutomationFilter = z9.lazy(
1566
- () => z9.union([
1567
- z9.object({ and: z9.array(AutomationFilter).min(1).max(50) }).strict(),
1568
- z9.object({ or: z9.array(AutomationFilter).min(1).max(50) }).strict(),
1569
- z9.object({ not: AutomationFilter }).strict(),
1770
+ var AutomationFilter = z10.lazy(
1771
+ () => z10.union([
1772
+ z10.object({ and: z10.array(AutomationFilter).min(1).max(50) }).strict(),
1773
+ z10.object({ or: z10.array(AutomationFilter).min(1).max(50) }).strict(),
1774
+ z10.object({ not: AutomationFilter }).strict(),
1570
1775
  AutomationFilterCondition
1571
1776
  ])
1572
1777
  );
@@ -1579,20 +1784,20 @@ function filterConditions(filter) {
1579
1784
  if ("not" in filter) return filterConditions(filter.not);
1580
1785
  return [filter];
1581
1786
  }
1582
- var StepId = z9.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "letters, digits, underscore and hyphen, 1 to 64");
1583
- var TimeOfDay = z9.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "HH:MM in 24 hours");
1584
- var Weekday = z9.number().int().min(0).max(6);
1585
- var TimezoneName = z9.string().min(1).max(64).regex(/^(UTC|[A-Za-z][A-Za-z0-9_+-]*(?:\/[A-Za-z0-9_+-]+)+)$/, "an IANA time zone name such as Europe/Berlin");
1787
+ var StepId = z10.string().regex(/^[A-Za-z0-9_-]{1,64}$/, "letters, digits, underscore and hyphen, 1 to 64");
1788
+ var TimeOfDay = z10.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "HH:MM in 24 hours");
1789
+ var Weekday = z10.number().int().min(0).max(6);
1790
+ var TimezoneName = z10.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");
1586
1791
  var MAX_DELAY_SECONDS = 365 * 24 * 60 * 60;
1587
- var DateOnly = z9.string().regex(/^\d{4}-\d{2}-\d{2}$/, "a calendar date such as 2026-09-20").refine((v) => {
1792
+ var DateOnly = z10.string().regex(/^\d{4}-\d{2}-\d{2}$/, "a calendar date such as 2026-09-20").refine((v) => {
1588
1793
  const [y, m, d] = v.split("-").map(Number);
1589
1794
  const t = new Date(Date.UTC(y, m - 1, d));
1590
1795
  return t.getUTCFullYear() === y && t.getUTCMonth() + 1 === m && t.getUTCDate() === d;
1591
1796
  }, "a real calendar date");
1592
- var OffsetDays = z9.number().int().min(-365).max(365);
1797
+ var OffsetDays = z10.number().int().min(-365).max(365);
1593
1798
  var DATE_PASSED_ANSWERS = ["skip", "stop", "continue"];
1594
- var DatePassedAnswer = z9.enum(DATE_PASSED_ANSWERS);
1595
- var EventName = z9.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,79}$/, "letters, digits, dot, colon, underscore and hyphen, 1 to 80");
1799
+ var DatePassedAnswer = z10.enum(DATE_PASSED_ANSWERS);
1800
+ var EventName = z10.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,79}$/, "letters, digits, dot, colon, underscore and hyphen, 1 to 80");
1596
1801
  var AUTOMATION_TRIGGER_KINDS = [
1597
1802
  "topic_subscribed",
1598
1803
  "form_confirmed",
@@ -1605,17 +1810,17 @@ var AUTOMATION_TRIGGER_KINDS = [
1605
1810
  "segment_entered",
1606
1811
  "link_clicked"
1607
1812
  ];
1608
- var AutomationTriggerKind = z9.enum(AUTOMATION_TRIGGER_KINDS);
1813
+ var AutomationTriggerKind = z10.enum(AUTOMATION_TRIGGER_KINDS);
1609
1814
  var exclude = { exclude: BoundedAutomationFilter.nullish() };
1610
- var AutomationTrigger = z9.discriminatedUnion("kind", [
1611
- z9.object({ kind: z9.literal("topic_subscribed"), topic: Slug, ...exclude }).strict(),
1612
- z9.object({ kind: z9.literal("form_confirmed"), form_id: Id, ...exclude }).strict(),
1613
- z9.object({ kind: z9.literal("tag_added"), tag: Slug, ...exclude }).strict(),
1815
+ var AutomationTrigger = z10.discriminatedUnion("kind", [
1816
+ z10.object({ kind: z10.literal("topic_subscribed"), topic: Slug, ...exclude }).strict(),
1817
+ z10.object({ kind: z10.literal("form_confirmed"), form_id: Id, ...exclude }).strict(),
1818
+ z10.object({ kind: z10.literal("tag_added"), tag: Slug, ...exclude }).strict(),
1614
1819
  /** `to` given: only a change that lands on this value fires. Absent: any change of the key. */
1615
- z9.object({ kind: z9.literal("property_changed"), key: ContactPropertyKey, to: JsonValue.optional(), ...exclude }).strict(),
1820
+ z10.object({ kind: z10.literal("property_changed"), key: ContactPropertyKey, to: JsonValue.optional(), ...exclude }).strict(),
1616
1821
  /** `where` filters the event's own data, so only `event:<key>` leaves belong in it. */
1617
- z9.object({ kind: z9.literal("event"), name: EventName, where: BoundedAutomationFilter.nullish(), ...exclude }).strict(),
1618
- z9.object({ kind: z9.literal("manual"), ...exclude }).strict(),
1822
+ z10.object({ kind: z10.literal("event"), name: EventName, where: BoundedAutomationFilter.nullish(), ...exclude }).strict(),
1823
+ z10.object({ kind: z10.literal("manual"), ...exclude }).strict(),
1619
1824
  /**
1620
1825
  * Every year on a date the contact carries: a birthday, a joining date, a
1621
1826
  * renewal. `offset_days` moves it ("three days before"), `at` is the wall
@@ -1625,8 +1830,8 @@ var AutomationTrigger = z9.discriminatedUnion("kind", [
1625
1830
  * A 29 February date fires on 1 March in a year that has no 29 February, so
1626
1831
  * nobody is skipped every fourth year.
1627
1832
  */
1628
- z9.object({
1629
- kind: z9.literal("date_anniversary"),
1833
+ z10.object({
1834
+ kind: z10.literal("date_anniversary"),
1630
1835
  key: ContactPropertyKey,
1631
1836
  offset_days: OffsetDays,
1632
1837
  at: TimeOfDay,
@@ -1638,8 +1843,8 @@ var AutomationTrigger = z9.discriminatedUnion("kind", [
1638
1843
  * not ask about a segment or about an event's data: there is no event, and a
1639
1844
  * segment is its own trigger kind.
1640
1845
  */
1641
- z9.object({
1642
- kind: z9.literal("exact_date"),
1846
+ z10.object({
1847
+ kind: z10.literal("exact_date"),
1643
1848
  on: DateOnly,
1644
1849
  at: TimeOfDay,
1645
1850
  where: BoundedAutomationFilter.nullish(),
@@ -1658,7 +1863,7 @@ var AutomationTrigger = z9.discriminatedUnion("kind", [
1658
1863
  * already exists. Entering those people as well is the publish dialog's
1659
1864
  * backfill question, answered by a person rather than by the sweep.
1660
1865
  */
1661
- z9.object({ kind: z9.literal("segment_entered"), segment_id: Id, ...exclude }).strict(),
1866
+ z10.object({ kind: z10.literal("segment_entered"), segment_id: Id, ...exclude }).strict(),
1662
1867
  /**
1663
1868
  * S4. When somebody clicks a link in a mailing that has already gone out.
1664
1869
  *
@@ -1668,7 +1873,7 @@ var AutomationTrigger = z9.discriminatedUnion("kind", [
1668
1873
  * tracking off there is no click to hear about, so the validator refuses it
1669
1874
  * rather than leaving an automation that can never fire.
1670
1875
  */
1671
- z9.object({ kind: z9.literal("link_clicked"), mailing_id: Id, url: z9.string().min(1).max(2048).optional(), ...exclude }).strict()
1876
+ z10.object({ kind: z10.literal("link_clicked"), mailing_id: Id, url: z10.string().min(1).max(2048).optional(), ...exclude }).strict()
1672
1877
  ]);
1673
1878
  var AUTOMATION_DATE_TRIGGER_KINDS = ["date_anniversary", "exact_date"];
1674
1879
  var MAX_TRIGGERS = 10;
@@ -1687,45 +1892,45 @@ var AUTOMATION_STEP_KINDS = [
1687
1892
  "webhook",
1688
1893
  "notify"
1689
1894
  ];
1690
- var AutomationStepKind = z9.enum(AUTOMATION_STEP_KINDS);
1895
+ var AutomationStepKind = z10.enum(AUTOMATION_STEP_KINDS);
1691
1896
  var next = { next: StepId.nullable() };
1692
- var Unchosen = z9.literal("");
1693
- var DraftSlug = z9.union([Slug, Unchosen]);
1694
- var DraftPropertyKey = z9.union([ContactPropertyKey, Unchosen]);
1695
- var label2 = { label: z9.string().max(120).nullish() };
1696
- var EmailStepLanguage = z9.object({
1697
- subject: z9.string().min(1).max(998),
1698
- preheader: z9.string().max(500).nullable(),
1897
+ var Unchosen = z10.literal("");
1898
+ var DraftSlug = z10.union([Slug, Unchosen]);
1899
+ var DraftPropertyKey = z10.union([ContactPropertyKey, Unchosen]);
1900
+ var label2 = { label: z10.string().max(120).nullish() };
1901
+ var EmailStepLanguage = z10.object({
1902
+ subject: z10.string().min(1).max(998),
1903
+ preheader: z10.string().max(500).nullable(),
1699
1904
  document: TemplateDocument,
1700
1905
  /** This language's insertions, its texts over the template's structure (every text present). */
1701
1906
  insertions: Insertions.nullish()
1702
1907
  }).strict();
1703
- var EmailStep = z9.object({
1704
- kind: z9.literal("email"),
1908
+ var EmailStep = z10.object({
1909
+ kind: z10.literal("email"),
1705
1910
  ...label2,
1706
1911
  ...next,
1707
1912
  template_id: Id.nullish(),
1708
1913
  document: TemplateDocument.nullish(),
1709
1914
  /** Empty while the step is being written, or when its template has a subject; else `not_chosen` refuses to publish it. */
1710
- subject: z9.string().max(998),
1711
- preheader: z9.string().max(500).nullish(),
1915
+ subject: z10.string().max(998),
1916
+ preheader: z10.string().max(500).nullish(),
1712
1917
  locale: LocaleTag.nullish(),
1713
- languages: z9.record(LocaleTag, EmailStepLanguage).nullish(),
1918
+ languages: z10.record(LocaleTag, EmailStepLanguage).nullish(),
1714
1919
  /** The main language's insertions, snapshot from the template when the automation is published. */
1715
1920
  insertions: Insertions.nullish()
1716
1921
  }).strict();
1717
- var DelayStep = z9.object({
1718
- kind: z9.literal("delay"),
1922
+ var DelayStep = z10.object({
1923
+ kind: z10.literal("delay"),
1719
1924
  ...label2,
1720
1925
  ...next,
1721
- wait: z9.discriminatedUnion("mode", [
1722
- z9.object({ mode: z9.literal("duration"), seconds: z9.number().int().min(1).max(MAX_DELAY_SECONDS) }).strict(),
1723
- z9.object({ mode: z9.literal("time_of_day"), at: TimeOfDay }).strict(),
1724
- z9.object({ mode: z9.literal("weekday"), weekday: Weekday, at: TimeOfDay }).strict(),
1926
+ wait: z10.discriminatedUnion("mode", [
1927
+ z10.object({ mode: z10.literal("duration"), seconds: z10.number().int().min(1).max(MAX_DELAY_SECONDS) }).strict(),
1928
+ z10.object({ mode: z10.literal("time_of_day"), at: TimeOfDay }).strict(),
1929
+ z10.object({ mode: z10.literal("weekday"), weekday: Weekday, at: TimeOfDay }).strict(),
1725
1930
  /** A fixed day has no next occurrence, so `continue` is not one of its answers. */
1726
- z9.object({ mode: z9.literal("date"), on: DateOnly, at: TimeOfDay, passed: z9.enum(["skip", "stop"]) }).strict(),
1727
- z9.object({
1728
- mode: z9.literal("date_property"),
1931
+ z10.object({ mode: z10.literal("date"), on: DateOnly, at: TimeOfDay, passed: z10.enum(["skip", "stop"]) }).strict(),
1932
+ z10.object({
1933
+ mode: z10.literal("date_property"),
1729
1934
  key: ContactPropertyKey,
1730
1935
  offset_days: OffsetDays,
1731
1936
  at: TimeOfDay,
@@ -1733,8 +1938,8 @@ var DelayStep = z9.object({
1733
1938
  }).strict()
1734
1939
  ])
1735
1940
  }).strict();
1736
- var ConditionStep = z9.object({
1737
- kind: z9.literal("condition"),
1941
+ var ConditionStep = z10.object({
1942
+ kind: z10.literal("condition"),
1738
1943
  ...label2,
1739
1944
  filter: BoundedAutomationFilter,
1740
1945
  yes: StepId.nullable(),
@@ -1745,49 +1950,49 @@ var ConditionStep = z9.object({
1745
1950
  * neither half means anything without the other: a window with no answer
1746
1951
  * for the end of it would be a silent decision.
1747
1952
  */
1748
- wait_for: z9.object({ up_to_s: z9.number().int().min(1).max(MAX_DELAY_SECONDS), on_timeout: z9.enum(["yes", "no"]) }).strict().nullish()
1953
+ wait_for: z10.object({ up_to_s: z10.number().int().min(1).max(MAX_DELAY_SECONDS), on_timeout: z10.enum(["yes", "no"]) }).strict().nullish()
1749
1954
  }).strict();
1750
- var SplitBranchKey = z9.string().regex(/^[A-Za-z0-9_-]{1,32}$/, "letters, digits, underscore and hyphen, 1 to 32");
1955
+ var SplitBranchKey = z10.string().regex(/^[A-Za-z0-9_-]{1,32}$/, "letters, digits, underscore and hyphen, 1 to 32");
1751
1956
  var MIN_SPLIT_BRANCHES = 2;
1752
1957
  var MAX_SPLIT_BRANCHES = 4;
1753
- var SplitStep = z9.object({
1754
- kind: z9.literal("split"),
1958
+ var SplitStep = z10.object({
1959
+ kind: z10.literal("split"),
1755
1960
  ...label2,
1756
- branches: z9.array(
1757
- z9.object({
1961
+ branches: z10.array(
1962
+ z10.object({
1758
1963
  key: SplitBranchKey,
1759
1964
  /** A whole percentage. Zero is allowed: a branch kept in the flow but switched off. */
1760
- weight: z9.number().int().min(0).max(100),
1965
+ weight: z10.number().int().min(0).max(100),
1761
1966
  next: StepId.nullable()
1762
1967
  }).strict()
1763
1968
  ).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")
1764
1969
  }).strict();
1765
- var GotoStep = z9.object({ kind: z9.literal("goto"), ...label2, target: StepId.nullable() }).strict();
1970
+ var GotoStep = z10.object({ kind: z10.literal("goto"), ...label2, target: StepId.nullable() }).strict();
1766
1971
  var MAX_STEP_VISITS = 20;
1767
- var WebhookStep = z9.object({ kind: z9.literal("webhook"), ...label2, ...next, endpoint_id: Id.nullable(), payload: JsonValue.nullish() }).strict();
1768
- var NotifyRecipients = z9.union([z9.literal("owner"), z9.literal("admins"), z9.object({ member_id: Id }).strict()]);
1769
- var NotifyStep = z9.object({
1770
- kind: z9.literal("notify"),
1972
+ var WebhookStep = z10.object({ kind: z10.literal("webhook"), ...label2, ...next, endpoint_id: Id.nullable(), payload: JsonValue.nullish() }).strict();
1973
+ var NotifyRecipients = z10.union([z10.literal("owner"), z10.literal("admins"), z10.object({ member_id: Id }).strict()]);
1974
+ var NotifyStep = z10.object({
1975
+ kind: z10.literal("notify"),
1771
1976
  ...label2,
1772
1977
  ...next,
1773
1978
  to: NotifyRecipients,
1774
1979
  /** Empty while the step is being written; `not_chosen` refuses to publish it. */
1775
- subject: z9.string().max(998),
1776
- body: z9.string().max(1e4)
1980
+ subject: z10.string().max(998),
1981
+ body: z10.string().max(1e4)
1777
1982
  }).strict();
1778
- var AutomationStep = z9.discriminatedUnion("kind", [
1983
+ var AutomationStep = z10.discriminatedUnion("kind", [
1779
1984
  EmailStep,
1780
1985
  DelayStep,
1781
1986
  ConditionStep,
1782
- z9.object({ kind: z9.literal("add_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
1783
- z9.object({ kind: z9.literal("remove_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
1987
+ z10.object({ kind: z10.literal("add_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
1988
+ z10.object({ kind: z10.literal("remove_tag"), ...label2, ...next, tag: DraftSlug }).strict(),
1784
1989
  /** `value` null clears the property, as a contact upsert does. */
1785
- z9.object({ kind: z9.literal("set_property"), ...label2, ...next, key: DraftPropertyKey, value: JsonValue }).strict(),
1990
+ z10.object({ kind: z10.literal("set_property"), ...label2, ...next, key: DraftPropertyKey, value: JsonValue }).strict(),
1786
1991
  /** Subscribing never lifts a suppression: the service checks that, not the flow. */
1787
- z9.object({ kind: z9.literal("subscribe_topic"), ...label2, ...next, topic: DraftSlug }).strict(),
1992
+ z10.object({ kind: z10.literal("subscribe_topic"), ...label2, ...next, topic: DraftSlug }).strict(),
1788
1993
  /** `topic` unsubscribes from the automation's own topic, `all` from every topic. */
1789
- z9.object({ kind: z9.literal("unsubscribe"), ...label2, ...next, scope: z9.enum(["topic", "all"]) }).strict(),
1790
- z9.object({ kind: z9.literal("exit"), ...label2 }).strict(),
1994
+ z10.object({ kind: z10.literal("unsubscribe"), ...label2, ...next, scope: z10.enum(["topic", "all"]) }).strict(),
1995
+ z10.object({ kind: z10.literal("exit"), ...label2 }).strict(),
1791
1996
  SplitStep,
1792
1997
  GotoStep,
1793
1998
  WebhookStep,
@@ -1811,25 +2016,25 @@ function stepTargets(step) {
1811
2016
  }
1812
2017
  }
1813
2018
  var MAX_STEPS = 200;
1814
- var AutomationFlow = z9.object({
1815
- triggers: z9.array(AutomationTrigger).max(MAX_TRIGGERS),
2019
+ var AutomationFlow = z10.object({
2020
+ triggers: z10.array(AutomationTrigger).max(MAX_TRIGGERS),
1816
2021
  /** The first step. `null` is an empty flow. */
1817
2022
  entry: StepId.nullable(),
1818
- steps: z9.record(StepId, AutomationStep)
2023
+ steps: z10.record(StepId, AutomationStep)
1819
2024
  }).strict();
1820
2025
  var emptyFlow = () => ({ triggers: [], entry: null, steps: {} });
1821
- var QuietHours = z9.object({
2026
+ var QuietHours = z10.object({
1822
2027
  start: TimeOfDay,
1823
2028
  end: TimeOfDay,
1824
- weekdays: z9.array(Weekday).min(1).max(7).nullish()
2029
+ weekdays: z10.array(Weekday).min(1).max(7).nullish()
1825
2030
  }).strict();
1826
2031
  var RE_ENTRY_MODES = ["off", "after_exit"];
1827
- var ReEntryMode = z9.enum(RE_ENTRY_MODES);
2032
+ var ReEntryMode = z10.enum(RE_ENTRY_MODES);
1828
2033
  var MAX_RE_ENTRY_COOLDOWN_SECONDS = 365 * 24 * 60 * 60;
1829
- var AutomationSettings = z9.object({
2034
+ var AutomationSettings = z10.object({
1830
2035
  re_entry: ReEntryMode,
1831
2036
  /** Seconds a person must wait after leaving before entering again. Only with `after_exit`. */
1832
- re_entry_cooldown_s: z9.number().int().min(0).max(MAX_RE_ENTRY_COOLDOWN_SECONDS).nullish(),
2037
+ re_entry_cooldown_s: z10.number().int().min(0).max(MAX_RE_ENTRY_COOLDOWN_SECONDS).nullish(),
1833
2038
  quiet_hours: QuietHours.nullish(),
1834
2039
  /** Checked before every step; when it matches, the run ends. */
1835
2040
  exit_filter: BoundedAutomationFilter.nullish()
@@ -1887,18 +2092,18 @@ var AUTOMATION_ISSUE_CODES = [
1887
2092
  /** A one-off date that is already over everywhere on earth, so it would fire for nobody. */
1888
2093
  "date_in_the_past"
1889
2094
  ];
1890
- var AutomationIssueCode = z9.enum(AUTOMATION_ISSUE_CODES);
1891
- var AutomationIssue = z9.object({
2095
+ var AutomationIssueCode = z10.enum(AUTOMATION_ISSUE_CODES);
2096
+ var AutomationIssue = z10.object({
1892
2097
  code: AutomationIssueCode,
1893
2098
  /** The step the issue is about, when it is about one. */
1894
2099
  step_id: StepId.nullable(),
1895
2100
  /** Where inside the document, for the canvas to point at a field. */
1896
- path: z9.array(z9.union([z9.string(), z9.number()])),
1897
- message: z9.string()
2101
+ path: z10.array(z10.union([z10.string(), z10.number()])),
2102
+ message: z10.string()
1898
2103
  });
1899
- var AutomationValidation = z9.object({
1900
- ok: z9.boolean(),
1901
- issues: z9.array(AutomationIssue)
2104
+ var AutomationValidation = z10.object({
2105
+ ok: z10.boolean(),
2106
+ issues: z10.array(AutomationIssue)
1902
2107
  });
1903
2108
  function validateAutomation(flow, settings, ctx) {
1904
2109
  const issues = [];
@@ -2289,7 +2494,7 @@ function cycles(flow) {
2289
2494
  return out.sort();
2290
2495
  }
2291
2496
  var AUTOMATION_STATUSES = ["draft", "active", "paused", "archived"];
2292
- var AutomationStatus = z9.enum(AUTOMATION_STATUSES);
2497
+ var AutomationStatus = z10.enum(AUTOMATION_STATUSES);
2293
2498
  var AUTOMATION_END_REASONS = [
2294
2499
  "completed",
2295
2500
  "exit_filter",
@@ -2308,9 +2513,9 @@ var AUTOMATION_END_REASONS = [
2308
2513
  "ended_by_hand",
2309
2514
  "failed"
2310
2515
  ];
2311
- var AutomationEndReason = z9.enum(AUTOMATION_END_REASONS);
2516
+ var AutomationEndReason = z10.enum(AUTOMATION_END_REASONS);
2312
2517
  var AUTOMATION_WAIT_REASONS = ["delay", "quiet_hours", "plan_limit", "sending", "condition"];
2313
- var AutomationWaitReason = z9.enum(AUTOMATION_WAIT_REASONS);
2518
+ var AutomationWaitReason = z10.enum(AUTOMATION_WAIT_REASONS);
2314
2519
  var AUTOMATION_ENTRY_REFUSALS = [
2315
2520
  "already_inside",
2316
2521
  "re_entry_off",
@@ -2321,26 +2526,26 @@ var AUTOMATION_ENTRY_REFUSALS = [
2321
2526
  "not_active",
2322
2527
  "unknown_contact"
2323
2528
  ];
2324
- var AutomationEntryRefusal = z9.enum(AUTOMATION_ENTRY_REFUSALS);
2325
- var AutomationCounts = z9.object({
2326
- started: z9.number().int().min(0),
2327
- in_progress: z9.number().int().min(0),
2328
- completed: z9.number().int().min(0),
2329
- exited: z9.number().int().min(0),
2330
- failed: z9.number().int().min(0)
2331
- });
2332
- var Automation = z9.object({
2529
+ var AutomationEntryRefusal = z10.enum(AUTOMATION_ENTRY_REFUSALS);
2530
+ var AutomationCounts = z10.object({
2531
+ started: z10.number().int().min(0),
2532
+ in_progress: z10.number().int().min(0),
2533
+ completed: z10.number().int().min(0),
2534
+ exited: z10.number().int().min(0),
2535
+ failed: z10.number().int().min(0)
2536
+ });
2537
+ var Automation = z10.object({
2333
2538
  id: Id,
2334
- name: z9.string().min(1).max(200),
2539
+ name: z10.string().min(1).max(200),
2335
2540
  status: AutomationStatus,
2336
2541
  /** Every automation sends under one topic; there are no transactional automations. */
2337
2542
  topic: Slug,
2338
2543
  provider_id: Id.nullable(),
2339
2544
  settings: AutomationSettings,
2340
2545
  /** The flow people are running through, null while the automation has never been published. */
2341
- published_version: z9.number().int().min(1).nullable(),
2546
+ published_version: z10.number().int().min(1).nullable(),
2342
2547
  /** The flow being edited. Increments on every save, like a template's version. */
2343
- draft_version: z9.number().int().min(1),
2548
+ draft_version: z10.number().int().min(1),
2344
2549
  counts: AutomationCounts,
2345
2550
  created_at: Timestamp,
2346
2551
  updated_at: Timestamp,
@@ -2353,16 +2558,16 @@ var AutomationWithFlow = Automation.extend({
2353
2558
  published_flow: AutomationFlow.nullable()
2354
2559
  });
2355
2560
  var AutomationSummary = Automation;
2356
- var AutomationCreate = z9.object({
2357
- name: z9.string().min(1).max(200),
2561
+ var AutomationCreate = z10.object({
2562
+ name: z10.string().min(1).max(200),
2358
2563
  topic: Slug,
2359
2564
  provider_id: Id.optional(),
2360
2565
  flow: AutomationFlow.optional(),
2361
2566
  settings: AutomationSettings.partial().optional()
2362
2567
  });
2363
- var AutomationUpdate = z9.object({
2364
- base_version: z9.number().int().min(1),
2365
- name: z9.string().min(1).max(200).optional(),
2568
+ var AutomationUpdate = z10.object({
2569
+ base_version: z10.number().int().min(1),
2570
+ name: z10.string().min(1).max(200).optional(),
2366
2571
  topic: Slug.optional(),
2367
2572
  provider_id: Id.optional(),
2368
2573
  flow: AutomationFlow.optional(),
@@ -2375,42 +2580,42 @@ var AutomationListQuery = PageQuery.extend({
2375
2580
  status: AutomationStatus.optional(),
2376
2581
  topic: Slug.optional()
2377
2582
  });
2378
- var AutomationPublishRequest = z9.object({
2583
+ var AutomationPublishRequest = z10.object({
2379
2584
  /**
2380
2585
  * Answer what this publish would do and change nothing, whatever the flow
2381
2586
  * looks like. Without it a publish that has no issues and moves nobody
2382
2587
  * simply goes ahead, which is right for an API caller and wrong for a
2383
2588
  * dialog that is only showing somebody what they are about to do.
2384
2589
  */
2385
- dry_run: z9.boolean().optional(),
2386
- confirm: z9.boolean().optional(),
2590
+ dry_run: z10.boolean().optional(),
2591
+ confirm: z10.boolean().optional(),
2387
2592
  /** Per removed step: the step its waiting runs move to, or null to end them. */
2388
- moves: z9.record(StepId, StepId.nullable()).optional(),
2593
+ moves: z10.record(StepId, StepId.nullable()).optional(),
2389
2594
  /** Also enter everyone who matches a trigger's condition right now. */
2390
- backfill: z9.boolean().optional()
2595
+ backfill: z10.boolean().optional()
2391
2596
  }).strict();
2392
- var AutomationPublishMove = z9.object({
2597
+ var AutomationPublishMove = z10.object({
2393
2598
  step_id: StepId,
2394
2599
  /** Why the step's people have to move: it is gone, or its delay changed. */
2395
- change: z9.enum(["removed", "delay_changed", "kind_changed"]),
2396
- waiting: z9.number().int().min(0),
2600
+ change: z10.enum(["removed", "delay_changed", "kind_changed"]),
2601
+ waiting: z10.number().int().min(0),
2397
2602
  /** Where they go: a step id, or null to end their runs with `step_removed`. */
2398
2603
  destination: StepId.nullable()
2399
2604
  });
2400
- var AutomationPublishResult = z9.object({
2401
- published: z9.boolean(),
2605
+ var AutomationPublishResult = z10.object({
2606
+ published: z10.boolean(),
2402
2607
  automation: Automation,
2403
2608
  /** Empty when nothing has to move; non-empty and `published` false asks for a confirmation. */
2404
- moves: z9.array(AutomationPublishMove),
2609
+ moves: z10.array(AutomationPublishMove),
2405
2610
  /** How many people the backfill entered, or would enter when it is not confirmed. */
2406
- backfill: z9.number().int().min(0),
2407
- issues: z9.array(AutomationIssue)
2408
- });
2409
- var AutomationDuplicateRequest = z9.object({ name: z9.string().min(1).max(200).optional() }).strict();
2410
- var AutomationEnrollRequest = z9.object({
2411
- contact_ids: z9.array(Id).min(1).max(1e3).optional(),
2412
- external_ids: z9.array(z9.string().min(1).max(255)).min(1).max(1e3).optional(),
2413
- emails: z9.array(Email).min(1).max(1e3).optional(),
2611
+ backfill: z10.number().int().min(0),
2612
+ issues: z10.array(AutomationIssue)
2613
+ });
2614
+ var AutomationDuplicateRequest = z10.object({ name: z10.string().min(1).max(200).optional() }).strict();
2615
+ var AutomationEnrollRequest = z10.object({
2616
+ contact_ids: z10.array(Id).min(1).max(1e3).optional(),
2617
+ external_ids: z10.array(z10.string().min(1).max(255)).min(1).max(1e3).optional(),
2618
+ emails: z10.array(Email).min(1).max(1e3).optional(),
2414
2619
  segment_id: Id.optional(),
2415
2620
  /** Where to start them; the flow's entry step by default. */
2416
2621
  step_id: StepId.optional()
@@ -2418,34 +2623,34 @@ var AutomationEnrollRequest = z9.object({
2418
2623
  (v) => [v.contact_ids, v.external_ids, v.emails, v.segment_id].filter((x) => x !== void 0).length === 1,
2419
2624
  "name the people exactly one way: contact_ids, external_ids, emails or segment_id"
2420
2625
  );
2421
- var AutomationEnrollment = z9.object({
2626
+ var AutomationEnrollment = z10.object({
2422
2627
  contact_id: Id.nullable(),
2423
2628
  email: Email.nullable(),
2424
- external_id: z9.string().nullable(),
2425
- entered: z9.boolean(),
2629
+ external_id: z10.string().nullable(),
2630
+ entered: z10.boolean(),
2426
2631
  run_id: Id.nullable(),
2427
2632
  reason: AutomationEntryRefusal.nullable()
2428
2633
  });
2429
- var AutomationEnrollResult = z9.object({
2430
- entered: z9.number().int().min(0),
2431
- refused: z9.number().int().min(0),
2432
- results: z9.array(AutomationEnrollment)
2634
+ var AutomationEnrollResult = z10.object({
2635
+ entered: z10.number().int().min(0),
2636
+ refused: z10.number().int().min(0),
2637
+ results: z10.array(AutomationEnrollment)
2433
2638
  });
2434
- var AutomationRunStatus = z9.enum(["active", "waiting", "completed", "exited", "failed"]);
2435
- var AutomationRun = z9.object({
2639
+ var AutomationRunStatus = z10.enum(["active", "waiting", "completed", "exited", "failed"]);
2640
+ var AutomationRun = z10.object({
2436
2641
  id: Id,
2437
2642
  automation_id: Id,
2438
2643
  contact_id: Id,
2439
2644
  email: Email,
2440
- external_id: z9.string().nullable(),
2441
- version: z9.number().int().min(1),
2645
+ external_id: z10.string().nullable(),
2646
+ version: z10.number().int().min(1),
2442
2647
  status: AutomationRunStatus,
2443
2648
  current_step_id: StepId.nullable(),
2444
2649
  next_action_at: Timestamp.nullable(),
2445
2650
  wait_reason: AutomationWaitReason.nullable(),
2446
- end_reason: z9.string().nullable(),
2651
+ end_reason: z10.string().nullable(),
2447
2652
  /** What went wrong the last time this run tried to take its step, null otherwise. */
2448
- last_error: z9.string().nullable(),
2653
+ last_error: z10.string().nullable(),
2449
2654
  entered_at: Timestamp,
2450
2655
  ended_at: Timestamp.nullable()
2451
2656
  });
@@ -2455,13 +2660,13 @@ var AutomationRunListQuery = PageQuery.extend({
2455
2660
  contact_id: Id.optional()
2456
2661
  });
2457
2662
  var ContactAutomationRun = AutomationRun.extend({
2458
- automation: z9.object({ id: Id, name: z9.string(), status: AutomationStatus })
2663
+ automation: z10.object({ id: Id, name: z10.string(), status: AutomationStatus })
2459
2664
  });
2460
2665
  var ContactAutomationListQuery = PageQuery.extend({ status: AutomationRunStatus.optional() });
2461
- var AutomationStepExecution = z9.object({
2666
+ var AutomationStepExecution = z10.object({
2462
2667
  step_id: StepId,
2463
2668
  step_kind: AutomationStepKind,
2464
- visit: z9.number().int().min(1),
2669
+ visit: z10.number().int().min(1),
2465
2670
  started_at: Timestamp,
2466
2671
  finished_at: Timestamp.nullable(),
2467
2672
  /**
@@ -2473,48 +2678,48 @@ var AutomationStepExecution = z9.object({
2473
2678
  */
2474
2679
  outcome: Properties
2475
2680
  });
2476
- var AutomationJourney = z9.object({
2681
+ var AutomationJourney = z10.object({
2477
2682
  run: AutomationRun,
2478
- steps: z9.array(AutomationStepExecution)
2683
+ steps: z10.array(AutomationStepExecution)
2479
2684
  });
2480
- var AutomationStepReport = z9.object({
2685
+ var AutomationStepReport = z10.object({
2481
2686
  step_id: StepId,
2482
2687
  step_kind: AutomationStepKind,
2483
- reached: z9.number().int().min(0),
2484
- waiting: z9.number().int().min(0),
2485
- passed: z9.number().int().min(0),
2688
+ reached: z10.number().int().min(0),
2689
+ waiting: z10.number().int().min(0),
2690
+ passed: z10.number().int().min(0),
2486
2691
  /** Per branch, for a condition: how many took `yes` and how many `no`. */
2487
- branches: z9.record(z9.number().int().min(0)),
2692
+ branches: z10.record(z10.number().int().min(0)),
2488
2693
  /** The step mailing's id, for an email step of the published version. */
2489
2694
  mailing_id: Id.nullable()
2490
2695
  });
2491
- var AutomationReport = z9.object({
2696
+ var AutomationReport = z10.object({
2492
2697
  counts: AutomationCounts,
2493
2698
  /** Why the people who left did: `AutomationEndReason` to a count. */
2494
- end_reasons: z9.record(z9.number().int().min(0)),
2699
+ end_reasons: z10.record(z10.number().int().min(0)),
2495
2700
  /**
2496
2701
  * Why people a trigger named did not enter: `AutomationEntryRefusal` to a
2497
2702
  * count. Without it a pause, an exclusion or a missing subscription would
2498
2703
  * turn people away invisibly.
2499
2704
  */
2500
- refusals: z9.record(z9.number().int().min(0)),
2501
- steps: z9.array(AutomationStepReport)
2502
- });
2503
- var AutomationExitRunRequest = z9.object({ reason: z9.string().max(200).optional() }).strict();
2504
- var AutomationRunParams = z9.object({ id: Id, run_id: Id });
2505
- var AutomationStepParams = z9.object({ id: Id, step_id: StepId });
2506
- var AutomationTestEmailRequest = z9.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
2507
- var AutomationValidateRequest = z9.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
2508
- var EventCreate = z9.object({
2705
+ refusals: z10.record(z10.number().int().min(0)),
2706
+ steps: z10.array(AutomationStepReport)
2707
+ });
2708
+ var AutomationExitRunRequest = z10.object({ reason: z10.string().max(200).optional() }).strict();
2709
+ var AutomationRunParams = z10.object({ id: Id, run_id: Id });
2710
+ var AutomationStepParams = z10.object({ id: Id, step_id: StepId });
2711
+ var AutomationTestEmailRequest = z10.object({ to: Email, merge: Properties.optional(), locale: LocaleTag.optional() }).strict();
2712
+ var AutomationValidateRequest = z10.object({ flow: AutomationFlow.optional(), settings: AutomationSettings.partial().optional() }).strict();
2713
+ var EventCreate = z10.object({
2509
2714
  name: EventName,
2510
- contact: z9.object({ external_id: z9.string().min(1).max(255).optional(), email: Email.optional(), id: Id.optional() }).refine((c) => [c.external_id, c.email, c.id].filter((x) => x !== void 0).length === 1, "name the contact exactly one way"),
2715
+ contact: z10.object({ external_id: z10.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"),
2511
2716
  data: Properties.optional(),
2512
2717
  occurred_at: Timestamp.optional(),
2513
- id: z9.string().min(1).max(128).optional()
2718
+ id: z10.string().min(1).max(128).optional()
2514
2719
  }).strict();
2515
- var Event = z9.object({
2720
+ var Event = z10.object({
2516
2721
  id: Id,
2517
- client_event_id: z9.string().nullable(),
2722
+ client_event_id: z10.string().nullable(),
2518
2723
  name: EventName,
2519
2724
  contact_id: Id,
2520
2725
  data: Properties,
@@ -2525,7 +2730,7 @@ var Event = z9.object({
2525
2730
  * hand. Each is then admitted or refused by the runtime on its own rules
2526
2731
  * (consent, exclusions, re-entry), which `automations.report` counts.
2527
2732
  */
2528
- entered: z9.number().int().min(0)
2733
+ entered: z10.number().int().min(0)
2529
2734
  });
2530
2735
  var EventListQuery = PageQuery.extend({
2531
2736
  name: EventName.optional(),
@@ -2533,19 +2738,15 @@ var EventListQuery = PageQuery.extend({
2533
2738
  });
2534
2739
 
2535
2740
  // src/workspace.ts
2536
- var CompanyId = z10.string().min(1).max(64);
2741
+ var CompanyId = z11.string().min(1).max(64);
2537
2742
  var ASSET_POLICIES = ["any", "service_only"];
2538
- var AssetPolicy = z10.enum(ASSET_POLICIES);
2743
+ var AssetPolicy = z11.enum(ASSET_POLICIES);
2539
2744
  var MAX_ALLOWED_ASSET_HOSTS = 20;
2540
- var AssetHost = z10.string().trim().toLowerCase().min(1).max(253).regex(/^(?=.{1,253}(?::\d{1,5})?$)[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+(:\d{1,5})?$/, "a host name such as example.com");
2541
- var MAX_MERGE_DEFAULTS = 50;
2542
- var MAX_MERGE_DEFAULT_LENGTH = 2e3;
2543
- var MergeFieldName = z10.string().regex(/^[a-z][a-z0-9_]*$/, "a merge-field name: lowercase letters, digits and underscores, starting with a letter").max(64);
2544
- var MergeDefaultValue = z10.union([z10.string().max(MAX_MERGE_DEFAULT_LENGTH), z10.number().finite(), z10.boolean()]);
2545
- var MergeDefaults = z10.record(MergeFieldName, MergeDefaultValue).refine((m) => Object.keys(m).length <= MAX_MERGE_DEFAULTS, `at most ${MAX_MERGE_DEFAULTS} merge defaults`).refine((m) => !Object.keys(m).some((k) => k in RESERVED_MERGE_FIELDS), {
2745
+ var AssetHost = z11.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");
2746
+ var MergeDefaults = z11.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), {
2546
2747
  message: `a reserved merge field (${Object.keys(RESERVED_MERGE_FIELDS).join(", ")}) cannot have a workspace default`
2547
2748
  });
2548
- var WorkspaceSettings = z10.object({
2749
+ var WorkspaceSettings = z11.object({
2549
2750
  /**
2550
2751
  * The workspace's main language (a {@link LocaleTag}, e.g. "de"): the main
2551
2752
  * language of a new template, and of the hosted pages when nothing else
@@ -2558,9 +2759,9 @@ var WorkspaceSettings = z10.object({
2558
2759
  * each; the hosted pages are offered in those of them they support (English,
2559
2760
  * German, French, Italian, Spanish). The service stores canonical casing.
2560
2761
  */
2561
- locales: z10.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
2762
+ locales: z11.array(LocaleTag).min(1).max(20).refine((l) => new Set(l.map((t) => t.toLowerCase())).size === l.length, "a language appears twice"),
2562
2763
  /** Open and click tracking. Off by default, opt-in per workspace. */
2563
- tracking_enabled: z10.boolean(),
2764
+ tracking_enabled: z11.boolean(),
2564
2765
  /** Where images, stylesheets and fonts in a mail may load from. `any` by default. */
2565
2766
  asset_policy: AssetPolicy,
2566
2767
  /**
@@ -2568,7 +2769,7 @@ var WorkspaceSettings = z10.object({
2568
2769
  * the workspace's website, typically. Empty by default. Ignored under `any`,
2569
2770
  * which allows everything already.
2570
2771
  */
2571
- allowed_asset_hosts: z10.array(AssetHost).max(MAX_ALLOWED_ASSET_HOSTS),
2772
+ allowed_asset_hosts: z11.array(AssetHost).max(MAX_ALLOWED_ASSET_HOSTS),
2572
2773
  /** Merge values every mail of the workspace can use (see `MergeDefaults`). Empty by default. */
2573
2774
  merge_defaults: MergeDefaults,
2574
2775
  /**
@@ -2577,10 +2778,10 @@ var WorkspaceSettings = z10.object({
2577
2778
  */
2578
2779
  default_timezone: TimezoneName.nullable()
2579
2780
  });
2580
- var Workspace = z10.object({
2781
+ var Workspace = z11.object({
2581
2782
  id: Id,
2582
2783
  slug: Slug,
2583
- name: z10.string().min(1).max(120),
2784
+ name: z11.string().min(1).max(120),
2584
2785
  settings: WorkspaceSettings,
2585
2786
  /**
2586
2787
  * The auth-brain company (tenant) the workspace was created for, or null for
@@ -2591,13 +2792,13 @@ var Workspace = z10.object({
2591
2792
  created_at: Timestamp,
2592
2793
  updated_at: Timestamp
2593
2794
  });
2594
- var WorkspaceCreate = z10.object({
2795
+ var WorkspaceCreate = z11.object({
2595
2796
  slug: Slug,
2596
- name: z10.string().min(1).max(120),
2797
+ name: z11.string().min(1).max(120),
2597
2798
  settings: WorkspaceSettings.partial().optional(),
2598
- owner: z10.object({
2799
+ owner: z11.object({
2599
2800
  email: Email,
2600
- name: z10.string().max(200).nullable().optional()
2801
+ name: z11.string().max(200).nullable().optional()
2601
2802
  }),
2602
2803
  /**
2603
2804
  * The signed-in person's active auth-brain company. The dashboard always
@@ -2607,49 +2808,49 @@ var WorkspaceCreate = z10.object({
2607
2808
  */
2608
2809
  company_id: CompanyId.optional()
2609
2810
  });
2610
- var WorkspaceUpdate = z10.object({
2611
- name: z10.string().min(1).max(120),
2811
+ var WorkspaceUpdate = z11.object({
2812
+ name: z11.string().min(1).max(120),
2612
2813
  settings: WorkspaceSettings.partial()
2613
2814
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
2614
- var WorkspaceMove = z10.object({ company_id: CompanyId });
2815
+ var WorkspaceMove = z11.object({ company_id: CompanyId });
2615
2816
  var MEMBER_ROLES = ["owner", "admin", "editor", "viewer"];
2616
- var MemberRole = z10.enum(MEMBER_ROLES);
2817
+ var MemberRole = z11.enum(MEMBER_ROLES);
2617
2818
  var WorkspaceMembership = Workspace.extend({ role: MemberRole });
2618
- var Member = z10.object({
2819
+ var Member = z11.object({
2619
2820
  id: Id,
2620
2821
  /** The person's auth-brain subject. */
2621
- subject: z10.string().min(1).max(255),
2822
+ subject: z11.string().min(1).max(255),
2622
2823
  email: Email,
2623
- name: z10.string().max(200).nullable(),
2824
+ name: z11.string().max(200).nullable(),
2624
2825
  role: MemberRole,
2625
2826
  created_at: Timestamp
2626
2827
  });
2627
- var MemberCreate = z10.object({
2628
- subject: z10.string().min(1).max(255),
2828
+ var MemberCreate = z11.object({
2829
+ subject: z11.string().min(1).max(255),
2629
2830
  email: Email,
2630
- name: z10.string().max(200).nullable().optional(),
2831
+ name: z11.string().max(200).nullable().optional(),
2631
2832
  role: MemberRole
2632
2833
  });
2633
- var MemberUpdate = z10.object({ role: MemberRole });
2834
+ var MemberUpdate = z11.object({ role: MemberRole });
2634
2835
  var API_KEY_SCOPES = ["full", "read", "send"];
2635
- var ApiKeyScope = z10.enum(API_KEY_SCOPES);
2636
- var ApiKey = z10.object({
2836
+ var ApiKeyScope = z11.enum(API_KEY_SCOPES);
2837
+ var ApiKey = z11.object({
2637
2838
  id: Id,
2638
- name: z10.string().min(1).max(120),
2839
+ name: z11.string().min(1).max(120),
2639
2840
  /** The first characters of the key, for recognising it in a list. */
2640
- prefix: z10.string().min(4).max(32),
2841
+ prefix: z11.string().min(4).max(32),
2641
2842
  scope: ApiKeyScope,
2642
2843
  last_used_at: Timestamp.nullable(),
2643
2844
  revoked_at: Timestamp.nullable(),
2644
2845
  created_at: Timestamp
2645
2846
  });
2646
- var ApiKeyCreate = z10.object({
2647
- name: z10.string().min(1).max(120),
2847
+ var ApiKeyCreate = z11.object({
2848
+ name: z11.string().min(1).max(120),
2648
2849
  /** Omitted means `full`. */
2649
2850
  scope: ApiKeyScope.optional()
2650
2851
  });
2651
- var ApiKeyCreated = z10.object({
2652
- key: z10.string().min(20),
2852
+ var ApiKeyCreated = z11.object({
2853
+ key: z11.string().min(20),
2653
2854
  api_key: ApiKey
2654
2855
  });
2655
2856
  var AUDIT_ACTIONS = [
@@ -2738,29 +2939,29 @@ var AUDIT_ACTIONS = [
2738
2939
  "automation.run_ended",
2739
2940
  "event.recorded"
2740
2941
  ];
2741
- var AuditAction = z10.enum(AUDIT_ACTIONS);
2742
- var AuditActor = z10.discriminatedUnion("type", [
2743
- z10.object({ type: z10.literal("member"), member_id: Id, subject: z10.string().min(1) }),
2744
- z10.object({
2745
- type: z10.literal("api_key"),
2942
+ var AuditAction = z11.enum(AUDIT_ACTIONS);
2943
+ var AuditActor = z11.discriminatedUnion("type", [
2944
+ z11.object({ type: z11.literal("member"), member_id: Id, subject: z11.string().min(1) }),
2945
+ z11.object({
2946
+ type: z11.literal("api_key"),
2746
2947
  api_key_id: Id,
2747
2948
  /**
2748
2949
  * Who the client's application said it was acting for, from
2749
2950
  * `ON_BEHALF_OF_HEADER`: reported by that application, never verified.
2750
2951
  * Absent when the call carried no label.
2751
2952
  */
2752
- on_behalf_of: z10.string().min(1).max(ON_BEHALF_OF_MAX_LENGTH).optional()
2953
+ on_behalf_of: z11.string().min(1).max(ON_BEHALF_OF_MAX_LENGTH).optional()
2753
2954
  }),
2754
2955
  /** The service itself (the worker, a bounce, the hosted unsubscribe page). */
2755
- z10.object({ type: z10.literal("system"), reason: z10.string().min(1).max(200) })
2956
+ z11.object({ type: z11.literal("system"), reason: z11.string().min(1).max(200) })
2756
2957
  ]);
2757
- var AuditEntry = z10.object({
2958
+ var AuditEntry = z11.object({
2758
2959
  id: Id,
2759
2960
  action: AuditAction,
2760
2961
  actor: AuditActor,
2761
- target_type: z10.string().min(1).max(64),
2962
+ target_type: z11.string().min(1).max(64),
2762
2963
  target_id: Id.nullable(),
2763
- details: z10.record(z10.unknown()),
2964
+ details: z11.record(z11.unknown()),
2764
2965
  created_at: Timestamp
2765
2966
  });
2766
2967
  var AuditQuery = PageQuery.extend({
@@ -2769,12 +2970,12 @@ var AuditQuery = PageQuery.extend({
2769
2970
  });
2770
2971
 
2771
2972
  // src/invites.ts
2772
- import { z as z11 } from "zod";
2973
+ import { z as z12 } from "zod";
2773
2974
  var INVITE_STATUSES = ["pending", "accepted", "revoked", "expired"];
2774
- var InviteStatus = z11.enum(INVITE_STATUSES);
2975
+ var InviteStatus = z12.enum(INVITE_STATUSES);
2775
2976
  var DEFAULT_INVITE_TTL_DAYS = 7;
2776
2977
  var MAX_INVITE_TTL_DAYS = 30;
2777
- var Invite = z11.object({
2978
+ var Invite = z12.object({
2778
2979
  id: Id,
2779
2980
  /** Stored lowercased; only a person signed in with this address can accept. */
2780
2981
  email: Email,
@@ -2782,32 +2983,32 @@ var Invite = z11.object({
2782
2983
  /** Derived from the timestamps below, never stored. */
2783
2984
  status: InviteStatus,
2784
2985
  /** The member who invited, while they are still one (null after they left). */
2785
- invited_by: z11.object({ member_id: Id.nullable(), email: Email.nullable() }),
2986
+ invited_by: z12.object({ member_id: Id.nullable(), email: Email.nullable() }),
2786
2987
  expires_at: Timestamp,
2787
2988
  accepted_at: Timestamp.nullable(),
2788
2989
  revoked_at: Timestamp.nullable(),
2789
2990
  created_at: Timestamp
2790
2991
  });
2791
- var InviteCreate = z11.object({
2992
+ var InviteCreate = z12.object({
2792
2993
  email: Email,
2793
2994
  role: MemberRole,
2794
- expires_in_days: z11.number().int().min(1).max(MAX_INVITE_TTL_DAYS).optional()
2995
+ expires_in_days: z12.number().int().min(1).max(MAX_INVITE_TTL_DAYS).optional()
2795
2996
  });
2796
- var InviteCreated = z11.object({
2997
+ var InviteCreated = z12.object({
2797
2998
  invite: Invite,
2798
- token: z11.string().min(32).max(128)
2999
+ token: z12.string().min(32).max(128)
2799
3000
  });
2800
3001
  var InviteListQuery = PageQuery.extend({
2801
3002
  status: InviteStatus.optional()
2802
3003
  });
2803
- var InviteAccept = z11.object({
2804
- token: z11.string().min(32).max(128),
3004
+ var InviteAccept = z12.object({
3005
+ token: z12.string().min(32).max(128),
2805
3006
  email: Email,
2806
- name: z11.string().max(200).nullable().optional()
3007
+ name: z12.string().max(200).nullable().optional()
2807
3008
  });
2808
- var InviteAccepted = z11.object({
3009
+ var InviteAccepted = z12.object({
2809
3010
  workspace: WorkspaceMembership,
2810
- already_member: z11.boolean()
3011
+ already_member: z12.boolean()
2811
3012
  });
2812
3013
  var INVITE_REFUSAL_REASONS = ["email_mismatch", "inviter_lacks_role", "expired", "revoked", "accepted"];
2813
3014
 
@@ -3437,13 +3638,13 @@ function renameInsertionEverywhere(drafts, from, rawTo) {
3437
3638
  }
3438
3639
 
3439
3640
  // src/providers.ts
3440
- import { z as z12 } from "zod";
3641
+ import { z as z13 } from "zod";
3441
3642
  var PROVIDER_KINDS = ["smtp", "resend"];
3442
- var ProviderKind = z12.enum(PROVIDER_KINDS);
3443
- var ProviderPolicy = z12.object({
3444
- daily_recipient_budget: z12.number().int().min(1).max(1e7),
3445
- min_interval_ms: z12.number().int().min(0).max(36e5),
3446
- max_recipients_per_message: z12.number().int().min(1).max(1e3)
3643
+ var ProviderKind = z13.enum(PROVIDER_KINDS);
3644
+ var ProviderPolicy = z13.object({
3645
+ daily_recipient_budget: z13.number().int().min(1).max(1e7),
3646
+ min_interval_ms: z13.number().int().min(0).max(36e5),
3647
+ max_recipients_per_message: z13.number().int().min(1).max(1e3)
3447
3648
  });
3448
3649
  var ICLOUD_SMTP_POLICY = {
3449
3650
  daily_recipient_budget: 800,
@@ -3451,17 +3652,17 @@ var ICLOUD_SMTP_POLICY = {
3451
3652
  max_recipients_per_message: 1
3452
3653
  };
3453
3654
  var SMTP_SECURITY = ["tls", "starttls"];
3454
- var SmtpConfigBase = z12.object({
3455
- host: z12.string().min(1).max(255),
3456
- port: z12.number().int().min(1).max(65535),
3655
+ var SmtpConfigBase = z13.object({
3656
+ host: z13.string().min(1).max(255),
3657
+ port: z13.number().int().min(1).max(65535),
3457
3658
  /** `tls` connects encrypted (465), `starttls` upgrades (587). Never plaintext. */
3458
- security: z12.enum(SMTP_SECURITY),
3459
- username: z12.string().min(1).max(255)
3659
+ security: z13.enum(SMTP_SECURITY),
3660
+ username: z13.string().min(1).max(255)
3460
3661
  });
3461
- var ResendConfigBase = z12.object({});
3462
- var ProviderRejections = z12.object({
3463
- count: z12.number().int().min(0),
3464
- last_error: z12.string().nullable(),
3662
+ var ResendConfigBase = z13.object({});
3663
+ var ProviderRejections = z13.object({
3664
+ count: z13.number().int().min(0),
3665
+ last_error: z13.string().nullable(),
3465
3666
  last_at: Timestamp.nullable(),
3466
3667
  /**
3467
3668
  * The last time the bounce circuit breaker tripped on one of this provider's
@@ -3471,59 +3672,59 @@ var ProviderRejections = z12.object({
3471
3672
  * run's bounce blocks were undone and the mailing paused. `sample` is the
3472
3673
  * reply that tripped it.
3473
3674
  */
3474
- anomaly: z12.object({
3675
+ anomaly: z13.object({
3475
3676
  at: Timestamp,
3476
3677
  /** `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. */
3477
- scope: z12.enum(["mailing", "provider"]),
3678
+ scope: z13.enum(["mailing", "provider"]),
3478
3679
  /**
3479
3680
  * True while the provider-wide breaker is open: no bounce blocks through
3480
3681
  * this provider, test sends refused and mailings not started or resumed
3481
3682
  * (`provider_anomaly`), until an admin clears it (`providers.clearAnomaly`).
3482
3683
  */
3483
- blocking: z12.boolean(),
3684
+ blocking: z13.boolean(),
3484
3685
  mailing_id: Id.nullable(),
3485
- reason: z12.string(),
3486
- sample: z12.string()
3686
+ reason: z13.string(),
3687
+ sample: z13.string()
3487
3688
  }).nullable()
3488
3689
  });
3489
- var ProviderEvents = z12.object({
3490
- status: z12.enum(["active", "needs_secret"]),
3491
- source: z12.enum(["automatic", "manual"]).nullable(),
3492
- url: z12.string().url(),
3493
- error: z12.string().nullable(),
3690
+ var ProviderEvents = z13.object({
3691
+ status: z13.enum(["active", "needs_secret"]),
3692
+ source: z13.enum(["automatic", "manual"]).nullable(),
3693
+ url: z13.string().url(),
3694
+ error: z13.string().nullable(),
3494
3695
  /**
3495
3696
  * Events that named an email this provider never sent through the service
3496
3697
  * (another workspace or system sharing the Resend account): counted, never
3497
3698
  * acted on.
3498
3699
  */
3499
- unmatched: z12.number().int().min(0)
3700
+ unmatched: z13.number().int().min(0)
3500
3701
  });
3501
3702
  var RESEND_EVENT_TYPES = ["email.bounced", "email.complained", "email.delivery_delayed"];
3502
- var ResendSigningSecret = z12.string().max(200).regex(/^whsec_[A-Za-z0-9+/]{16,}={0,2}$/, "must be the signing secret Resend shows, starting with whsec_");
3503
- var ProviderEventsSecret = z12.object({ signing_secret: ResendSigningSecret });
3703
+ var ResendSigningSecret = z13.string().max(200).regex(/^whsec_[A-Za-z0-9+/]{16,}={0,2}$/, "must be the signing secret Resend shows, starting with whsec_");
3704
+ var ProviderEventsSecret = z13.object({ signing_secret: ResendSigningSecret });
3504
3705
  var ProviderFields = {
3505
- name: z12.string().min(1).max(120),
3506
- from_name: z12.string().min(1).max(120),
3706
+ name: z13.string().min(1).max(120),
3707
+ from_name: z13.string().min(1).max(120),
3507
3708
  from_email: Email,
3508
3709
  reply_to: Email.nullable(),
3509
3710
  policy: ProviderPolicy
3510
3711
  };
3511
- var Provider = z12.discriminatedUnion("kind", [
3512
- z12.object({
3712
+ var Provider = z13.discriminatedUnion("kind", [
3713
+ z13.object({
3513
3714
  id: Id,
3514
- kind: z12.literal("smtp"),
3715
+ kind: z13.literal("smtp"),
3515
3716
  config: SmtpConfigBase,
3516
- has_secret: z12.boolean(),
3717
+ has_secret: z13.boolean(),
3517
3718
  ...ProviderFields,
3518
3719
  rejections: ProviderRejections,
3519
3720
  created_at: Timestamp,
3520
3721
  updated_at: Timestamp
3521
3722
  }),
3522
- z12.object({
3723
+ z13.object({
3523
3724
  id: Id,
3524
- kind: z12.literal("resend"),
3725
+ kind: z13.literal("resend"),
3525
3726
  config: ResendConfigBase,
3526
- has_secret: z12.boolean(),
3727
+ has_secret: z13.boolean(),
3527
3728
  ...ProviderFields,
3528
3729
  rejections: ProviderRejections,
3529
3730
  events: ProviderEvents,
@@ -3531,31 +3732,31 @@ var Provider = z12.discriminatedUnion("kind", [
3531
3732
  updated_at: Timestamp
3532
3733
  })
3533
3734
  ]);
3534
- var ProviderCreate = z12.discriminatedUnion("kind", [
3535
- z12.object({
3536
- kind: z12.literal("smtp"),
3537
- config: SmtpConfigBase.extend({ password: z12.string().min(1).max(1024) }),
3735
+ var ProviderCreate = z13.discriminatedUnion("kind", [
3736
+ z13.object({
3737
+ kind: z13.literal("smtp"),
3738
+ config: SmtpConfigBase.extend({ password: z13.string().min(1).max(1024) }),
3538
3739
  ...ProviderFields
3539
3740
  }),
3540
- z12.object({
3541
- kind: z12.literal("resend"),
3542
- config: ResendConfigBase.extend({ api_key: z12.string().min(1).max(1024) }),
3741
+ z13.object({
3742
+ kind: z13.literal("resend"),
3743
+ config: ResendConfigBase.extend({ api_key: z13.string().min(1).max(1024) }),
3543
3744
  ...ProviderFields
3544
3745
  })
3545
3746
  ]);
3546
- var ProviderUpdate = z12.discriminatedUnion("kind", [
3547
- z12.object({
3548
- kind: z12.literal("smtp"),
3549
- config: SmtpConfigBase.extend({ password: z12.string().min(1).max(1024).optional() }).partial().optional(),
3747
+ var ProviderUpdate = z13.discriminatedUnion("kind", [
3748
+ z13.object({
3749
+ kind: z13.literal("smtp"),
3750
+ config: SmtpConfigBase.extend({ password: z13.string().min(1).max(1024).optional() }).partial().optional(),
3550
3751
  name: ProviderFields.name.optional(),
3551
3752
  from_name: ProviderFields.from_name.optional(),
3552
3753
  from_email: ProviderFields.from_email.optional(),
3553
3754
  reply_to: ProviderFields.reply_to.optional(),
3554
3755
  policy: ProviderPolicy.partial().optional()
3555
3756
  }),
3556
- z12.object({
3557
- kind: z12.literal("resend"),
3558
- config: ResendConfigBase.extend({ api_key: z12.string().min(1).max(1024).optional() }).optional(),
3757
+ z13.object({
3758
+ kind: z13.literal("resend"),
3759
+ config: ResendConfigBase.extend({ api_key: z13.string().min(1).max(1024).optional() }).optional(),
3559
3760
  name: ProviderFields.name.optional(),
3560
3761
  from_name: ProviderFields.from_name.optional(),
3561
3762
  from_email: ProviderFields.from_email.optional(),
@@ -3563,48 +3764,48 @@ var ProviderUpdate = z12.discriminatedUnion("kind", [
3563
3764
  policy: ProviderPolicy.partial().optional()
3564
3765
  })
3565
3766
  ]);
3566
- var ProviderUsage = z12.object({
3767
+ var ProviderUsage = z13.object({
3567
3768
  provider_id: Id,
3568
- recipients_last_24h: z12.number().int().min(0),
3569
- remaining_budget: z12.number().int().min(0),
3769
+ recipients_last_24h: z13.number().int().min(0),
3770
+ remaining_budget: z13.number().int().min(0),
3570
3771
  /** When enough of the rolling window frees up to send again, if exhausted. */
3571
3772
  next_capacity_at: Timestamp.nullable()
3572
3773
  });
3573
- var ProviderVerifyResult = z12.object({
3574
- ok: z12.boolean(),
3575
- error: z12.string().nullable()
3774
+ var ProviderVerifyResult = z13.object({
3775
+ ok: z13.boolean(),
3776
+ error: z13.string().nullable()
3576
3777
  });
3577
3778
 
3578
3779
  // src/contacts.ts
3579
- import { z as z13 } from "zod";
3580
- var Topic = z13.object({
3780
+ import { z as z14 } from "zod";
3781
+ var Topic = z14.object({
3581
3782
  id: Id,
3582
3783
  slug: Slug,
3583
- name: z13.string().min(1).max(120),
3784
+ name: z14.string().min(1).max(120),
3584
3785
  /** Shown on the hosted preference page. */
3585
- description: z13.string().max(1e3).nullable(),
3786
+ description: z14.string().max(1e3).nullable(),
3586
3787
  /** Translations of `name` and `description` per locale, for the hosted page. */
3587
- translations: z13.record(
3588
- z13.object({ name: z13.string().min(1).max(120), description: z13.string().max(1e3).nullable() })
3788
+ translations: z14.record(
3789
+ z14.object({ name: z14.string().min(1).max(120), description: z14.string().max(1e3).nullable() })
3589
3790
  ),
3590
3791
  created_at: Timestamp,
3591
3792
  updated_at: Timestamp
3592
3793
  });
3593
- var TopicCreate = z13.object({
3794
+ var TopicCreate = z14.object({
3594
3795
  slug: Slug,
3595
- name: z13.string().min(1).max(120),
3596
- description: z13.string().max(1e3).optional(),
3796
+ name: z14.string().min(1).max(120),
3797
+ description: z14.string().max(1e3).optional(),
3597
3798
  translations: Topic.shape.translations.optional()
3598
3799
  });
3599
3800
  var TopicUpdate = TopicCreate.omit({ slug: true }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
3600
- var Contact = z13.object({
3801
+ var Contact = z14.object({
3601
3802
  id: Id,
3602
- external_id: z13.string().min(1).max(255).nullable(),
3803
+ external_id: z14.string().min(1).max(255).nullable(),
3603
3804
  /** Stored lowercased, unique per workspace. */
3604
3805
  email: Email,
3605
- first_name: z13.string().max(200).nullable(),
3606
- last_name: z13.string().max(200).nullable(),
3607
- locale: z13.string().min(2).max(35).nullable(),
3806
+ first_name: z14.string().max(200).nullable(),
3807
+ last_name: z14.string().max(200).nullable(),
3808
+ locale: z14.string().min(2).max(35).nullable(),
3608
3809
  /**
3609
3810
  * The person's own time zone, an IANA name such as `Europe/Berlin` (A1).
3610
3811
  * Every wall clock an automation waits for is read in it, falling back to the
@@ -3612,65 +3813,65 @@ var Contact = z13.object({
3612
3813
  */
3613
3814
  timezone: TimezoneName.nullable(),
3614
3815
  properties: Properties,
3615
- topics: z13.array(Slug),
3816
+ topics: z14.array(Slug),
3616
3817
  /** The slugs of the contact's tags (S4). */
3617
- tags: z13.array(Slug),
3818
+ tags: z14.array(Slug),
3618
3819
  created_at: Timestamp,
3619
3820
  updated_at: Timestamp
3620
3821
  });
3621
- var ContactUpsert = z13.object({
3622
- external_id: z13.string().min(1).max(255).optional(),
3822
+ var ContactUpsert = z14.object({
3823
+ external_id: z14.string().min(1).max(255).optional(),
3623
3824
  email: Email.optional(),
3624
- first_name: z13.string().max(200).nullable().optional(),
3625
- last_name: z13.string().max(200).nullable().optional(),
3626
- locale: z13.string().min(2).max(35).nullable().optional(),
3825
+ first_name: z14.string().max(200).nullable().optional(),
3826
+ last_name: z14.string().max(200).nullable().optional(),
3827
+ locale: z14.string().min(2).max(35).nullable().optional(),
3627
3828
  timezone: TimezoneName.nullable().optional(),
3628
3829
  properties: Properties.optional(),
3629
- topics: z13.array(Slug).max(100).optional()
3830
+ topics: z14.array(Slug).max(100).optional()
3630
3831
  }).refine((v) => v.external_id !== void 0 || v.email !== void 0, {
3631
3832
  message: "external_id or email is required",
3632
3833
  path: ["email"]
3633
3834
  });
3634
- var ContactUpsertResult = z13.object({
3835
+ var ContactUpsertResult = z14.object({
3635
3836
  contact: Contact,
3636
- created: z13.boolean()
3837
+ created: z14.boolean()
3637
3838
  });
3638
3839
  var ContactListQuery = PageQuery.extend({
3639
- email: z13.string().min(1).max(254).optional(),
3640
- external_id: z13.string().min(1).max(255).optional(),
3840
+ email: z14.string().min(1).max(254).optional(),
3841
+ external_id: z14.string().min(1).max(255).optional(),
3641
3842
  topic: Slug.optional()
3642
3843
  });
3643
- var ContactErased = z13.object({
3644
- ok: z13.literal(true),
3645
- erased_messages: z13.number().int().min(0),
3646
- erased_recipients: z13.number().int().min(0),
3647
- suppressions_kept: z13.number().int().min(0)
3844
+ var ContactErased = z14.object({
3845
+ ok: z14.literal(true),
3846
+ erased_messages: z14.number().int().min(0),
3847
+ erased_recipients: z14.number().int().min(0),
3848
+ suppressions_kept: z14.number().int().min(0)
3648
3849
  });
3649
3850
  var SUPPRESSION_REASONS = ["unsubscribed", "bounced", "complained", "manual"];
3650
- var SuppressionReason = z13.enum(SUPPRESSION_REASONS);
3651
- var Suppression = z13.object({
3851
+ var SuppressionReason = z14.enum(SUPPRESSION_REASONS);
3852
+ var Suppression = z14.object({
3652
3853
  id: Id,
3653
3854
  email: Email,
3654
3855
  reason: SuppressionReason,
3655
3856
  topic: Slug.nullable(),
3656
3857
  source_message_id: Id.nullable(),
3657
- note: z13.string().max(1e3).nullable(),
3858
+ note: z14.string().max(1e3).nullable(),
3658
3859
  created_at: Timestamp
3659
3860
  });
3660
- var SuppressionCreate = z13.object({
3861
+ var SuppressionCreate = z14.object({
3661
3862
  email: Email,
3662
- reason: z13.enum(["manual", "unsubscribed"]),
3863
+ reason: z14.enum(["manual", "unsubscribed"]),
3663
3864
  topic: Slug.nullable().optional(),
3664
- note: z13.string().max(1e3).optional()
3865
+ note: z14.string().max(1e3).optional()
3665
3866
  });
3666
3867
  var SuppressionListQuery = PageQuery.extend({
3667
- email: z13.string().min(1).max(254).optional(),
3868
+ email: z14.string().min(1).max(254).optional(),
3668
3869
  reason: SuppressionReason.optional(),
3669
3870
  topic: Slug.optional()
3670
3871
  });
3671
3872
 
3672
3873
  // src/webhooks.ts
3673
- import { z as z14 } from "zod";
3874
+ import { z as z15 } from "zod";
3674
3875
  var WEBHOOK_EVENT_TYPES = [
3675
3876
  "message.sent",
3676
3877
  "message.failed",
@@ -3714,23 +3915,23 @@ var WEBHOOK_EVENT_TYPES = [
3714
3915
  "template.updated",
3715
3916
  "template.deleted"
3716
3917
  ];
3717
- var WebhookEventType = z14.enum(WEBHOOK_EVENT_TYPES);
3718
- var MessageEventBase = z14.object({
3918
+ var WebhookEventType = z15.enum(WEBHOOK_EVENT_TYPES);
3919
+ var MessageEventBase = z15.object({
3719
3920
  message_id: Id,
3720
3921
  mailing_id: Id.nullable(),
3721
3922
  mailing_metadata: MailingMetadata.nullable(),
3722
3923
  recipient_id: Id.nullable(),
3723
3924
  contact_id: Id.nullable(),
3724
- external_id: z14.string().nullable(),
3925
+ external_id: z15.string().nullable(),
3725
3926
  email: Email,
3726
- subject: z14.string(),
3927
+ subject: z15.string(),
3727
3928
  topic: Slug.nullable(),
3728
- provider_message_id: z14.string().nullable(),
3729
- is_test: z14.boolean()
3929
+ provider_message_id: z15.string().nullable(),
3930
+ is_test: z15.boolean()
3730
3931
  });
3731
3932
  var MessageSentData = MessageEventBase.extend({
3732
3933
  /** The final HTML as sent, so the client can archive it beside its own records. */
3733
- html: z14.string(),
3934
+ html: z15.string(),
3734
3935
  sent_at: Timestamp,
3735
3936
  /**
3736
3937
  * The choice each insertion made (see `Message.insertions`); absent or null
@@ -3741,20 +3942,20 @@ var MessageSentData = MessageEventBase.extend({
3741
3942
  insertions: InsertionChoices.nullish()
3742
3943
  });
3743
3944
  var MessageFailedData = MessageEventBase.extend({
3744
- error: z14.string(),
3945
+ error: z15.string(),
3745
3946
  /** False when the provider rejected permanently; the recipient will not be retried. */
3746
- retryable: z14.boolean(),
3947
+ retryable: z15.boolean(),
3747
3948
  failed_at: Timestamp
3748
3949
  });
3749
3950
  var UNSUBSCRIBE_SOURCES = ["hosted_page", "one_click", "api", "dashboard", "signup_form"];
3750
- var ContactUnsubscribedData = z14.object({
3951
+ var ContactUnsubscribedData = z15.object({
3751
3952
  contact_id: Id.nullable(),
3752
- external_id: z14.string().nullable(),
3953
+ external_id: z15.string().nullable(),
3753
3954
  email: Email,
3754
3955
  /** The topic unsubscribed from; null means every topic. */
3755
3956
  topic: Slug.nullable(),
3756
3957
  mailing_id: Id.nullable(),
3757
- source: z14.enum(UNSUBSCRIBE_SOURCES),
3958
+ source: z15.enum(UNSUBSCRIBE_SOURCES),
3758
3959
  unsubscribed_at: Timestamp
3759
3960
  });
3760
3961
  var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: true }).extend({
@@ -3763,142 +3964,142 @@ var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: tr
3763
3964
  * breaker undid a `bounced` block it judged false (a `contact.bounced` for the
3764
3965
  * same address and mailing went out before); `topic` is null.
3765
3966
  */
3766
- source: z14.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
3967
+ source: z15.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
3767
3968
  resubscribed_at: Timestamp
3768
3969
  });
3769
- var ContactBouncedData = z14.object({
3970
+ var ContactBouncedData = z15.object({
3770
3971
  contact_id: Id.nullable(),
3771
- external_id: z14.string().nullable(),
3972
+ external_id: z15.string().nullable(),
3772
3973
  email: Email,
3773
3974
  /** `bounced` for a hard bounce, `complained` for a spam complaint. */
3774
- reason: z14.enum(["bounced", "complained"]),
3975
+ reason: z15.enum(["bounced", "complained"]),
3775
3976
  message_id: Id.nullable(),
3776
- diagnostic: z14.string().nullable(),
3977
+ diagnostic: z15.string().nullable(),
3777
3978
  bounced_at: Timestamp
3778
3979
  });
3779
- var MailingFinishedData = z14.object({
3980
+ var MailingFinishedData = z15.object({
3780
3981
  mailing_id: Id,
3781
3982
  mailing_metadata: MailingMetadata,
3782
- status: z14.enum(["sent", "partially_failed", "cancelled"]),
3983
+ status: z15.enum(["sent", "partially_failed", "cancelled"]),
3783
3984
  counts: MailingCounts,
3784
3985
  finished_at: Timestamp
3785
3986
  });
3786
- var ContactSubscribedData = z14.object({
3987
+ var ContactSubscribedData = z15.object({
3787
3988
  contact_id: Id,
3788
- external_id: z14.string().nullable(),
3989
+ external_id: z15.string().nullable(),
3789
3990
  email: Email,
3790
- topics: z14.array(Slug),
3791
- source: z14.enum(["signup_form", "api", "dashboard", "automation"]),
3991
+ topics: z15.array(Slug),
3992
+ source: z15.enum(["signup_form", "api", "dashboard", "automation"]),
3792
3993
  signup_form_id: Id.nullable(),
3793
- signup_form_version: z14.number().int().min(1).nullable(),
3994
+ signup_form_version: z15.number().int().min(1).nullable(),
3794
3995
  subscribed_at: Timestamp
3795
3996
  });
3796
- var ImportFinishedData = z14.object({
3997
+ var ImportFinishedData = z15.object({
3797
3998
  import_id: Id,
3798
- status: z14.enum(["completed", "cancelled", "failed"]),
3999
+ status: z15.enum(["completed", "cancelled", "failed"]),
3799
4000
  result: ImportReport.nullable(),
3800
- error: z14.string().nullable(),
4001
+ error: z15.string().nullable(),
3801
4002
  finished_at: Timestamp
3802
4003
  });
3803
- var MailingScheduledData = z14.object({
4004
+ var MailingScheduledData = z15.object({
3804
4005
  mailing_id: Id,
3805
4006
  mailing_metadata: MailingMetadata,
3806
4007
  scheduled_at: Timestamp.nullable()
3807
4008
  });
3808
- var MailingStartedData = z14.object({
4009
+ var MailingStartedData = z15.object({
3809
4010
  mailing_id: Id,
3810
4011
  mailing_metadata: MailingMetadata,
3811
- trigger: z14.enum(["send", "schedule"]),
3812
- recipients: z14.number().int().min(0),
4012
+ trigger: z15.enum(["send", "schedule"]),
4013
+ recipients: z15.number().int().min(0),
3813
4014
  started_at: Timestamp
3814
4015
  });
3815
- var MailingScheduleFailedData = z14.object({
4016
+ var MailingScheduleFailedData = z15.object({
3816
4017
  mailing_id: Id,
3817
4018
  mailing_metadata: MailingMetadata,
3818
- code: z14.string(),
3819
- message: z14.string(),
4019
+ code: z15.string(),
4020
+ message: z15.string(),
3820
4021
  failed_at: Timestamp
3821
4022
  });
3822
- var MailingAbWinnerSelectedData = z14.object({
4023
+ var MailingAbWinnerSelectedData = z15.object({
3823
4024
  mailing_id: Id,
3824
4025
  mailing_metadata: MailingMetadata,
3825
- winner: z14.string(),
3826
- decided_by: z14.enum(["metric", "manual"]),
3827
- variants: z14.array(VariantAnalytics),
4026
+ winner: z15.string(),
4027
+ decided_by: z15.enum(["metric", "manual"]),
4028
+ variants: z15.array(VariantAnalytics),
3828
4029
  decided_at: Timestamp
3829
4030
  });
3830
- var ContactTaggedData = z14.object({
4031
+ var ContactTaggedData = z15.object({
3831
4032
  contact_id: Id,
3832
- external_id: z14.string().nullable(),
4033
+ external_id: z15.string().nullable(),
3833
4034
  email: Email,
3834
4035
  /** Only the tags the contact did not already have. */
3835
- tags: z14.array(Slug).min(1),
3836
- source: z14.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4036
+ tags: z15.array(Slug).min(1),
4037
+ source: z15.enum(["api", "dashboard", "signup_form", "import", "automation"]),
3837
4038
  tagged_at: Timestamp
3838
4039
  });
3839
- var ContactUpdatedData = z14.object({
4040
+ var ContactUpdatedData = z15.object({
3840
4041
  contact_id: Id,
3841
- external_id: z14.string().nullable(),
4042
+ external_id: z15.string().nullable(),
3842
4043
  email: Email,
3843
- changed: z14.array(z14.string()).min(1),
4044
+ changed: z15.array(z15.string()).min(1),
3844
4045
  properties: Properties,
3845
- source: z14.enum(["api", "dashboard", "signup_form", "import", "automation"]),
4046
+ source: z15.enum(["api", "dashboard", "signup_form", "import", "automation"]),
3846
4047
  updated_at: Timestamp
3847
4048
  });
3848
- var AutomationRunEventBase = z14.object({
4049
+ var AutomationRunEventBase = z15.object({
3849
4050
  automation_id: Id,
3850
- automation_name: z14.string(),
4051
+ automation_name: z15.string(),
3851
4052
  run_id: Id,
3852
- version: z14.number().int().min(1),
4053
+ version: z15.number().int().min(1),
3853
4054
  contact_id: Id,
3854
- external_id: z14.string().nullable(),
4055
+ external_id: z15.string().nullable(),
3855
4056
  email: Email
3856
4057
  });
3857
4058
  var AutomationRunStartedData = AutomationRunEventBase.extend({
3858
4059
  /** What let them in: a trigger kind, or `manual` for an explicit enrolment. */
3859
- trigger_kind: z14.string(),
4060
+ trigger_kind: z15.string(),
3860
4061
  entered_at: Timestamp
3861
4062
  });
3862
4063
  var AutomationRunCompletedData = AutomationRunEventBase.extend({
3863
- last_step_id: z14.string().nullable(),
4064
+ last_step_id: z15.string().nullable(),
3864
4065
  completed_at: Timestamp
3865
4066
  });
3866
4067
  var AutomationRunExitedData = AutomationRunEventBase.extend({
3867
4068
  reason: AutomationEndReason,
3868
- step_id: z14.string().nullable(),
4069
+ step_id: z15.string().nullable(),
3869
4070
  exited_at: Timestamp
3870
4071
  });
3871
4072
  var AutomationRunFailedData = AutomationRunEventBase.extend({
3872
- reason: z14.string(),
3873
- step_id: z14.string().nullable(),
4073
+ reason: z15.string(),
4074
+ step_id: z15.string().nullable(),
3874
4075
  failed_at: Timestamp
3875
4076
  });
3876
4077
  var AutomationWebhookData = AutomationRunEventBase.extend({
3877
- step_id: z14.string(),
4078
+ step_id: z15.string(),
3878
4079
  /** The step's own label, when it was given one, so a receiver can branch on a name. */
3879
- step_label: z14.string().nullable(),
4080
+ step_label: z15.string().nullable(),
3880
4081
  /** Whatever the step carries, verbatim. Null when it carries nothing. */
3881
4082
  payload: JsonValue.nullable(),
3882
4083
  fired_at: Timestamp
3883
4084
  });
3884
- var TemplateEventBase = z14.object({
4085
+ var TemplateEventBase = z15.object({
3885
4086
  template_id: Id,
3886
- name: z14.string().min(1).max(200),
3887
- version: z14.number().int().min(1),
3888
- source: z14.enum(["api", "dashboard", "mjml_import"])
4087
+ name: z15.string().min(1).max(200),
4088
+ version: z15.number().int().min(1),
4089
+ source: z15.enum(["api", "dashboard", "mjml_import"])
3889
4090
  });
3890
4091
  var TemplateCreatedData = TemplateEventBase.extend({ created_at: Timestamp });
3891
- var TemplateUpdatedData = TemplateEventBase.extend({ archived: z14.boolean(), updated_at: Timestamp });
4092
+ var TemplateUpdatedData = TemplateEventBase.extend({ archived: z15.boolean(), updated_at: Timestamp });
3892
4093
  var TemplateDeletedData = TemplateEventBase.extend({ deleted_at: Timestamp });
3893
- var envelope = (type, data) => z14.object({
4094
+ var envelope = (type, data) => z15.object({
3894
4095
  /** Unique per event: a receiver deduplicates on it (deliveries may repeat). */
3895
4096
  id: Id,
3896
- type: z14.literal(type),
4097
+ type: z15.literal(type),
3897
4098
  created_at: Timestamp,
3898
4099
  workspace_id: Id,
3899
4100
  data
3900
4101
  });
3901
- var WebhookEvent = z14.discriminatedUnion("type", [
4102
+ var WebhookEvent = z15.discriminatedUnion("type", [
3902
4103
  envelope("message.sent", MessageSentData),
3903
4104
  envelope("message.failed", MessageFailedData),
3904
4105
  envelope("contact.unsubscribed", ContactUnsubscribedData),
@@ -3922,16 +4123,16 @@ var WebhookEvent = z14.discriminatedUnion("type", [
3922
4123
  envelope("template.updated", TemplateUpdatedData),
3923
4124
  envelope("template.deleted", TemplateDeletedData)
3924
4125
  ]);
3925
- var WebhookEndpoint = z14.object({
4126
+ var WebhookEndpoint = z15.object({
3926
4127
  id: Id,
3927
- url: z14.string().url(),
3928
- description: z14.string().max(500).nullable(),
3929
- events: z14.array(WebhookEventType).min(1),
3930
- enabled: z14.boolean(),
4128
+ url: z15.string().url(),
4129
+ description: z15.string().max(500).nullable(),
4130
+ events: z15.array(WebhookEventType).min(1),
4131
+ enabled: z15.boolean(),
3931
4132
  created_at: Timestamp,
3932
4133
  updated_at: Timestamp
3933
4134
  });
3934
- var WebhookUrl = z14.string().url().refine((u) => {
4135
+ var WebhookUrl = z15.string().url().refine((u) => {
3935
4136
  try {
3936
4137
  const url = new URL(u);
3937
4138
  if (url.protocol === "https:") return true;
@@ -3940,35 +4141,35 @@ var WebhookUrl = z14.string().url().refine((u) => {
3940
4141
  return false;
3941
4142
  }
3942
4143
  }, "must be https (http only for localhost)");
3943
- var WebhookEndpointCreate = z14.object({
4144
+ var WebhookEndpointCreate = z15.object({
3944
4145
  url: WebhookUrl,
3945
- description: z14.string().max(500).optional(),
3946
- events: z14.array(WebhookEventType).min(1),
3947
- enabled: z14.boolean().optional()
4146
+ description: z15.string().max(500).optional(),
4147
+ events: z15.array(WebhookEventType).min(1),
4148
+ enabled: z15.boolean().optional()
3948
4149
  });
3949
- var WebhookEndpointUpdate = z14.object({
4150
+ var WebhookEndpointUpdate = z15.object({
3950
4151
  url: WebhookUrl,
3951
- description: z14.string().max(500).nullable(),
3952
- events: z14.array(WebhookEventType).min(1),
3953
- enabled: z14.boolean()
4152
+ description: z15.string().max(500).nullable(),
4153
+ events: z15.array(WebhookEventType).min(1),
4154
+ enabled: z15.boolean()
3954
4155
  }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
3955
- var WebhookEndpointWithSecret = z14.object({
4156
+ var WebhookEndpointWithSecret = z15.object({
3956
4157
  endpoint: WebhookEndpoint,
3957
- secret: z14.string().min(32)
4158
+ secret: z15.string().min(32)
3958
4159
  });
3959
4160
  var WEBHOOK_DELIVERY_STATUSES = ["pending", "succeeded", "failed"];
3960
- var WebhookDeliveryStatus = z14.enum(WEBHOOK_DELIVERY_STATUSES);
4161
+ var WebhookDeliveryStatus = z15.enum(WEBHOOK_DELIVERY_STATUSES);
3961
4162
  var WEBHOOK_MAX_ATTEMPTS = 8;
3962
4163
  var WEBHOOK_RETRY_DELAYS_SECONDS = [30, 120, 600, 1800, 3600, 7200, 21600];
3963
- var WebhookDelivery = z14.object({
4164
+ var WebhookDelivery = z15.object({
3964
4165
  id: Id,
3965
4166
  endpoint_id: Id,
3966
4167
  event_id: Id,
3967
4168
  event_type: WebhookEventType,
3968
4169
  status: WebhookDeliveryStatus,
3969
- attempts: z14.number().int().min(0),
3970
- last_status_code: z14.number().int().min(100).max(599).nullable(),
3971
- last_error: z14.string().nullable(),
4170
+ attempts: z15.number().int().min(0),
4171
+ last_status_code: z15.number().int().min(100).max(599).nullable(),
4172
+ last_error: z15.string().nullable(),
3972
4173
  next_attempt_at: Timestamp.nullable(),
3973
4174
  delivered_at: Timestamp.nullable(),
3974
4175
  created_at: Timestamp
@@ -3977,7 +4178,7 @@ var WebhookDeliveryListQuery = PageQuery.extend({
3977
4178
  status: WebhookDeliveryStatus.optional(),
3978
4179
  event_type: WebhookEventType.optional()
3979
4180
  });
3980
- var WebhookDeliveryParams = z14.object({ id: Id, delivery_id: Id });
4181
+ var WebhookDeliveryParams = z15.object({ id: Id, delivery_id: Id });
3981
4182
 
3982
4183
  // src/webhook-signing.ts
3983
4184
  var WEBHOOK_SIGNATURE_HEADER = "x-mail-signature";
@@ -4044,79 +4245,79 @@ async function verifyWebhook(input) {
4044
4245
  }
4045
4246
 
4046
4247
  // src/billing.ts
4047
- import { z as z15 } from "zod";
4248
+ import { z as z16 } from "zod";
4048
4249
  var PLAN_IDS = ["free", "starter", "growth", "design_partner"];
4049
- var PlanId = z15.enum(PLAN_IDS);
4050
- var PlanLimits = z15.object({
4051
- monthly_messages: z15.number().int().min(0).nullable(),
4052
- contacts: z15.number().int().min(0).nullable(),
4053
- members: z15.number().int().min(1).nullable(),
4054
- providers: z15.number().int().min(1).nullable(),
4055
- webhook_endpoints: z15.number().int().min(0).nullable(),
4250
+ var PlanId = z16.enum(PLAN_IDS);
4251
+ var PlanLimits = z16.object({
4252
+ monthly_messages: z16.number().int().min(0).nullable(),
4253
+ contacts: z16.number().int().min(0).nullable(),
4254
+ members: z16.number().int().min(1).nullable(),
4255
+ providers: z16.number().int().min(1).nullable(),
4256
+ webhook_endpoints: z16.number().int().min(0).nullable(),
4056
4257
  /** Automations that may be live (active or paused) at once (A1). */
4057
- active_automations: z15.number().int().min(0).nullable(),
4258
+ active_automations: z16.number().int().min(0).nullable(),
4058
4259
  /** Steps one automation may hold. Null is the flow's own cap, not unlimited. */
4059
- automation_steps: z15.number().int().min(1).nullable()
4260
+ automation_steps: z16.number().int().min(1).nullable()
4060
4261
  });
4061
- var PlanFeatures = z15.object({
4262
+ var PlanFeatures = z16.object({
4062
4263
  /** A/B tests of subject and content on a mailing (S4). */
4063
- ab_testing: z15.boolean(),
4264
+ ab_testing: z16.boolean(),
4064
4265
  /** Open and click tracking, still off until a workspace turns it on (`settings.tracking_enabled`). */
4065
- tracking: z15.boolean(),
4266
+ tracking: z16.boolean(),
4066
4267
  /** Sending and hosting pages on the workspace's own domain (a later phase). */
4067
- custom_domains: z15.boolean(),
4268
+ custom_domains: z16.boolean(),
4068
4269
  /** Automations: flows a person walks through step by step (A1). */
4069
- automations: z15.boolean()
4270
+ automations: z16.boolean()
4070
4271
  });
4071
4272
  var PLAN_FEATURES = ["ab_testing", "tracking", "custom_domains", "automations"];
4072
- var Plan = z15.object({
4273
+ var Plan = z16.object({
4073
4274
  id: PlanId,
4074
- name: z15.string().min(1),
4275
+ name: z16.string().min(1),
4075
4276
  /** Price in the smallest currency unit per month; null for plans not sold. */
4076
- monthly_price_cents: z15.number().int().min(0).nullable(),
4077
- currency: z15.string().length(3),
4277
+ monthly_price_cents: z16.number().int().min(0).nullable(),
4278
+ currency: z16.string().length(3),
4078
4279
  limits: PlanLimits,
4079
4280
  features: PlanFeatures
4080
4281
  });
4081
- var CatalogPlan = Plan.extend({ sellable: z15.boolean() });
4082
- var Subscription = z15.object({
4282
+ var CatalogPlan = Plan.extend({ sellable: z16.boolean() });
4283
+ var Subscription = z16.object({
4083
4284
  workspace_id: Id,
4084
4285
  plan: PlanId,
4085
- status: z15.enum(["active", "trialing", "past_due", "cancelled"]),
4286
+ status: z16.enum(["active", "trialing", "past_due", "cancelled"]),
4086
4287
  current_period_start: Timestamp,
4087
4288
  current_period_end: Timestamp,
4088
- cancel_at_period_end: z15.boolean(),
4289
+ cancel_at_period_end: z16.boolean(),
4089
4290
  /**
4090
4291
  * A design partner outside billing (plan `design_partner`, no limits, no
4091
4292
  * checkout). Set only by an operator, never through the API.
4092
4293
  */
4093
- billing_exempt: z15.boolean()
4294
+ billing_exempt: z16.boolean()
4094
4295
  });
4095
4296
  var USAGE_METRICS = ["messages", "contacts", "members", "providers", "webhook_endpoints", "active_automations"];
4096
- var UsageMetric = z15.enum(USAGE_METRICS);
4297
+ var UsageMetric = z16.enum(USAGE_METRICS);
4097
4298
  var USAGE_WARNING_RATIO = 0.8;
4098
- var UsageWarning = z15.object({
4299
+ var UsageWarning = z16.object({
4099
4300
  metric: UsageMetric,
4100
- used: z15.number().int().min(0),
4101
- limit: z15.number().int().min(0),
4301
+ used: z16.number().int().min(0),
4302
+ limit: z16.number().int().min(0),
4102
4303
  /** `approaching`: at or above USAGE_WARNING_RATIO of the limit; `reached`: at or above the limit. */
4103
- level: z15.enum(["approaching", "reached"])
4304
+ level: z16.enum(["approaching", "reached"])
4104
4305
  });
4105
- var Usage = z15.object({
4306
+ var Usage = z16.object({
4106
4307
  plan: PlanId,
4107
4308
  period_start: Timestamp,
4108
4309
  period_end: Timestamp,
4109
- metrics: z15.record(UsageMetric, z15.object({ used: z15.number().int().min(0), limit: z15.number().int().min(0).nullable() })),
4110
- warnings: z15.array(UsageWarning)
4310
+ metrics: z16.record(UsageMetric, z16.object({ used: z16.number().int().min(0), limit: z16.number().int().min(0).nullable() })),
4311
+ warnings: z16.array(UsageWarning)
4111
4312
  });
4112
- var CheckoutRequest = z15.object({
4113
- plan: z15.enum(["starter", "growth"]),
4114
- success_url: z15.string().url(),
4115
- cancel_url: z15.string().url()
4313
+ var CheckoutRequest = z16.object({
4314
+ plan: z16.enum(["starter", "growth"]),
4315
+ success_url: z16.string().url(),
4316
+ cancel_url: z16.string().url()
4116
4317
  });
4117
- var CheckoutSession = z15.object({ url: z15.string().url() });
4118
- var PortalRequest = z15.object({ return_url: z15.string().url() });
4119
- var PortalSession = z15.object({ url: z15.string().url() });
4318
+ var CheckoutSession = z16.object({ url: z16.string().url() });
4319
+ var PortalRequest = z16.object({ return_url: z16.string().url() });
4320
+ var PortalSession = z16.object({ url: z16.string().url() });
4120
4321
  var USAGE_WARNING_HEADER = "x-mail-usage-warning";
4121
4322
  function formatUsageWarningHeader(warnings) {
4122
4323
  if (warnings.length === 0) return null;
@@ -4136,7 +4337,7 @@ function parseUsageWarningHeader(value) {
4136
4337
  }
4137
4338
 
4138
4339
  // src/routes.ts
4139
- import { z as z16 } from "zod";
4340
+ import { z as z17 } from "zod";
4140
4341
  var list = (item) => page(item);
4141
4342
  var foundationRoutes = {
4142
4343
  "workspaces.create": {
@@ -4364,7 +4565,7 @@ var templateRoutes = {
4364
4565
  path: "/v1/templates/:id/export",
4365
4566
  params: IdParams,
4366
4567
  query: TemplateExportQuery,
4367
- response: z16.string(),
4568
+ response: z17.string(),
4368
4569
  responseType: "text",
4369
4570
  status: 200,
4370
4571
  access: "read",
@@ -4688,7 +4889,7 @@ var sendingRoutes = {
4688
4889
  path: "/v1/mailings/:id/export",
4689
4890
  params: IdParams,
4690
4891
  query: MailingExportQuery,
4691
- response: z16.string(),
4892
+ response: z17.string(),
4692
4893
  responseType: "text",
4693
4894
  status: 200,
4694
4895
  access: "read",
@@ -4734,6 +4935,21 @@ var sendingRoutes = {
4734
4935
  access: "write",
4735
4936
  phase: "S2"
4736
4937
  },
4938
+ /**
4939
+ * A dry run: what each given recipient would be sent (every value's text and
4940
+ * the layer it comes from, each insertion's choice, the problems found),
4941
+ * without adding anybody. Reads only, in any state of the mailing.
4942
+ */
4943
+ "mailings.resolve": {
4944
+ method: "POST",
4945
+ path: "/v1/mailings/:id/resolve",
4946
+ params: IdParams,
4947
+ body: MailingResolveRequest,
4948
+ response: MailingResolveResult,
4949
+ status: 200,
4950
+ access: "read",
4951
+ phase: "S2"
4952
+ },
4737
4953
  "mailings.send": {
4738
4954
  method: "POST",
4739
4955
  path: "/v1/mailings/:id/send",
@@ -4921,7 +5137,7 @@ var platformRoutes = {
4921
5137
  "contactProperties.list": {
4922
5138
  method: "GET",
4923
5139
  path: "/v1/contact-properties",
4924
- response: z16.object({ data: z16.array(ContactPropertyDefinition) }),
5140
+ response: z17.object({ data: z17.array(ContactPropertyDefinition) }),
4925
5141
  status: 200,
4926
5142
  access: "read",
4927
5143
  phase: "S4"
@@ -5220,7 +5436,7 @@ var billingRoutes = {
5220
5436
  "billing.plans": {
5221
5437
  method: "GET",
5222
5438
  path: "/v1/billing/plans",
5223
- response: z16.object({ data: z16.array(CatalogPlan) }),
5439
+ response: z17.object({ data: z17.array(CatalogPlan) }),
5224
5440
  status: 200,
5225
5441
  access: "read",
5226
5442
  phase: "S5"
@@ -5362,7 +5578,7 @@ var automationRoutes = {
5362
5578
  method: "POST",
5363
5579
  path: "/v1/automations/:id/pause",
5364
5580
  params: IdParams,
5365
- body: z16.object({}).strict(),
5581
+ body: z17.object({}).strict(),
5366
5582
  response: Automation,
5367
5583
  status: 200,
5368
5584
  access: "write",
@@ -5372,7 +5588,7 @@ var automationRoutes = {
5372
5588
  method: "POST",
5373
5589
  path: "/v1/automations/:id/resume",
5374
5590
  params: IdParams,
5375
- body: z16.object({}).strict(),
5591
+ body: z17.object({}).strict(),
5376
5592
  response: Automation,
5377
5593
  status: 200,
5378
5594
  access: "write",
@@ -5382,7 +5598,7 @@ var automationRoutes = {
5382
5598
  method: "POST",
5383
5599
  path: "/v1/automations/:id/archive",
5384
5600
  params: IdParams,
5385
- body: z16.object({}).strict(),
5601
+ body: z17.object({}).strict(),
5386
5602
  response: Automation,
5387
5603
  status: 200,
5388
5604
  access: "write",
@@ -5516,13 +5732,13 @@ function matchRoute(method, pathname) {
5516
5732
  for (const [id, route] of Object.entries(routes)) {
5517
5733
  if (route.method !== method) continue;
5518
5734
  const names = [];
5519
- const pattern2 = new RegExp(
5735
+ const pattern3 = new RegExp(
5520
5736
  "^" + route.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/:([a-z_]+)/g, (_, name) => {
5521
5737
  names.push(name);
5522
5738
  return "([^/]+)";
5523
5739
  }) + "$"
5524
5740
  );
5525
- const match = pattern2.exec(pathname);
5741
+ const match = pattern3.exec(pathname);
5526
5742
  if (!match) continue;
5527
5743
  const params = {};
5528
5744
  names.forEach((name, i) => {
@@ -5722,6 +5938,7 @@ export {
5722
5938
  InviteListQuery,
5723
5939
  InviteStatus,
5724
5940
  JsonValue,
5941
+ LETTER_ONLY_MERGE_FIELDS,
5725
5942
  LETTER_RECIPIENT_REFUSAL,
5726
5943
  LIST_UNSUBSCRIBE_POST_VALUE,
5727
5944
  LOCALE_TAG_PATTERN,
@@ -5790,7 +6007,10 @@ export {
5790
6007
  MailingLanguageReport,
5791
6008
  MailingLanguageStatus,
5792
6009
  MailingListQuery,
6010
+ MailingMerge,
5793
6011
  MailingMetadata,
6012
+ MailingResolveRequest,
6013
+ MailingResolveResult,
5794
6014
  MailingRetryFailedRequest,
5795
6015
  MailingScheduleFailedData,
5796
6016
  MailingScheduleRequest,
@@ -5815,6 +6035,8 @@ export {
5815
6035
  MessageOutcome,
5816
6036
  MessageSentData,
5817
6037
  MessageSummary,
6038
+ MessageValues,
6039
+ NAME_ON_BROADCAST_REFUSAL,
5818
6040
  NotifyRecipients,
5819
6041
  NotifyStep,
5820
6042
  ON_BEHALF_OF_HEADER,
@@ -5850,6 +6072,8 @@ export {
5850
6072
  REQUEST_ID_HEADER,
5851
6073
  RESEND_EVENT_TYPES,
5852
6074
  RESERVED_MERGE_FIELDS,
6075
+ RESOLVE_PROBLEMS,
6076
+ RESOLVE_REJECTIONS,
5853
6077
  RETRYABLE_ERRORS,
5854
6078
  RETRY_AFTER_HEADER,
5855
6079
  RE_ENTRY_MODES,
@@ -5862,6 +6086,9 @@ export {
5862
6086
  RecipientStatus,
5863
6087
  RemoteImage,
5864
6088
  ResendSigningSecret,
6089
+ ResolveProblem,
6090
+ ResolvedRecipient,
6091
+ ResolvedValue,
5865
6092
  SERVICE_FILLED_MERGE_FIELDS,
5866
6093
  SIGNUP_FORM_FIELDS,
5867
6094
  SKIP_REASONS,
@@ -5948,10 +6175,13 @@ export {
5948
6175
  USAGE_METRICS,
5949
6176
  USAGE_WARNING_HEADER,
5950
6177
  USAGE_WARNING_RATIO,
6178
+ UnfilledLink,
5951
6179
  Usage,
5952
6180
  UsageMetric,
5953
6181
  UsageWarning,
6182
+ VALUE_LAYERS,
5954
6183
  ValidationIssue,
6184
+ ValueLayer,
5955
6185
  VariantAnalytics,
5956
6186
  WEBHOOK_DELIVERY_STATUSES,
5957
6187
  WEBHOOK_EVENT_ID_HEADER,
@@ -6015,6 +6245,7 @@ export {
6015
6245
  editMainInsertions,
6016
6246
  effectivePreviewPicks,
6017
6247
  emptyFlow,
6248
+ emptyLinkValues,
6018
6249
  errorBody,
6019
6250
  escapeMergeHtml,
6020
6251
  exportFilename,
@@ -6045,6 +6276,8 @@ export {
6045
6276
  languageInsertions,
6046
6277
  languageName,
6047
6278
  languageTabs,
6279
+ letterOnlyValues,
6280
+ linkTokens,
6048
6281
  mainInsertionText,
6049
6282
  matchLocale,
6050
6283
  matchRoute,
@@ -6065,6 +6298,8 @@ export {
6065
6298
  previewInsertions,
6066
6299
  previewPersonalization,
6067
6300
  primaryLanguage,
6301
+ printedFields,
6302
+ rawMergeValue,
6068
6303
  reachable,
6069
6304
  readyWithoutInsertions,
6070
6305
  readyWithoutSubject,
@@ -6081,6 +6316,7 @@ export {
6081
6316
  renameTokenInDocument,
6082
6317
  renameTokenInText,
6083
6318
  resolveInsertions,
6319
+ resolveValue,
6084
6320
  restorePatch,
6085
6321
  routes,
6086
6322
  sameJson,
@@ -6107,5 +6343,7 @@ export {
6107
6343
  unknownRefusedInsertions,
6108
6344
  unplacedInsertions,
6109
6345
  validateAutomation,
6346
+ valueNames,
6347
+ valuesRead,
6110
6348
  verifyWebhook
6111
6349
  };