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