@marlinjai/mail-contract 0.20.0 → 0.22.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.d.mts +1026 -59
- package/dist/index.d.ts +1026 -59
- package/dist/index.js +661 -186
- package/dist/index.mjs +641 -186
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -131,8 +131,11 @@ var RETRYABLE_ERRORS = [
|
|
|
131
131
|
"service_unavailable"
|
|
132
132
|
];
|
|
133
133
|
var BILLING_NOT_CONFIGURED_REASON = "billing_not_configured";
|
|
134
|
+
var DOMAIN_BUYING_NOT_CONFIGURED_REASON = "domain_buying_not_configured";
|
|
135
|
+
var DOMAIN_PRICE_CHANGED_REASON = "price_changed";
|
|
136
|
+
var LASTING_REASONS = [BILLING_NOT_CONFIGURED_REASON, DOMAIN_BUYING_NOT_CONFIGURED_REASON];
|
|
134
137
|
function isRetryableError(code, details) {
|
|
135
|
-
return RETRYABLE_ERRORS.includes(code) && details?.reason
|
|
138
|
+
return RETRYABLE_ERRORS.includes(code) && !LASTING_REASONS.includes(details?.reason);
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
// src/headers.ts
|
|
@@ -2785,7 +2788,7 @@ var EventListQuery = PageQuery.extend({
|
|
|
2785
2788
|
|
|
2786
2789
|
// src/legal.ts
|
|
2787
2790
|
import { z as z11 } from "zod";
|
|
2788
|
-
var LEGAL_TERMS_VERSION = "2026-10-
|
|
2791
|
+
var LEGAL_TERMS_VERSION = "2026-10-28";
|
|
2789
2792
|
var AcceptTerms = z11.literal(LEGAL_TERMS_VERSION, {
|
|
2790
2793
|
errorMap: () => ({ message: `must be "${LEGAL_TERMS_VERSION}": accept the current terms of service and processing agreement` })
|
|
2791
2794
|
});
|
|
@@ -3038,6 +3041,15 @@ var AUDIT_ACTIONS = [
|
|
|
3038
3041
|
"billing.exemption_changed",
|
|
3039
3042
|
"billing.extra_sending_domains_changed",
|
|
3040
3043
|
"billing.terms_accepted",
|
|
3044
|
+
// Domains bought inside Lumitra Mail
|
|
3045
|
+
"domain_order.created",
|
|
3046
|
+
"domain_order.paid",
|
|
3047
|
+
"domain_order.registered",
|
|
3048
|
+
"domain_order.ready",
|
|
3049
|
+
"domain_order.needs_attention",
|
|
3050
|
+
"domain_order.kind_changed",
|
|
3051
|
+
"domain_order.refunded",
|
|
3052
|
+
"domain_order.cancelled",
|
|
3041
3053
|
// A1: automations
|
|
3042
3054
|
"automation.created",
|
|
3043
3055
|
"automation.updated",
|
|
@@ -3052,7 +3064,7 @@ var AUDIT_ACTIONS = [
|
|
|
3052
3064
|
"event.recorded"
|
|
3053
3065
|
];
|
|
3054
3066
|
var AuditAction = z12.enum(AUDIT_ACTIONS);
|
|
3055
|
-
var TRUSTED_APPS = ["booking"];
|
|
3067
|
+
var TRUSTED_APPS = ["booking", "sites"];
|
|
3056
3068
|
var TrustedApp = z12.enum(TRUSTED_APPS);
|
|
3057
3069
|
var AuditActor = z12.discriminatedUnion("type", [
|
|
3058
3070
|
z12.object({
|
|
@@ -3961,36 +3973,418 @@ function senderOnDomain(input, ctx) {
|
|
|
3961
3973
|
var SendingDomainCreate = z15.object({ domain: SendingDomainName, ...SenderFields }).superRefine(senderOnDomain);
|
|
3962
3974
|
var SendingDomainUpdate = z15.object({ from_name: SenderFields.from_name.optional(), from_email: Email.optional(), reply_to: Email.nullable().optional() }).refine((v) => Object.keys(v).length > 0, "nothing to change");
|
|
3963
3975
|
|
|
3964
|
-
// src/
|
|
3976
|
+
// src/domains.ts
|
|
3965
3977
|
import { z as z16 } from "zod";
|
|
3966
|
-
|
|
3978
|
+
|
|
3979
|
+
// src/phone.ts
|
|
3980
|
+
var REGISTRY_PHONE = /^\+\d{1,3}\.\d{4,14}$/;
|
|
3981
|
+
var CALLING_CODE_OF_COUNTRY = {
|
|
3982
|
+
DE: "49",
|
|
3983
|
+
AT: "43",
|
|
3984
|
+
CH: "41",
|
|
3985
|
+
LI: "423",
|
|
3986
|
+
LU: "352",
|
|
3987
|
+
NL: "31",
|
|
3988
|
+
BE: "32",
|
|
3989
|
+
FR: "33",
|
|
3990
|
+
IT: "39",
|
|
3991
|
+
ES: "34",
|
|
3992
|
+
PT: "351",
|
|
3993
|
+
IE: "353",
|
|
3994
|
+
GB: "44",
|
|
3995
|
+
DK: "45",
|
|
3996
|
+
SE: "46",
|
|
3997
|
+
NO: "47",
|
|
3998
|
+
FI: "358",
|
|
3999
|
+
IS: "354",
|
|
4000
|
+
PL: "48",
|
|
4001
|
+
CZ: "420",
|
|
4002
|
+
SK: "421",
|
|
4003
|
+
HU: "36",
|
|
4004
|
+
SI: "386",
|
|
4005
|
+
HR: "385",
|
|
4006
|
+
RO: "40",
|
|
4007
|
+
BG: "359",
|
|
4008
|
+
GR: "30",
|
|
4009
|
+
CY: "357",
|
|
4010
|
+
MT: "356",
|
|
4011
|
+
EE: "372",
|
|
4012
|
+
LV: "371",
|
|
4013
|
+
LT: "370",
|
|
4014
|
+
US: "1",
|
|
4015
|
+
CA: "1",
|
|
4016
|
+
AU: "61",
|
|
4017
|
+
NZ: "64",
|
|
4018
|
+
TR: "90",
|
|
4019
|
+
IL: "972",
|
|
4020
|
+
AE: "971",
|
|
4021
|
+
IN: "91",
|
|
4022
|
+
JP: "81",
|
|
4023
|
+
CN: "86",
|
|
4024
|
+
SG: "65",
|
|
4025
|
+
ZA: "27",
|
|
4026
|
+
BR: "55",
|
|
4027
|
+
MX: "52",
|
|
4028
|
+
UA: "380",
|
|
4029
|
+
RS: "381"
|
|
4030
|
+
};
|
|
4031
|
+
var CALLING_CODES = /* @__PURE__ */ new Set([
|
|
4032
|
+
"1",
|
|
4033
|
+
"7",
|
|
4034
|
+
"20",
|
|
4035
|
+
"27",
|
|
4036
|
+
"30",
|
|
4037
|
+
"31",
|
|
4038
|
+
"32",
|
|
4039
|
+
"33",
|
|
4040
|
+
"34",
|
|
4041
|
+
"36",
|
|
4042
|
+
"39",
|
|
4043
|
+
"40",
|
|
4044
|
+
"41",
|
|
4045
|
+
"43",
|
|
4046
|
+
"44",
|
|
4047
|
+
"45",
|
|
4048
|
+
"46",
|
|
4049
|
+
"47",
|
|
4050
|
+
"48",
|
|
4051
|
+
"49",
|
|
4052
|
+
"51",
|
|
4053
|
+
"52",
|
|
4054
|
+
"53",
|
|
4055
|
+
"54",
|
|
4056
|
+
"55",
|
|
4057
|
+
"56",
|
|
4058
|
+
"57",
|
|
4059
|
+
"58",
|
|
4060
|
+
"60",
|
|
4061
|
+
"61",
|
|
4062
|
+
"62",
|
|
4063
|
+
"63",
|
|
4064
|
+
"64",
|
|
4065
|
+
"65",
|
|
4066
|
+
"66",
|
|
4067
|
+
"81",
|
|
4068
|
+
"82",
|
|
4069
|
+
"84",
|
|
4070
|
+
"86",
|
|
4071
|
+
"90",
|
|
4072
|
+
"91",
|
|
4073
|
+
"92",
|
|
4074
|
+
"93",
|
|
4075
|
+
"94",
|
|
4076
|
+
"95",
|
|
4077
|
+
"98",
|
|
4078
|
+
"211",
|
|
4079
|
+
"212",
|
|
4080
|
+
"213",
|
|
4081
|
+
"216",
|
|
4082
|
+
"218",
|
|
4083
|
+
"220",
|
|
4084
|
+
"221",
|
|
4085
|
+
"222",
|
|
4086
|
+
"223",
|
|
4087
|
+
"224",
|
|
4088
|
+
"225",
|
|
4089
|
+
"226",
|
|
4090
|
+
"227",
|
|
4091
|
+
"228",
|
|
4092
|
+
"229",
|
|
4093
|
+
"230",
|
|
4094
|
+
"231",
|
|
4095
|
+
"232",
|
|
4096
|
+
"233",
|
|
4097
|
+
"234",
|
|
4098
|
+
"235",
|
|
4099
|
+
"236",
|
|
4100
|
+
"237",
|
|
4101
|
+
"238",
|
|
4102
|
+
"239",
|
|
4103
|
+
"240",
|
|
4104
|
+
"241",
|
|
4105
|
+
"242",
|
|
4106
|
+
"243",
|
|
4107
|
+
"244",
|
|
4108
|
+
"245",
|
|
4109
|
+
"246",
|
|
4110
|
+
"247",
|
|
4111
|
+
"248",
|
|
4112
|
+
"249",
|
|
4113
|
+
"250",
|
|
4114
|
+
"251",
|
|
4115
|
+
"252",
|
|
4116
|
+
"253",
|
|
4117
|
+
"254",
|
|
4118
|
+
"255",
|
|
4119
|
+
"256",
|
|
4120
|
+
"257",
|
|
4121
|
+
"258",
|
|
4122
|
+
"260",
|
|
4123
|
+
"261",
|
|
4124
|
+
"262",
|
|
4125
|
+
"263",
|
|
4126
|
+
"264",
|
|
4127
|
+
"265",
|
|
4128
|
+
"266",
|
|
4129
|
+
"267",
|
|
4130
|
+
"268",
|
|
4131
|
+
"269",
|
|
4132
|
+
"290",
|
|
4133
|
+
"291",
|
|
4134
|
+
"297",
|
|
4135
|
+
"298",
|
|
4136
|
+
"299",
|
|
4137
|
+
"350",
|
|
4138
|
+
"351",
|
|
4139
|
+
"352",
|
|
4140
|
+
"353",
|
|
4141
|
+
"354",
|
|
4142
|
+
"355",
|
|
4143
|
+
"356",
|
|
4144
|
+
"357",
|
|
4145
|
+
"358",
|
|
4146
|
+
"359",
|
|
4147
|
+
"370",
|
|
4148
|
+
"371",
|
|
4149
|
+
"372",
|
|
4150
|
+
"373",
|
|
4151
|
+
"374",
|
|
4152
|
+
"375",
|
|
4153
|
+
"376",
|
|
4154
|
+
"377",
|
|
4155
|
+
"378",
|
|
4156
|
+
"379",
|
|
4157
|
+
"380",
|
|
4158
|
+
"381",
|
|
4159
|
+
"382",
|
|
4160
|
+
"383",
|
|
4161
|
+
"385",
|
|
4162
|
+
"386",
|
|
4163
|
+
"387",
|
|
4164
|
+
"389",
|
|
4165
|
+
"420",
|
|
4166
|
+
"421",
|
|
4167
|
+
"423",
|
|
4168
|
+
"500",
|
|
4169
|
+
"501",
|
|
4170
|
+
"502",
|
|
4171
|
+
"503",
|
|
4172
|
+
"504",
|
|
4173
|
+
"505",
|
|
4174
|
+
"506",
|
|
4175
|
+
"507",
|
|
4176
|
+
"508",
|
|
4177
|
+
"509",
|
|
4178
|
+
"590",
|
|
4179
|
+
"591",
|
|
4180
|
+
"592",
|
|
4181
|
+
"593",
|
|
4182
|
+
"594",
|
|
4183
|
+
"595",
|
|
4184
|
+
"596",
|
|
4185
|
+
"597",
|
|
4186
|
+
"598",
|
|
4187
|
+
"599",
|
|
4188
|
+
"670",
|
|
4189
|
+
"672",
|
|
4190
|
+
"673",
|
|
4191
|
+
"674",
|
|
4192
|
+
"675",
|
|
4193
|
+
"676",
|
|
4194
|
+
"677",
|
|
4195
|
+
"678",
|
|
4196
|
+
"679",
|
|
4197
|
+
"680",
|
|
4198
|
+
"681",
|
|
4199
|
+
"682",
|
|
4200
|
+
"683",
|
|
4201
|
+
"685",
|
|
4202
|
+
"686",
|
|
4203
|
+
"687",
|
|
4204
|
+
"688",
|
|
4205
|
+
"689",
|
|
4206
|
+
"690",
|
|
4207
|
+
"691",
|
|
4208
|
+
"692",
|
|
4209
|
+
"850",
|
|
4210
|
+
"852",
|
|
4211
|
+
"853",
|
|
4212
|
+
"855",
|
|
4213
|
+
"856",
|
|
4214
|
+
"880",
|
|
4215
|
+
"886",
|
|
4216
|
+
"960",
|
|
4217
|
+
"961",
|
|
4218
|
+
"962",
|
|
4219
|
+
"963",
|
|
4220
|
+
"964",
|
|
4221
|
+
"965",
|
|
4222
|
+
"966",
|
|
4223
|
+
"967",
|
|
4224
|
+
"968",
|
|
4225
|
+
"970",
|
|
4226
|
+
"971",
|
|
4227
|
+
"972",
|
|
4228
|
+
"973",
|
|
4229
|
+
"974",
|
|
4230
|
+
"975",
|
|
4231
|
+
"976",
|
|
4232
|
+
"977",
|
|
4233
|
+
"992",
|
|
4234
|
+
"993",
|
|
4235
|
+
"994",
|
|
4236
|
+
"995",
|
|
4237
|
+
"996",
|
|
4238
|
+
"998"
|
|
4239
|
+
]);
|
|
4240
|
+
var KEEPS_LEADING_ZERO = /* @__PURE__ */ new Set(["39", "378", "379"]);
|
|
4241
|
+
function normalizePhone(raw, country) {
|
|
4242
|
+
const text = raw.trim();
|
|
4243
|
+
if (REGISTRY_PHONE.test(text)) return text;
|
|
4244
|
+
const compact = text.replace(/\(0\)/g, "").replace(/[\s\-./()]/g, "");
|
|
4245
|
+
let international;
|
|
4246
|
+
if (/^\+\d+$/.test(compact)) international = compact.slice(1);
|
|
4247
|
+
else if (/^00\d+$/.test(compact)) international = compact.slice(2);
|
|
4248
|
+
else if (/^0\d+$/.test(compact)) {
|
|
4249
|
+
const code = country ? CALLING_CODE_OF_COUNTRY[country.trim().toUpperCase()] : void 0;
|
|
4250
|
+
if (!code) return raw;
|
|
4251
|
+
return `+${code}.${KEEPS_LEADING_ZERO.has(code) ? compact : compact.slice(1)}`;
|
|
4252
|
+
} else return raw;
|
|
4253
|
+
for (const length of [1, 2, 3]) {
|
|
4254
|
+
const code = international.slice(0, length);
|
|
4255
|
+
if (CALLING_CODES.has(code)) {
|
|
4256
|
+
const rest = international.slice(length);
|
|
4257
|
+
return `+${code}.${KEEPS_LEADING_ZERO.has(code) ? rest : rest.replace(/^0/, "")}`;
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
return raw;
|
|
4261
|
+
}
|
|
4262
|
+
|
|
4263
|
+
// src/domains.ts
|
|
4264
|
+
var DomainSearchQuery = z16.object({ q: z16.string().trim().min(1).max(63) });
|
|
4265
|
+
var DOMAIN_UNAVAILABLE_REASONS = ["taken", "extension_not_supported", "premium", "not_registrable"];
|
|
4266
|
+
var DomainUnavailableReason = z16.enum(DOMAIN_UNAVAILABLE_REASONS);
|
|
4267
|
+
var DomainOffer = z16.object({
|
|
4268
|
+
domain: z16.string(),
|
|
4269
|
+
available: z16.boolean(),
|
|
4270
|
+
reason: DomainUnavailableReason.nullable(),
|
|
4271
|
+
price_cents: z16.number().int().min(0).nullable(),
|
|
4272
|
+
renewal_price_cents: z16.number().int().min(0).nullable(),
|
|
4273
|
+
currency: z16.literal("EUR")
|
|
4274
|
+
});
|
|
4275
|
+
var DOMAIN_BUYING_BLOCKS = ["not_configured", "paid_plan_required", "no_company"];
|
|
4276
|
+
var DomainBuyingBlock = z16.enum(DOMAIN_BUYING_BLOCKS);
|
|
4277
|
+
var DomainSearchResult = z16.object({
|
|
4278
|
+
data: z16.array(DomainOffer),
|
|
4279
|
+
blocked: DomainBuyingBlock.nullable()
|
|
4280
|
+
});
|
|
4281
|
+
var DomainRegistrant = z16.object({
|
|
4282
|
+
name: z16.string().trim().min(3).max(120).regex(/\S+\s+\S+/, "must be a first and a last name"),
|
|
4283
|
+
organization: z16.string().trim().min(1).max(120).nullable().optional(),
|
|
4284
|
+
email: Email,
|
|
4285
|
+
phone: z16.string().trim().min(1).max(40),
|
|
4286
|
+
street: z16.string().trim().min(3).max(200),
|
|
4287
|
+
city: z16.string().trim().min(1).max(100),
|
|
4288
|
+
state: z16.string().trim().min(1).max(100),
|
|
4289
|
+
postal_code: z16.string().trim().min(2).max(20),
|
|
4290
|
+
country_code: z16.string().trim().toUpperCase().regex(/^[A-Z]{2}$/, "must be a two-letter country code such as DE")
|
|
4291
|
+
}).superRefine((holder, ctx) => {
|
|
4292
|
+
if (typeof holder.phone === "string" && !REGISTRY_PHONE.test(normalizePhone(holder.phone, holder.country_code))) {
|
|
4293
|
+
ctx.addIssue({ code: z16.ZodIssueCode.custom, path: ["phone"], message: "must be a phone number with its country code, such as +49 30 1234 5678" });
|
|
4294
|
+
}
|
|
4295
|
+
}).transform((holder) => ({ ...holder, phone: normalizePhone(holder.phone, holder.country_code) }));
|
|
4296
|
+
var MAX_DOMAIN_ORDERS_PER_DAY = 2;
|
|
4297
|
+
var DOMAIN_ORDER_KINDS = ["sending", "domain_only"];
|
|
4298
|
+
var DomainOrderKind = z16.enum(DOMAIN_ORDER_KINDS);
|
|
4299
|
+
var DomainOrderCreate = z16.object({
|
|
4300
|
+
domain: SendingDomainName,
|
|
4301
|
+
price_cents: z16.number().int().min(0),
|
|
4302
|
+
registrant: DomainRegistrant,
|
|
4303
|
+
kind: DomainOrderKind.default("sending"),
|
|
4304
|
+
from_name: z16.string().trim().min(1).max(120).optional(),
|
|
4305
|
+
from_local_part: z16.string().trim().toLowerCase().regex(/^[a-z0-9](?:[a-z0-9._+-]{0,62}[a-z0-9])?$/, "must be the part before the @, such as hello").optional(),
|
|
4306
|
+
/**
|
|
4307
|
+
* Where Stripe returns to after paying, and after leaving the payment. The
|
|
4308
|
+
* service adds `domain_order=<order id>` to both, so the page coming back
|
|
4309
|
+
* knows which order to show (and read: `domainOrders.get` confirms a
|
|
4310
|
+
* payment at once, before Stripe's webhook arrives).
|
|
4311
|
+
*/
|
|
4312
|
+
success_url: z16.string().url(),
|
|
4313
|
+
cancel_url: z16.string().url(),
|
|
4314
|
+
/** The buyer accepted the terms of service (which cover bought domains) of this version. */
|
|
4315
|
+
accept_terms: AcceptTerms
|
|
4316
|
+
}).superRefine((order, ctx) => {
|
|
4317
|
+
if (order.kind !== "sending") return;
|
|
4318
|
+
if (!order.from_name) ctx.addIssue({ code: z16.ZodIssueCode.custom, path: ["from_name"], message: "is needed for a domain mail is sent from" });
|
|
4319
|
+
if (!order.from_local_part) ctx.addIssue({ code: z16.ZodIssueCode.custom, path: ["from_local_part"], message: "is needed for a domain mail is sent from" });
|
|
4320
|
+
});
|
|
4321
|
+
var DOMAIN_ORDER_STATES = [
|
|
4322
|
+
"awaiting_payment",
|
|
4323
|
+
"paid",
|
|
4324
|
+
"registering",
|
|
4325
|
+
"setting_up",
|
|
4326
|
+
"ready",
|
|
4327
|
+
"needs_attention",
|
|
4328
|
+
"refunded",
|
|
4329
|
+
"cancelled"
|
|
4330
|
+
];
|
|
4331
|
+
var DomainOrderState = z16.enum(DOMAIN_ORDER_STATES);
|
|
4332
|
+
var DomainOrder = z16.object({
|
|
4333
|
+
id: Id,
|
|
4334
|
+
domain: z16.string(),
|
|
4335
|
+
state: DomainOrderState,
|
|
4336
|
+
price_cents: z16.number().int().min(0),
|
|
4337
|
+
renewal_price_cents: z16.number().int().min(0),
|
|
4338
|
+
currency: z16.literal("EUR"),
|
|
4339
|
+
/** Stripe's payment page while `awaiting_payment`; null otherwise. */
|
|
4340
|
+
checkout_url: z16.string().url().nullable(),
|
|
4341
|
+
registrant_name: z16.string(),
|
|
4342
|
+
kind: DomainOrderKind,
|
|
4343
|
+
/** The sender, for a `sending` order; null for `domain_only`. */
|
|
4344
|
+
from_name: z16.string().nullable(),
|
|
4345
|
+
from_email: Email.nullable(),
|
|
4346
|
+
/** The sending domain once `ready`. */
|
|
4347
|
+
sending_domain_id: Id.nullable(),
|
|
4348
|
+
/** When the paid year ends, once registered. */
|
|
4349
|
+
expires_at: Timestamp.nullable(),
|
|
4350
|
+
/** What went wrong, for `needs_attention` and `refunded`; null otherwise. */
|
|
4351
|
+
last_error: z16.string().nullable(),
|
|
4352
|
+
paid_at: Timestamp.nullable(),
|
|
4353
|
+
registered_at: Timestamp.nullable(),
|
|
4354
|
+
created_at: Timestamp,
|
|
4355
|
+
updated_at: Timestamp
|
|
4356
|
+
});
|
|
4357
|
+
|
|
4358
|
+
// src/contacts.ts
|
|
4359
|
+
import { z as z17 } from "zod";
|
|
4360
|
+
var Topic = z17.object({
|
|
3967
4361
|
id: Id,
|
|
3968
4362
|
slug: Slug,
|
|
3969
|
-
name:
|
|
4363
|
+
name: z17.string().min(1).max(120),
|
|
3970
4364
|
/** Shown on the hosted preference page. */
|
|
3971
|
-
description:
|
|
4365
|
+
description: z17.string().max(1e3).nullable(),
|
|
3972
4366
|
/** Translations of `name` and `description` per locale, for the hosted page. */
|
|
3973
|
-
translations:
|
|
3974
|
-
|
|
4367
|
+
translations: z17.record(
|
|
4368
|
+
z17.object({ name: z17.string().min(1).max(120), description: z17.string().max(1e3).nullable() })
|
|
3975
4369
|
),
|
|
3976
4370
|
created_at: Timestamp,
|
|
3977
4371
|
updated_at: Timestamp
|
|
3978
4372
|
});
|
|
3979
|
-
var TopicCreate =
|
|
4373
|
+
var TopicCreate = z17.object({
|
|
3980
4374
|
slug: Slug,
|
|
3981
|
-
name:
|
|
3982
|
-
description:
|
|
4375
|
+
name: z17.string().min(1).max(120),
|
|
4376
|
+
description: z17.string().max(1e3).optional(),
|
|
3983
4377
|
translations: Topic.shape.translations.optional()
|
|
3984
4378
|
});
|
|
3985
4379
|
var TopicUpdate = TopicCreate.omit({ slug: true }).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
|
|
3986
|
-
var Contact =
|
|
4380
|
+
var Contact = z17.object({
|
|
3987
4381
|
id: Id,
|
|
3988
|
-
external_id:
|
|
4382
|
+
external_id: z17.string().min(1).max(255).nullable(),
|
|
3989
4383
|
/** Stored lowercased, unique per workspace. */
|
|
3990
4384
|
email: Email,
|
|
3991
|
-
first_name:
|
|
3992
|
-
last_name:
|
|
3993
|
-
locale:
|
|
4385
|
+
first_name: z17.string().max(200).nullable(),
|
|
4386
|
+
last_name: z17.string().max(200).nullable(),
|
|
4387
|
+
locale: z17.string().min(2).max(35).nullable(),
|
|
3994
4388
|
/**
|
|
3995
4389
|
* The person's own time zone, an IANA name such as `Europe/Berlin` (A1).
|
|
3996
4390
|
* Every wall clock an automation waits for is read in it, falling back to the
|
|
@@ -3998,65 +4392,65 @@ var Contact = z16.object({
|
|
|
3998
4392
|
*/
|
|
3999
4393
|
timezone: TimezoneName.nullable(),
|
|
4000
4394
|
properties: Properties,
|
|
4001
|
-
topics:
|
|
4395
|
+
topics: z17.array(Slug),
|
|
4002
4396
|
/** The slugs of the contact's tags (S4). */
|
|
4003
|
-
tags:
|
|
4397
|
+
tags: z17.array(Slug),
|
|
4004
4398
|
created_at: Timestamp,
|
|
4005
4399
|
updated_at: Timestamp
|
|
4006
4400
|
});
|
|
4007
|
-
var ContactUpsert =
|
|
4008
|
-
external_id:
|
|
4401
|
+
var ContactUpsert = z17.object({
|
|
4402
|
+
external_id: z17.string().min(1).max(255).optional(),
|
|
4009
4403
|
email: Email.optional(),
|
|
4010
|
-
first_name:
|
|
4011
|
-
last_name:
|
|
4012
|
-
locale:
|
|
4404
|
+
first_name: z17.string().max(200).nullable().optional(),
|
|
4405
|
+
last_name: z17.string().max(200).nullable().optional(),
|
|
4406
|
+
locale: z17.string().min(2).max(35).nullable().optional(),
|
|
4013
4407
|
timezone: TimezoneName.nullable().optional(),
|
|
4014
4408
|
properties: Properties.optional(),
|
|
4015
|
-
topics:
|
|
4409
|
+
topics: z17.array(Slug).max(100).optional()
|
|
4016
4410
|
}).refine((v) => v.external_id !== void 0 || v.email !== void 0, {
|
|
4017
4411
|
message: "external_id or email is required",
|
|
4018
4412
|
path: ["email"]
|
|
4019
4413
|
});
|
|
4020
|
-
var ContactUpsertResult =
|
|
4414
|
+
var ContactUpsertResult = z17.object({
|
|
4021
4415
|
contact: Contact,
|
|
4022
|
-
created:
|
|
4416
|
+
created: z17.boolean()
|
|
4023
4417
|
});
|
|
4024
4418
|
var ContactListQuery = PageQuery.extend({
|
|
4025
|
-
email:
|
|
4026
|
-
external_id:
|
|
4419
|
+
email: z17.string().min(1).max(254).optional(),
|
|
4420
|
+
external_id: z17.string().min(1).max(255).optional(),
|
|
4027
4421
|
topic: Slug.optional()
|
|
4028
4422
|
});
|
|
4029
|
-
var ContactErased =
|
|
4030
|
-
ok:
|
|
4031
|
-
erased_messages:
|
|
4032
|
-
erased_recipients:
|
|
4033
|
-
suppressions_kept:
|
|
4423
|
+
var ContactErased = z17.object({
|
|
4424
|
+
ok: z17.literal(true),
|
|
4425
|
+
erased_messages: z17.number().int().min(0),
|
|
4426
|
+
erased_recipients: z17.number().int().min(0),
|
|
4427
|
+
suppressions_kept: z17.number().int().min(0)
|
|
4034
4428
|
});
|
|
4035
4429
|
var SUPPRESSION_REASONS = ["unsubscribed", "bounced", "complained", "manual"];
|
|
4036
|
-
var SuppressionReason =
|
|
4037
|
-
var Suppression =
|
|
4430
|
+
var SuppressionReason = z17.enum(SUPPRESSION_REASONS);
|
|
4431
|
+
var Suppression = z17.object({
|
|
4038
4432
|
id: Id,
|
|
4039
4433
|
email: Email,
|
|
4040
4434
|
reason: SuppressionReason,
|
|
4041
4435
|
topic: Slug.nullable(),
|
|
4042
4436
|
source_message_id: Id.nullable(),
|
|
4043
|
-
note:
|
|
4437
|
+
note: z17.string().max(1e3).nullable(),
|
|
4044
4438
|
created_at: Timestamp
|
|
4045
4439
|
});
|
|
4046
|
-
var SuppressionCreate =
|
|
4440
|
+
var SuppressionCreate = z17.object({
|
|
4047
4441
|
email: Email,
|
|
4048
|
-
reason:
|
|
4442
|
+
reason: z17.enum(["manual", "unsubscribed"]),
|
|
4049
4443
|
topic: Slug.nullable().optional(),
|
|
4050
|
-
note:
|
|
4444
|
+
note: z17.string().max(1e3).optional()
|
|
4051
4445
|
});
|
|
4052
4446
|
var SuppressionListQuery = PageQuery.extend({
|
|
4053
|
-
email:
|
|
4447
|
+
email: z17.string().min(1).max(254).optional(),
|
|
4054
4448
|
reason: SuppressionReason.optional(),
|
|
4055
4449
|
topic: Slug.optional()
|
|
4056
4450
|
});
|
|
4057
4451
|
|
|
4058
4452
|
// src/webhooks.ts
|
|
4059
|
-
import { z as
|
|
4453
|
+
import { z as z18 } from "zod";
|
|
4060
4454
|
var WEBHOOK_EVENT_TYPES = [
|
|
4061
4455
|
"message.sent",
|
|
4062
4456
|
"message.failed",
|
|
@@ -4100,23 +4494,23 @@ var WEBHOOK_EVENT_TYPES = [
|
|
|
4100
4494
|
"template.updated",
|
|
4101
4495
|
"template.deleted"
|
|
4102
4496
|
];
|
|
4103
|
-
var WebhookEventType =
|
|
4104
|
-
var MessageEventBase =
|
|
4497
|
+
var WebhookEventType = z18.enum(WEBHOOK_EVENT_TYPES);
|
|
4498
|
+
var MessageEventBase = z18.object({
|
|
4105
4499
|
message_id: Id,
|
|
4106
4500
|
mailing_id: Id.nullable(),
|
|
4107
4501
|
mailing_metadata: MailingMetadata.nullable(),
|
|
4108
4502
|
recipient_id: Id.nullable(),
|
|
4109
4503
|
contact_id: Id.nullable(),
|
|
4110
|
-
external_id:
|
|
4504
|
+
external_id: z18.string().nullable(),
|
|
4111
4505
|
email: Email,
|
|
4112
|
-
subject:
|
|
4506
|
+
subject: z18.string(),
|
|
4113
4507
|
topic: Slug.nullable(),
|
|
4114
|
-
provider_message_id:
|
|
4115
|
-
is_test:
|
|
4508
|
+
provider_message_id: z18.string().nullable(),
|
|
4509
|
+
is_test: z18.boolean()
|
|
4116
4510
|
});
|
|
4117
4511
|
var MessageSentData = MessageEventBase.extend({
|
|
4118
4512
|
/** The final HTML as sent, so the client can archive it beside its own records. */
|
|
4119
|
-
html:
|
|
4513
|
+
html: z18.string(),
|
|
4120
4514
|
sent_at: Timestamp,
|
|
4121
4515
|
/**
|
|
4122
4516
|
* The choice each insertion made (see `Message.insertions`); absent or null
|
|
@@ -4127,20 +4521,20 @@ var MessageSentData = MessageEventBase.extend({
|
|
|
4127
4521
|
insertions: InsertionChoices.nullish()
|
|
4128
4522
|
});
|
|
4129
4523
|
var MessageFailedData = MessageEventBase.extend({
|
|
4130
|
-
error:
|
|
4524
|
+
error: z18.string(),
|
|
4131
4525
|
/** False when the provider rejected permanently; the recipient will not be retried. */
|
|
4132
|
-
retryable:
|
|
4526
|
+
retryable: z18.boolean(),
|
|
4133
4527
|
failed_at: Timestamp
|
|
4134
4528
|
});
|
|
4135
4529
|
var UNSUBSCRIBE_SOURCES = ["hosted_page", "one_click", "api", "dashboard", "signup_form"];
|
|
4136
|
-
var ContactUnsubscribedData =
|
|
4530
|
+
var ContactUnsubscribedData = z18.object({
|
|
4137
4531
|
contact_id: Id.nullable(),
|
|
4138
|
-
external_id:
|
|
4532
|
+
external_id: z18.string().nullable(),
|
|
4139
4533
|
email: Email,
|
|
4140
4534
|
/** The topic unsubscribed from; null means every topic. */
|
|
4141
4535
|
topic: Slug.nullable(),
|
|
4142
4536
|
mailing_id: Id.nullable(),
|
|
4143
|
-
source:
|
|
4537
|
+
source: z18.enum(UNSUBSCRIBE_SOURCES),
|
|
4144
4538
|
unsubscribed_at: Timestamp
|
|
4145
4539
|
});
|
|
4146
4540
|
var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: true }).extend({
|
|
@@ -4149,142 +4543,142 @@ var ContactResubscribedData = ContactUnsubscribedData.omit({ unsubscribed_at: tr
|
|
|
4149
4543
|
* breaker undid a `bounced` block it judged false (a `contact.bounced` for the
|
|
4150
4544
|
* same address and mailing went out before); `topic` is null.
|
|
4151
4545
|
*/
|
|
4152
|
-
source:
|
|
4546
|
+
source: z18.enum([...UNSUBSCRIBE_SOURCES, "bounce_reverted"]),
|
|
4153
4547
|
resubscribed_at: Timestamp
|
|
4154
4548
|
});
|
|
4155
|
-
var ContactBouncedData =
|
|
4549
|
+
var ContactBouncedData = z18.object({
|
|
4156
4550
|
contact_id: Id.nullable(),
|
|
4157
|
-
external_id:
|
|
4551
|
+
external_id: z18.string().nullable(),
|
|
4158
4552
|
email: Email,
|
|
4159
4553
|
/** `bounced` for a hard bounce, `complained` for a spam complaint. */
|
|
4160
|
-
reason:
|
|
4554
|
+
reason: z18.enum(["bounced", "complained"]),
|
|
4161
4555
|
message_id: Id.nullable(),
|
|
4162
|
-
diagnostic:
|
|
4556
|
+
diagnostic: z18.string().nullable(),
|
|
4163
4557
|
bounced_at: Timestamp
|
|
4164
4558
|
});
|
|
4165
|
-
var MailingFinishedData =
|
|
4559
|
+
var MailingFinishedData = z18.object({
|
|
4166
4560
|
mailing_id: Id,
|
|
4167
4561
|
mailing_metadata: MailingMetadata,
|
|
4168
|
-
status:
|
|
4562
|
+
status: z18.enum(["sent", "partially_failed", "cancelled"]),
|
|
4169
4563
|
counts: MailingCounts,
|
|
4170
4564
|
finished_at: Timestamp
|
|
4171
4565
|
});
|
|
4172
|
-
var ContactSubscribedData =
|
|
4566
|
+
var ContactSubscribedData = z18.object({
|
|
4173
4567
|
contact_id: Id,
|
|
4174
|
-
external_id:
|
|
4568
|
+
external_id: z18.string().nullable(),
|
|
4175
4569
|
email: Email,
|
|
4176
|
-
topics:
|
|
4177
|
-
source:
|
|
4570
|
+
topics: z18.array(Slug),
|
|
4571
|
+
source: z18.enum(["signup_form", "api", "dashboard", "automation"]),
|
|
4178
4572
|
signup_form_id: Id.nullable(),
|
|
4179
|
-
signup_form_version:
|
|
4573
|
+
signup_form_version: z18.number().int().min(1).nullable(),
|
|
4180
4574
|
subscribed_at: Timestamp
|
|
4181
4575
|
});
|
|
4182
|
-
var ImportFinishedData =
|
|
4576
|
+
var ImportFinishedData = z18.object({
|
|
4183
4577
|
import_id: Id,
|
|
4184
|
-
status:
|
|
4578
|
+
status: z18.enum(["completed", "cancelled", "failed"]),
|
|
4185
4579
|
result: ImportReport.nullable(),
|
|
4186
|
-
error:
|
|
4580
|
+
error: z18.string().nullable(),
|
|
4187
4581
|
finished_at: Timestamp
|
|
4188
4582
|
});
|
|
4189
|
-
var MailingScheduledData =
|
|
4583
|
+
var MailingScheduledData = z18.object({
|
|
4190
4584
|
mailing_id: Id,
|
|
4191
4585
|
mailing_metadata: MailingMetadata,
|
|
4192
4586
|
scheduled_at: Timestamp.nullable()
|
|
4193
4587
|
});
|
|
4194
|
-
var MailingStartedData =
|
|
4588
|
+
var MailingStartedData = z18.object({
|
|
4195
4589
|
mailing_id: Id,
|
|
4196
4590
|
mailing_metadata: MailingMetadata,
|
|
4197
|
-
trigger:
|
|
4198
|
-
recipients:
|
|
4591
|
+
trigger: z18.enum(["send", "schedule"]),
|
|
4592
|
+
recipients: z18.number().int().min(0),
|
|
4199
4593
|
started_at: Timestamp
|
|
4200
4594
|
});
|
|
4201
|
-
var MailingScheduleFailedData =
|
|
4595
|
+
var MailingScheduleFailedData = z18.object({
|
|
4202
4596
|
mailing_id: Id,
|
|
4203
4597
|
mailing_metadata: MailingMetadata,
|
|
4204
|
-
code:
|
|
4205
|
-
message:
|
|
4598
|
+
code: z18.string(),
|
|
4599
|
+
message: z18.string(),
|
|
4206
4600
|
failed_at: Timestamp
|
|
4207
4601
|
});
|
|
4208
|
-
var MailingAbWinnerSelectedData =
|
|
4602
|
+
var MailingAbWinnerSelectedData = z18.object({
|
|
4209
4603
|
mailing_id: Id,
|
|
4210
4604
|
mailing_metadata: MailingMetadata,
|
|
4211
|
-
winner:
|
|
4212
|
-
decided_by:
|
|
4213
|
-
variants:
|
|
4605
|
+
winner: z18.string(),
|
|
4606
|
+
decided_by: z18.enum(["metric", "manual"]),
|
|
4607
|
+
variants: z18.array(VariantAnalytics),
|
|
4214
4608
|
decided_at: Timestamp
|
|
4215
4609
|
});
|
|
4216
|
-
var ContactTaggedData =
|
|
4610
|
+
var ContactTaggedData = z18.object({
|
|
4217
4611
|
contact_id: Id,
|
|
4218
|
-
external_id:
|
|
4612
|
+
external_id: z18.string().nullable(),
|
|
4219
4613
|
email: Email,
|
|
4220
4614
|
/** Only the tags the contact did not already have. */
|
|
4221
|
-
tags:
|
|
4222
|
-
source:
|
|
4615
|
+
tags: z18.array(Slug).min(1),
|
|
4616
|
+
source: z18.enum(["api", "dashboard", "signup_form", "import", "automation"]),
|
|
4223
4617
|
tagged_at: Timestamp
|
|
4224
4618
|
});
|
|
4225
|
-
var ContactUpdatedData =
|
|
4619
|
+
var ContactUpdatedData = z18.object({
|
|
4226
4620
|
contact_id: Id,
|
|
4227
|
-
external_id:
|
|
4621
|
+
external_id: z18.string().nullable(),
|
|
4228
4622
|
email: Email,
|
|
4229
|
-
changed:
|
|
4623
|
+
changed: z18.array(z18.string()).min(1),
|
|
4230
4624
|
properties: Properties,
|
|
4231
|
-
source:
|
|
4625
|
+
source: z18.enum(["api", "dashboard", "signup_form", "import", "automation"]),
|
|
4232
4626
|
updated_at: Timestamp
|
|
4233
4627
|
});
|
|
4234
|
-
var AutomationRunEventBase =
|
|
4628
|
+
var AutomationRunEventBase = z18.object({
|
|
4235
4629
|
automation_id: Id,
|
|
4236
|
-
automation_name:
|
|
4630
|
+
automation_name: z18.string(),
|
|
4237
4631
|
run_id: Id,
|
|
4238
|
-
version:
|
|
4632
|
+
version: z18.number().int().min(1),
|
|
4239
4633
|
contact_id: Id,
|
|
4240
|
-
external_id:
|
|
4634
|
+
external_id: z18.string().nullable(),
|
|
4241
4635
|
email: Email
|
|
4242
4636
|
});
|
|
4243
4637
|
var AutomationRunStartedData = AutomationRunEventBase.extend({
|
|
4244
4638
|
/** What let them in: a trigger kind, or `manual` for an explicit enrolment. */
|
|
4245
|
-
trigger_kind:
|
|
4639
|
+
trigger_kind: z18.string(),
|
|
4246
4640
|
entered_at: Timestamp
|
|
4247
4641
|
});
|
|
4248
4642
|
var AutomationRunCompletedData = AutomationRunEventBase.extend({
|
|
4249
|
-
last_step_id:
|
|
4643
|
+
last_step_id: z18.string().nullable(),
|
|
4250
4644
|
completed_at: Timestamp
|
|
4251
4645
|
});
|
|
4252
4646
|
var AutomationRunExitedData = AutomationRunEventBase.extend({
|
|
4253
4647
|
reason: AutomationEndReason,
|
|
4254
|
-
step_id:
|
|
4648
|
+
step_id: z18.string().nullable(),
|
|
4255
4649
|
exited_at: Timestamp
|
|
4256
4650
|
});
|
|
4257
4651
|
var AutomationRunFailedData = AutomationRunEventBase.extend({
|
|
4258
|
-
reason:
|
|
4259
|
-
step_id:
|
|
4652
|
+
reason: z18.string(),
|
|
4653
|
+
step_id: z18.string().nullable(),
|
|
4260
4654
|
failed_at: Timestamp
|
|
4261
4655
|
});
|
|
4262
4656
|
var AutomationWebhookData = AutomationRunEventBase.extend({
|
|
4263
|
-
step_id:
|
|
4657
|
+
step_id: z18.string(),
|
|
4264
4658
|
/** The step's own label, when it was given one, so a receiver can branch on a name. */
|
|
4265
|
-
step_label:
|
|
4659
|
+
step_label: z18.string().nullable(),
|
|
4266
4660
|
/** Whatever the step carries, verbatim. Null when it carries nothing. */
|
|
4267
4661
|
payload: JsonValue.nullable(),
|
|
4268
4662
|
fired_at: Timestamp
|
|
4269
4663
|
});
|
|
4270
|
-
var TemplateEventBase =
|
|
4664
|
+
var TemplateEventBase = z18.object({
|
|
4271
4665
|
template_id: Id,
|
|
4272
|
-
name:
|
|
4273
|
-
version:
|
|
4274
|
-
source:
|
|
4666
|
+
name: z18.string().min(1).max(200),
|
|
4667
|
+
version: z18.number().int().min(1),
|
|
4668
|
+
source: z18.enum(["api", "dashboard", "mjml_import"])
|
|
4275
4669
|
});
|
|
4276
4670
|
var TemplateCreatedData = TemplateEventBase.extend({ created_at: Timestamp });
|
|
4277
|
-
var TemplateUpdatedData = TemplateEventBase.extend({ archived:
|
|
4671
|
+
var TemplateUpdatedData = TemplateEventBase.extend({ archived: z18.boolean(), updated_at: Timestamp });
|
|
4278
4672
|
var TemplateDeletedData = TemplateEventBase.extend({ deleted_at: Timestamp });
|
|
4279
|
-
var envelope = (type, data) =>
|
|
4673
|
+
var envelope = (type, data) => z18.object({
|
|
4280
4674
|
/** Unique per event: a receiver deduplicates on it (deliveries may repeat). */
|
|
4281
4675
|
id: Id,
|
|
4282
|
-
type:
|
|
4676
|
+
type: z18.literal(type),
|
|
4283
4677
|
created_at: Timestamp,
|
|
4284
4678
|
workspace_id: Id,
|
|
4285
4679
|
data
|
|
4286
4680
|
});
|
|
4287
|
-
var WebhookEvent =
|
|
4681
|
+
var WebhookEvent = z18.discriminatedUnion("type", [
|
|
4288
4682
|
envelope("message.sent", MessageSentData),
|
|
4289
4683
|
envelope("message.failed", MessageFailedData),
|
|
4290
4684
|
envelope("contact.unsubscribed", ContactUnsubscribedData),
|
|
@@ -4308,16 +4702,16 @@ var WebhookEvent = z17.discriminatedUnion("type", [
|
|
|
4308
4702
|
envelope("template.updated", TemplateUpdatedData),
|
|
4309
4703
|
envelope("template.deleted", TemplateDeletedData)
|
|
4310
4704
|
]);
|
|
4311
|
-
var WebhookEndpoint =
|
|
4705
|
+
var WebhookEndpoint = z18.object({
|
|
4312
4706
|
id: Id,
|
|
4313
|
-
url:
|
|
4314
|
-
description:
|
|
4315
|
-
events:
|
|
4316
|
-
enabled:
|
|
4707
|
+
url: z18.string().url(),
|
|
4708
|
+
description: z18.string().max(500).nullable(),
|
|
4709
|
+
events: z18.array(WebhookEventType).min(1),
|
|
4710
|
+
enabled: z18.boolean(),
|
|
4317
4711
|
created_at: Timestamp,
|
|
4318
4712
|
updated_at: Timestamp
|
|
4319
4713
|
});
|
|
4320
|
-
var WebhookUrl =
|
|
4714
|
+
var WebhookUrl = z18.string().url().refine((u) => {
|
|
4321
4715
|
try {
|
|
4322
4716
|
const url = new URL(u);
|
|
4323
4717
|
if (url.protocol === "https:") return true;
|
|
@@ -4326,35 +4720,35 @@ var WebhookUrl = z17.string().url().refine((u) => {
|
|
|
4326
4720
|
return false;
|
|
4327
4721
|
}
|
|
4328
4722
|
}, "must be https (http only for localhost)");
|
|
4329
|
-
var WebhookEndpointCreate =
|
|
4723
|
+
var WebhookEndpointCreate = z18.object({
|
|
4330
4724
|
url: WebhookUrl,
|
|
4331
|
-
description:
|
|
4332
|
-
events:
|
|
4333
|
-
enabled:
|
|
4725
|
+
description: z18.string().max(500).optional(),
|
|
4726
|
+
events: z18.array(WebhookEventType).min(1),
|
|
4727
|
+
enabled: z18.boolean().optional()
|
|
4334
4728
|
});
|
|
4335
|
-
var WebhookEndpointUpdate =
|
|
4729
|
+
var WebhookEndpointUpdate = z18.object({
|
|
4336
4730
|
url: WebhookUrl,
|
|
4337
|
-
description:
|
|
4338
|
-
events:
|
|
4339
|
-
enabled:
|
|
4731
|
+
description: z18.string().max(500).nullable(),
|
|
4732
|
+
events: z18.array(WebhookEventType).min(1),
|
|
4733
|
+
enabled: z18.boolean()
|
|
4340
4734
|
}).partial().refine((v) => Object.keys(v).length > 0, "at least one field");
|
|
4341
|
-
var WebhookEndpointWithSecret =
|
|
4735
|
+
var WebhookEndpointWithSecret = z18.object({
|
|
4342
4736
|
endpoint: WebhookEndpoint,
|
|
4343
|
-
secret:
|
|
4737
|
+
secret: z18.string().min(32)
|
|
4344
4738
|
});
|
|
4345
4739
|
var WEBHOOK_DELIVERY_STATUSES = ["pending", "succeeded", "failed"];
|
|
4346
|
-
var WebhookDeliveryStatus =
|
|
4740
|
+
var WebhookDeliveryStatus = z18.enum(WEBHOOK_DELIVERY_STATUSES);
|
|
4347
4741
|
var WEBHOOK_MAX_ATTEMPTS = 8;
|
|
4348
4742
|
var WEBHOOK_RETRY_DELAYS_SECONDS = [30, 120, 600, 1800, 3600, 7200, 21600];
|
|
4349
|
-
var WebhookDelivery =
|
|
4743
|
+
var WebhookDelivery = z18.object({
|
|
4350
4744
|
id: Id,
|
|
4351
4745
|
endpoint_id: Id,
|
|
4352
4746
|
event_id: Id,
|
|
4353
4747
|
event_type: WebhookEventType,
|
|
4354
4748
|
status: WebhookDeliveryStatus,
|
|
4355
|
-
attempts:
|
|
4356
|
-
last_status_code:
|
|
4357
|
-
last_error:
|
|
4749
|
+
attempts: z18.number().int().min(0),
|
|
4750
|
+
last_status_code: z18.number().int().min(100).max(599).nullable(),
|
|
4751
|
+
last_error: z18.string().nullable(),
|
|
4358
4752
|
next_attempt_at: Timestamp.nullable(),
|
|
4359
4753
|
delivered_at: Timestamp.nullable(),
|
|
4360
4754
|
created_at: Timestamp
|
|
@@ -4363,7 +4757,7 @@ var WebhookDeliveryListQuery = PageQuery.extend({
|
|
|
4363
4757
|
status: WebhookDeliveryStatus.optional(),
|
|
4364
4758
|
event_type: WebhookEventType.optional()
|
|
4365
4759
|
});
|
|
4366
|
-
var WebhookDeliveryParams =
|
|
4760
|
+
var WebhookDeliveryParams = z18.object({ id: Id, delivery_id: Id });
|
|
4367
4761
|
|
|
4368
4762
|
// src/webhook-signing.ts
|
|
4369
4763
|
var WEBHOOK_SIGNATURE_HEADER = "x-mail-signature";
|
|
@@ -4430,99 +4824,99 @@ async function verifyWebhook(input) {
|
|
|
4430
4824
|
}
|
|
4431
4825
|
|
|
4432
4826
|
// src/billing.ts
|
|
4433
|
-
import { z as
|
|
4827
|
+
import { z as z19 } from "zod";
|
|
4434
4828
|
var PLAN_IDS = ["free", "starter", "growth", "design_partner"];
|
|
4435
|
-
var PlanId =
|
|
4436
|
-
var PlanLimits =
|
|
4437
|
-
monthly_messages:
|
|
4438
|
-
contacts:
|
|
4439
|
-
members:
|
|
4440
|
-
providers:
|
|
4441
|
-
webhook_endpoints:
|
|
4829
|
+
var PlanId = z19.enum(PLAN_IDS);
|
|
4830
|
+
var PlanLimits = z19.object({
|
|
4831
|
+
monthly_messages: z19.number().int().min(0).nullable(),
|
|
4832
|
+
contacts: z19.number().int().min(0).nullable(),
|
|
4833
|
+
members: z19.number().int().min(1).nullable(),
|
|
4834
|
+
providers: z19.number().int().min(1).nullable(),
|
|
4835
|
+
webhook_endpoints: z19.number().int().min(0).nullable(),
|
|
4442
4836
|
/** Automations that may be live (active or paused) at once (A1). */
|
|
4443
|
-
active_automations:
|
|
4837
|
+
active_automations: z19.number().int().min(0).nullable(),
|
|
4444
4838
|
/** Steps one automation may hold. Null is the flow's own cap, not unlimited. */
|
|
4445
|
-
automation_steps:
|
|
4839
|
+
automation_steps: z19.number().int().min(1).nullable(),
|
|
4446
4840
|
/** Own domains Lumitra Mail sends from (managed sending domains); 0 when the plan has none. */
|
|
4447
|
-
sending_domains:
|
|
4841
|
+
sending_domains: z19.number().int().min(0).nullable()
|
|
4448
4842
|
});
|
|
4449
|
-
var PlanFeatures =
|
|
4843
|
+
var PlanFeatures = z19.object({
|
|
4450
4844
|
/** A/B tests of subject and content on a mailing (S4). */
|
|
4451
|
-
ab_testing:
|
|
4845
|
+
ab_testing: z19.boolean(),
|
|
4452
4846
|
/** Open and click tracking, still off until a workspace turns it on (`settings.tracking_enabled`). */
|
|
4453
|
-
tracking:
|
|
4847
|
+
tracking: z19.boolean(),
|
|
4454
4848
|
/** Automations: flows a person walks through step by step (A1). */
|
|
4455
|
-
automations:
|
|
4849
|
+
automations: z19.boolean()
|
|
4456
4850
|
});
|
|
4457
4851
|
var PLAN_FEATURES = ["ab_testing", "tracking", "automations"];
|
|
4458
|
-
var Plan =
|
|
4852
|
+
var Plan = z19.object({
|
|
4459
4853
|
id: PlanId,
|
|
4460
|
-
name:
|
|
4854
|
+
name: z19.string().min(1),
|
|
4461
4855
|
/** Price in the smallest currency unit per month; null for plans not sold. */
|
|
4462
|
-
monthly_price_cents:
|
|
4463
|
-
currency:
|
|
4856
|
+
monthly_price_cents: z19.number().int().min(0).nullable(),
|
|
4857
|
+
currency: z19.string().length(3),
|
|
4464
4858
|
limits: PlanLimits,
|
|
4465
4859
|
features: PlanFeatures
|
|
4466
4860
|
});
|
|
4467
|
-
var CatalogPlan = Plan.extend({ sellable:
|
|
4468
|
-
var Subscription =
|
|
4861
|
+
var CatalogPlan = Plan.extend({ sellable: z19.boolean() });
|
|
4862
|
+
var Subscription = z19.object({
|
|
4469
4863
|
workspace_id: Id,
|
|
4470
4864
|
plan: PlanId,
|
|
4471
|
-
status:
|
|
4865
|
+
status: z19.enum(["active", "trialing", "past_due", "cancelled"]),
|
|
4472
4866
|
current_period_start: Timestamp,
|
|
4473
4867
|
current_period_end: Timestamp,
|
|
4474
|
-
cancel_at_period_end:
|
|
4868
|
+
cancel_at_period_end: z19.boolean(),
|
|
4475
4869
|
/**
|
|
4476
4870
|
* A design partner outside billing (plan `design_partner`, no limits, no
|
|
4477
4871
|
* checkout). Set only by an operator, never through the API.
|
|
4478
4872
|
*/
|
|
4479
|
-
billing_exempt:
|
|
4873
|
+
billing_exempt: z19.boolean(),
|
|
4480
4874
|
/**
|
|
4481
4875
|
* Own sending domains bought on top of the plan's included ones (the
|
|
4482
4876
|
* add-on), each a monthly charge on the same subscription. 0 without the
|
|
4483
4877
|
* add-on; the usage limit `sending_domains` is the plan's plus these.
|
|
4484
4878
|
*/
|
|
4485
|
-
extra_sending_domains:
|
|
4879
|
+
extra_sending_domains: z19.number().int().min(0)
|
|
4486
4880
|
});
|
|
4487
|
-
var BillingAddons =
|
|
4488
|
-
sending_domain:
|
|
4489
|
-
monthly_price_cents:
|
|
4490
|
-
currency:
|
|
4491
|
-
sellable:
|
|
4881
|
+
var BillingAddons = z19.object({
|
|
4882
|
+
sending_domain: z19.object({
|
|
4883
|
+
monthly_price_cents: z19.number().int().min(0),
|
|
4884
|
+
currency: z19.string().length(3),
|
|
4885
|
+
sellable: z19.boolean()
|
|
4492
4886
|
})
|
|
4493
4887
|
});
|
|
4494
4888
|
var MAX_EXTRA_SENDING_DOMAINS = 100;
|
|
4495
|
-
var ExtraSendingDomainsUpdate =
|
|
4889
|
+
var ExtraSendingDomainsUpdate = z19.object({ quantity: z19.number().int().min(0).max(MAX_EXTRA_SENDING_DOMAINS) });
|
|
4496
4890
|
var USAGE_METRICS = ["messages", "contacts", "members", "providers", "webhook_endpoints", "active_automations", "sending_domains"];
|
|
4497
|
-
var UsageMetric =
|
|
4891
|
+
var UsageMetric = z19.enum(USAGE_METRICS);
|
|
4498
4892
|
var USAGE_WARNING_RATIO = 0.8;
|
|
4499
|
-
var UsageWarning =
|
|
4893
|
+
var UsageWarning = z19.object({
|
|
4500
4894
|
metric: UsageMetric,
|
|
4501
|
-
used:
|
|
4502
|
-
limit:
|
|
4895
|
+
used: z19.number().int().min(0),
|
|
4896
|
+
limit: z19.number().int().min(0),
|
|
4503
4897
|
/** `approaching`: at or above USAGE_WARNING_RATIO of the limit; `reached`: at or above the limit. */
|
|
4504
|
-
level:
|
|
4898
|
+
level: z19.enum(["approaching", "reached"])
|
|
4505
4899
|
});
|
|
4506
|
-
var TermsStatus =
|
|
4507
|
-
var Usage =
|
|
4900
|
+
var TermsStatus = z19.object({ accepted_version: z19.string().nullable(), current_version: z19.string() });
|
|
4901
|
+
var Usage = z19.object({
|
|
4508
4902
|
plan: PlanId,
|
|
4509
4903
|
period_start: Timestamp,
|
|
4510
4904
|
period_end: Timestamp,
|
|
4511
|
-
metrics:
|
|
4512
|
-
warnings:
|
|
4905
|
+
metrics: z19.record(UsageMetric, z19.object({ used: z19.number().int().min(0), limit: z19.number().int().min(0).nullable() })),
|
|
4906
|
+
warnings: z19.array(UsageWarning),
|
|
4513
4907
|
terms: TermsStatus
|
|
4514
4908
|
});
|
|
4515
|
-
var TermsAcceptance =
|
|
4516
|
-
var CheckoutRequest =
|
|
4517
|
-
plan:
|
|
4518
|
-
success_url:
|
|
4519
|
-
cancel_url:
|
|
4909
|
+
var TermsAcceptance = z19.object({ accept_terms: AcceptTerms });
|
|
4910
|
+
var CheckoutRequest = z19.object({
|
|
4911
|
+
plan: z19.enum(["starter", "growth"]),
|
|
4912
|
+
success_url: z19.string().url(),
|
|
4913
|
+
cancel_url: z19.string().url(),
|
|
4520
4914
|
/** The buyer accepted the terms of service and the processing agreement of this version. */
|
|
4521
4915
|
accept_terms: AcceptTerms
|
|
4522
4916
|
});
|
|
4523
|
-
var CheckoutSession =
|
|
4524
|
-
var PortalRequest =
|
|
4525
|
-
var PortalSession =
|
|
4917
|
+
var CheckoutSession = z19.object({ url: z19.string().url() });
|
|
4918
|
+
var PortalRequest = z19.object({ return_url: z19.string().url() });
|
|
4919
|
+
var PortalSession = z19.object({ url: z19.string().url() });
|
|
4526
4920
|
var USAGE_WARNING_HEADER = "x-mail-usage-warning";
|
|
4527
4921
|
function formatUsageWarningHeader(warnings) {
|
|
4528
4922
|
if (warnings.length === 0) return null;
|
|
@@ -4542,7 +4936,7 @@ function parseUsageWarningHeader(value) {
|
|
|
4542
4936
|
}
|
|
4543
4937
|
|
|
4544
4938
|
// src/routes.ts
|
|
4545
|
-
import { z as
|
|
4939
|
+
import { z as z20 } from "zod";
|
|
4546
4940
|
var list = (item) => page(item);
|
|
4547
4941
|
var foundationRoutes = {
|
|
4548
4942
|
"workspaces.create": {
|
|
@@ -4788,7 +5182,7 @@ var templateRoutes = {
|
|
|
4788
5182
|
path: "/v1/templates/:id/export",
|
|
4789
5183
|
params: IdParams,
|
|
4790
5184
|
query: TemplateExportQuery,
|
|
4791
|
-
response:
|
|
5185
|
+
response: z20.string(),
|
|
4792
5186
|
responseType: "text",
|
|
4793
5187
|
status: 200,
|
|
4794
5188
|
access: "read",
|
|
@@ -5168,7 +5562,7 @@ var sendingRoutes = {
|
|
|
5168
5562
|
path: "/v1/mailings/:id/export",
|
|
5169
5563
|
params: IdParams,
|
|
5170
5564
|
query: MailingExportQuery,
|
|
5171
|
-
response:
|
|
5565
|
+
response: z20.string(),
|
|
5172
5566
|
responseType: "text",
|
|
5173
5567
|
status: 200,
|
|
5174
5568
|
access: "read",
|
|
@@ -5435,7 +5829,7 @@ var platformRoutes = {
|
|
|
5435
5829
|
"contactProperties.list": {
|
|
5436
5830
|
method: "GET",
|
|
5437
5831
|
path: "/v1/contact-properties",
|
|
5438
|
-
response:
|
|
5832
|
+
response: z20.object({ data: z20.array(ContactPropertyDefinition) }),
|
|
5439
5833
|
status: 200,
|
|
5440
5834
|
access: "read",
|
|
5441
5835
|
phase: "S4"
|
|
@@ -5734,7 +6128,7 @@ var billingRoutes = {
|
|
|
5734
6128
|
"billing.plans": {
|
|
5735
6129
|
method: "GET",
|
|
5736
6130
|
path: "/v1/billing/plans",
|
|
5737
|
-
response:
|
|
6131
|
+
response: z20.object({ data: z20.array(CatalogPlan), addons: BillingAddons }),
|
|
5738
6132
|
status: 200,
|
|
5739
6133
|
access: "read",
|
|
5740
6134
|
phase: "S5"
|
|
@@ -5785,6 +6179,44 @@ var billingRoutes = {
|
|
|
5785
6179
|
phase: "S5"
|
|
5786
6180
|
}
|
|
5787
6181
|
};
|
|
6182
|
+
var domainBuyingRoutes = {
|
|
6183
|
+
"domains.search": {
|
|
6184
|
+
method: "GET",
|
|
6185
|
+
path: "/v1/domains/search",
|
|
6186
|
+
query: DomainSearchQuery,
|
|
6187
|
+
response: DomainSearchResult,
|
|
6188
|
+
status: 200,
|
|
6189
|
+
access: "admin",
|
|
6190
|
+
phase: "S5"
|
|
6191
|
+
},
|
|
6192
|
+
"domainOrders.create": {
|
|
6193
|
+
method: "POST",
|
|
6194
|
+
path: "/v1/domain-orders",
|
|
6195
|
+
body: DomainOrderCreate,
|
|
6196
|
+
response: DomainOrder,
|
|
6197
|
+
status: 201,
|
|
6198
|
+
access: "admin",
|
|
6199
|
+
phase: "S5"
|
|
6200
|
+
},
|
|
6201
|
+
"domainOrders.list": {
|
|
6202
|
+
method: "GET",
|
|
6203
|
+
path: "/v1/domain-orders",
|
|
6204
|
+
query: PageQuery,
|
|
6205
|
+
response: list(DomainOrder),
|
|
6206
|
+
status: 200,
|
|
6207
|
+
access: "admin",
|
|
6208
|
+
phase: "S5"
|
|
6209
|
+
},
|
|
6210
|
+
"domainOrders.get": {
|
|
6211
|
+
method: "GET",
|
|
6212
|
+
path: "/v1/domain-orders/:id",
|
|
6213
|
+
params: IdParams,
|
|
6214
|
+
response: DomainOrder,
|
|
6215
|
+
status: 200,
|
|
6216
|
+
access: "admin",
|
|
6217
|
+
phase: "S5"
|
|
6218
|
+
}
|
|
6219
|
+
};
|
|
5788
6220
|
var inviteRoutes = {
|
|
5789
6221
|
"invites.create": {
|
|
5790
6222
|
method: "POST",
|
|
@@ -5894,7 +6326,7 @@ var automationRoutes = {
|
|
|
5894
6326
|
method: "POST",
|
|
5895
6327
|
path: "/v1/automations/:id/pause",
|
|
5896
6328
|
params: IdParams,
|
|
5897
|
-
body:
|
|
6329
|
+
body: z20.object({}).strict(),
|
|
5898
6330
|
response: Automation,
|
|
5899
6331
|
status: 200,
|
|
5900
6332
|
access: "write",
|
|
@@ -5904,7 +6336,7 @@ var automationRoutes = {
|
|
|
5904
6336
|
method: "POST",
|
|
5905
6337
|
path: "/v1/automations/:id/resume",
|
|
5906
6338
|
params: IdParams,
|
|
5907
|
-
body:
|
|
6339
|
+
body: z20.object({}).strict(),
|
|
5908
6340
|
response: Automation,
|
|
5909
6341
|
status: 200,
|
|
5910
6342
|
access: "write",
|
|
@@ -5914,7 +6346,7 @@ var automationRoutes = {
|
|
|
5914
6346
|
method: "POST",
|
|
5915
6347
|
path: "/v1/automations/:id/archive",
|
|
5916
6348
|
params: IdParams,
|
|
5917
|
-
body:
|
|
6349
|
+
body: z20.object({}).strict(),
|
|
5918
6350
|
response: Automation,
|
|
5919
6351
|
status: 200,
|
|
5920
6352
|
access: "write",
|
|
@@ -6029,10 +6461,13 @@ var routes = {
|
|
|
6029
6461
|
...inviteRoutes,
|
|
6030
6462
|
...platformRoutes,
|
|
6031
6463
|
...billingRoutes,
|
|
6464
|
+
...domainBuyingRoutes,
|
|
6032
6465
|
...automationRoutes
|
|
6033
6466
|
};
|
|
6034
6467
|
var TRUSTED_APP_OPERATIONS = {
|
|
6035
|
-
booking: ["workspaces.list", "workspace.update", "providers.list", "sendingDomains.list", "apiKeys.create", "apiKeys.revoke"]
|
|
6468
|
+
booking: ["workspaces.list", "workspace.update", "providers.list", "sendingDomains.list", "apiKeys.create", "apiKeys.revoke"],
|
|
6469
|
+
// The shop's receipt email needs exactly what connecting a booking page needs.
|
|
6470
|
+
sites: ["workspaces.list", "workspace.update", "providers.list", "sendingDomains.list", "apiKeys.create", "apiKeys.revoke"]
|
|
6036
6471
|
};
|
|
6037
6472
|
function trustedAppMayCall(app, id) {
|
|
6038
6473
|
return TRUSTED_APP_OPERATIONS[app].includes(id);
|
|
@@ -6193,10 +6628,26 @@ export {
|
|
|
6193
6628
|
DEFAULT_INVITE_TTL_DAYS,
|
|
6194
6629
|
DEFAULT_PAGE_LIMIT,
|
|
6195
6630
|
DOCUMENT_SCHEMA_VERSIONS,
|
|
6631
|
+
DOMAIN_BUYING_BLOCKS,
|
|
6632
|
+
DOMAIN_BUYING_NOT_CONFIGURED_REASON,
|
|
6633
|
+
DOMAIN_ORDER_KINDS,
|
|
6634
|
+
DOMAIN_ORDER_STATES,
|
|
6635
|
+
DOMAIN_PRICE_CHANGED_REASON,
|
|
6636
|
+
DOMAIN_UNAVAILABLE_REASONS,
|
|
6196
6637
|
DateOnly,
|
|
6197
6638
|
DatePassedAnswer,
|
|
6198
6639
|
DelayStep,
|
|
6199
6640
|
DocumentSchemaVersion,
|
|
6641
|
+
DomainBuyingBlock,
|
|
6642
|
+
DomainOffer,
|
|
6643
|
+
DomainOrder,
|
|
6644
|
+
DomainOrderCreate,
|
|
6645
|
+
DomainOrderKind,
|
|
6646
|
+
DomainOrderState,
|
|
6647
|
+
DomainRegistrant,
|
|
6648
|
+
DomainSearchQuery,
|
|
6649
|
+
DomainSearchResult,
|
|
6650
|
+
DomainUnavailableReason,
|
|
6200
6651
|
EDITABLE_MAILING_STATUSES,
|
|
6201
6652
|
ERROR_CODES,
|
|
6202
6653
|
ERROR_STATUS,
|
|
@@ -6280,6 +6731,7 @@ export {
|
|
|
6280
6731
|
MAX_ASSET_BYTES,
|
|
6281
6732
|
MAX_DELAY_SECONDS,
|
|
6282
6733
|
MAX_DOCUMENT_BYTES,
|
|
6734
|
+
MAX_DOMAIN_ORDERS_PER_DAY,
|
|
6283
6735
|
MAX_ENGAGEMENT_DAYS,
|
|
6284
6736
|
MAX_EXPORT_WARNINGS_HEADER_LENGTH,
|
|
6285
6737
|
MAX_EXTRA_SENDING_DOMAINS,
|
|
@@ -6404,6 +6856,7 @@ export {
|
|
|
6404
6856
|
QuietHours,
|
|
6405
6857
|
RECIPIENT_REJECTIONS,
|
|
6406
6858
|
RECIPIENT_STATUSES,
|
|
6859
|
+
REGISTRY_PHONE,
|
|
6407
6860
|
REQUEST_ID_HEADER,
|
|
6408
6861
|
RESEND_EVENT_TYPES,
|
|
6409
6862
|
RESERVED_MERGE_FIELDS,
|
|
@@ -6590,6 +7043,7 @@ export {
|
|
|
6590
7043
|
demoteForSave,
|
|
6591
7044
|
demotedBySave,
|
|
6592
7045
|
describeMissingTexts,
|
|
7046
|
+
domainBuyingRoutes,
|
|
6593
7047
|
draftDocument,
|
|
6594
7048
|
draftInsertionProblems,
|
|
6595
7049
|
draftsDirty,
|
|
@@ -6640,6 +7094,7 @@ export {
|
|
|
6640
7094
|
missingInsertionTexts,
|
|
6641
7095
|
missingRequiredMergeFields,
|
|
6642
7096
|
normalizeChoiceKey,
|
|
7097
|
+
normalizePhone,
|
|
6643
7098
|
nowSeconds,
|
|
6644
7099
|
operationsWithAccess,
|
|
6645
7100
|
ownEntry,
|