@marlinjai/mail-contract 0.10.0 → 0.12.0

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