domain0 0.3.2 → 0.4.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.
Files changed (40) hide show
  1. package/README.md +17 -6
  2. package/dist/contracts.cjs +1 -1811
  3. package/dist/contracts.cjs.map +1 -1
  4. package/dist/contracts.d.cts +2 -2
  5. package/dist/contracts.d.mts +2 -2
  6. package/dist/contracts.mjs +1 -1665
  7. package/dist/contracts.mjs.map +1 -1
  8. package/dist/error-1Gob8Pup.cjs +2 -0
  9. package/dist/{error-BB4-lyc4.cjs.map → error-1Gob8Pup.cjs.map} +1 -1
  10. package/dist/error-szz6-UFL.mjs +2 -0
  11. package/dist/{error-Cyd6a9ay.mjs.map → error-szz6-UFL.mjs.map} +1 -1
  12. package/dist/{index-sSrRFTnm.d.cts → index-DzGqFq0D.d.cts} +1678 -128
  13. package/dist/{index-sSrRFTnm.d.mts → index-DzGqFq0D.d.mts} +1678 -128
  14. package/dist/index.cjs +1 -245
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -3
  17. package/dist/index.d.mts +3 -3
  18. package/dist/index.mjs +1 -90
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/sdk-BbUuEwzs.mjs +148 -0
  21. package/dist/sdk-BbUuEwzs.mjs.map +1 -0
  22. package/dist/{sdk-B10fN-QP.d.mts → sdk-CkEDIlsq.d.cts} +8 -9
  23. package/dist/{sdk-DYR5Itru.d.cts → sdk-D2QNoMIg.d.mts} +8 -9
  24. package/dist/sdk-Dv22iteS.cjs +148 -0
  25. package/dist/sdk-Dv22iteS.cjs.map +1 -0
  26. package/dist/server.cjs +1 -102
  27. package/dist/server.cjs.map +1 -1
  28. package/dist/server.mjs +1 -101
  29. package/dist/server.mjs.map +1 -1
  30. package/dist/ui.cjs +1 -12
  31. package/dist/ui.d.cts +22 -3
  32. package/dist/ui.d.mts +22 -3
  33. package/dist/ui.mjs +1 -2
  34. package/package.json +7 -1
  35. package/dist/error-BB4-lyc4.cjs +0 -48
  36. package/dist/error-Cyd6a9ay.mjs +0 -31
  37. package/dist/sdk-DILJWt1m.cjs +0 -4264
  38. package/dist/sdk-DILJWt1m.cjs.map +0 -1
  39. package/dist/sdk-IuBNH4cL.mjs +0 -4187
  40. package/dist/sdk-IuBNH4cL.mjs.map +0 -1
@@ -1,1666 +1,2 @@
1
- import { z } from "zod";
2
- //#region src/contracts/primitives.ts
3
- const identifier = z.string().trim().min(1).max(200);
4
- const ConnectionIdSchema = identifier.brand().meta({ id: "ConnectionId" });
5
- const ApplicationIdSchema = identifier.brand().meta({ id: "ApplicationId" });
6
- const TenantIdSchema = identifier.brand().meta({ id: "TenantId" });
7
- const ProviderIdSchema = z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).brand().meta({ id: "ProviderId" });
8
- const CommandIdSchema = identifier.brand().meta({ id: "CommandId" });
9
- const DomainNameSchema = z.string().trim().toLowerCase().overwrite((value) => value.replace(/\.$/, "")).min(3).max(253).regex(/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/).refine((value) => !/^\d+(?:\.\d+){3}$/.test(value), "IP addresses are not domain names").brand().meta({ id: "DomainName" });
10
- const IsoDateTimeSchema = z.iso.datetime({ offset: true }).meta({ id: "IsoDateTime" });
11
- //#endregion
12
- //#region src/contracts/dns.ts
13
- const RelativeDnsHostSchema = z.string().trim().toLowerCase().overwrite((value) => value.replace(/\.$/, "")).min(1).max(253).refine(isRelativeDnsHost, "Host must be @ or a valid relative DNS name");
14
- const caaValuePattern = /^([0-9]{1,3})[\t ]+([A-Za-z0-9-]{1,15})[\t ]+(?:"([^\r\n"]*)"|([^\r\n"]+))$/;
15
- const DnsRecordTypeSchema = z.enum([
16
- "A",
17
- "AAAA",
18
- "CNAME",
19
- "CAA",
20
- "MX",
21
- "TXT",
22
- "NS"
23
- ]).meta({ id: "DnsRecordType" });
24
- const DmarcTagNameSchema = z.string().regex(/^[a-z]{1,32}$/);
25
- const DmarcTagValueSchema = z.string().min(1).max(4096).refine((value) => value.trim() === value && /^[\x20-\x3a\x3c-\x7e]+$/.test(value), { message: "DMARC tag values must be trimmed printable ASCII without semicolons" });
26
- const DmarcTagMapSchema = z.record(DmarcTagNameSchema, DmarcTagValueSchema).refine((tags) => Object.keys(tags).length <= 32, "At most 32 DMARC tags are allowed");
27
- const AdvancedDmarcOptionsSchema = z.object({
28
- inheritRootDmarc: z.boolean().default(false),
29
- overrideTags: DmarcTagMapSchema.default({}),
30
- removeTags: z.array(DmarcTagNameSchema).max(32).refine((tags) => new Set(tags).size === tags.length, "DMARC tags to remove must be unique").default([]),
31
- addTagsIfNotExist: DmarcTagMapSchema.default({})
32
- }).strict().refine((options) => options.inheritRootDmarc || Object.keys(options.overrideTags).length > 0 || options.removeTags.length > 0 || Object.keys(options.addTagsIfNotExist).length > 0, "At least one advanced DMARC option is required").superRefine((options, context) => {
33
- for (const [field, tags] of [["overrideTags", options.overrideTags], ["addTagsIfNotExist", options.addTagsIfNotExist]]) for (const [name, value] of Object.entries(tags)) if (!isValidKnownDmarcTag(name, value)) context.addIssue({
34
- code: "custom",
35
- path: [field, name],
36
- message: `Invalid value for the ${name} DMARC tag`
37
- });
38
- }).meta({ id: "AdvancedDmarcOptions" });
39
- const CoreDnsRecordSchema = z.object({
40
- host: RelativeDnsHostSchema,
41
- type: DnsRecordTypeSchema,
42
- value: z.string().trim().min(1).max(65535),
43
- ttl: z.number().int().min(1).max(2147483647).default(300),
44
- priority: z.number().int().min(0).max(65535).optional(),
45
- optional: z.boolean().default(false)
46
- }).strict().superRefine((record, context) => {
47
- if (record.type === "MX" && record.priority === void 0) context.addIssue({
48
- code: "custom",
49
- path: ["priority"],
50
- message: "MX records require a priority"
51
- });
52
- if (record.type !== "MX" && record.priority !== void 0) context.addIssue({
53
- code: "custom",
54
- path: ["priority"],
55
- message: "Only MX records accept a priority"
56
- });
57
- if (record.type === "A" && !z.ipv4().safeParse(record.value).success) context.addIssue({
58
- code: "custom",
59
- path: ["value"],
60
- message: "A records require an IPv4 address"
61
- });
62
- if (record.type === "AAAA" && !z.ipv6().safeParse(record.value).success) context.addIssue({
63
- code: "custom",
64
- path: ["value"],
65
- message: "AAAA records require an IPv6 address"
66
- });
67
- if ([
68
- "CNAME",
69
- "MX",
70
- "NS"
71
- ].includes(record.type) && !DomainNameSchema.safeParse(record.value).success) context.addIssue({
72
- code: "custom",
73
- path: ["value"],
74
- message: `${record.type} records require a domain name`
75
- });
76
- if (record.type === "CAA") {
77
- const match = caaValuePattern.exec(record.value);
78
- if (match === null || Number(match[1]) > 255) context.addIssue({
79
- code: "custom",
80
- path: ["value"],
81
- message: "CAA values must contain flags, a tag, and a quoted value"
82
- });
83
- }
84
- if (record.type === "TXT" && /[\u0000\r\n]/.test(record.value)) context.addIssue({
85
- code: "custom",
86
- path: ["value"],
87
- message: "TXT values cannot contain NUL or newlines"
88
- });
89
- });
90
- const ResolvedDnsRecordSchema = CoreDnsRecordSchema.meta({ id: "ResolvedDnsRecord" });
91
- const DnsRecordSchema = CoreDnsRecordSchema.safeExtend({ advancedDmarcOptions: AdvancedDmarcOptionsSchema.optional() }).superRefine((record, context) => {
92
- if (record.advancedDmarcOptions === void 0) return;
93
- if (record.type !== "TXT" || record.host !== "_dmarc" && !record.host.startsWith("_dmarc.")) context.addIssue({
94
- code: "custom",
95
- path: ["advancedDmarcOptions"],
96
- message: "Advanced DMARC options require a TXT record at a _dmarc host"
97
- });
98
- if (!isValidDmarcRecord(record.value)) context.addIssue({
99
- code: "custom",
100
- path: ["value"],
101
- message: "Advanced DMARC options require a valid DMARC1 value with a policy tag"
102
- });
103
- }).meta({ id: "DnsRecord" });
104
- const ExistingRecordPolicySchema = z.object({
105
- validateDmarc: z.boolean().default(false),
106
- validateCAA: z.boolean().default(false)
107
- }).strict().meta({ id: "ExistingRecordPolicy" });
108
- const DnsIntentSchema = z.object({
109
- domain: DomainNameSchema,
110
- records: z.array(DnsRecordSchema).min(1).max(100),
111
- existingRecordPolicy: ExistingRecordPolicySchema.default({
112
- validateDmarc: false,
113
- validateCAA: false
114
- })
115
- }).strict().meta({ id: "DnsIntent" });
116
- const ResolvedDnsIntentSchema = z.object({
117
- domain: DomainNameSchema,
118
- records: z.array(ResolvedDnsRecordSchema).max(100)
119
- }).strict().meta({ id: "ResolvedDnsIntent" });
120
- const CheckRecordsInputSchema = ResolvedDnsIntentSchema.meta({ id: "CheckRecordsInput" });
121
- const CheckedRecordSchema = z.object({
122
- record: ResolvedDnsRecordSchema,
123
- authoritativeServers: z.number().int().min(1).max(16),
124
- matchingServers: z.number().int().min(0).max(16),
125
- propagated: z.boolean()
126
- }).strict().superRefine((result, context) => {
127
- if (result.matchingServers > result.authoritativeServers) context.addIssue({
128
- code: "custom",
129
- path: ["matchingServers"],
130
- message: "Matching nameservers cannot exceed authoritative nameservers"
131
- });
132
- if (result.propagated !== (result.matchingServers === result.authoritativeServers)) context.addIssue({
133
- code: "custom",
134
- path: ["propagated"],
135
- message: "Propagation state must match the authoritative nameserver counts"
136
- });
137
- }).meta({ id: "CheckedRecord" });
138
- const CheckRecordsResponseSchema = z.object({
139
- domain: DomainNameSchema,
140
- allPropagated: z.boolean(),
141
- records: z.array(CheckedRecordSchema).min(1).max(100)
142
- }).strict().superRefine((result, context) => {
143
- if (result.allPropagated !== result.records.every((record) => record.propagated)) context.addIssue({
144
- code: "custom",
145
- path: ["allPropagated"],
146
- message: "Overall propagation state must match every record result"
147
- });
148
- }).meta({ id: "CheckRecordsResponse" });
149
- const ConflictPolicySchema = z.enum([
150
- "preserve",
151
- "replace_same_name_and_type",
152
- "replace_all_at_name"
153
- ]).meta({ id: "ConflictPolicy" });
154
- const SpfConflictPolicySchema = z.enum(["merge", "replace"]).meta({ id: "SpfConflictPolicy" });
155
- const ChangeActionSchema = z.enum([
156
- "create",
157
- "replace",
158
- "delete"
159
- ]).meta({ id: "ChangeAction" });
160
- const PlannedChangeSchema = z.object({
161
- action: ChangeActionSchema,
162
- before: ResolvedDnsRecordSchema.optional(),
163
- after: ResolvedDnsRecordSchema.optional(),
164
- destructive: z.boolean()
165
- }).strict().superRefine((change, context) => {
166
- if (change.action === "create" && change.after === void 0) context.addIssue({
167
- code: "custom",
168
- path: ["after"],
169
- message: "Create requires the resulting record"
170
- });
171
- if (change.action === "replace" && (change.before === void 0 || change.after === void 0)) context.addIssue({
172
- code: "custom",
173
- message: "Replace requires both current and resulting records"
174
- });
175
- if (change.action === "delete" && change.before === void 0) context.addIssue({
176
- code: "custom",
177
- path: ["before"],
178
- message: "Delete requires the current record"
179
- });
180
- }).meta({ id: "PlannedChange" });
181
- function isRelativeDnsHost(value) {
182
- if (value === "@") return true;
183
- return value.split(".").every((label, index) => {
184
- if (label === "*") return index === 0;
185
- return label.length >= 1 && label.length <= 63 && !label.startsWith("-") && !label.endsWith("-") && /^[a-z0-9_-]+$/.test(label);
186
- });
187
- }
188
- function isValidDmarcRecord(value) {
189
- const parts = value.split(";").map((part) => part.trim()).filter(Boolean);
190
- const seen = /* @__PURE__ */ new Set();
191
- if (parts.length < 2) return false;
192
- for (const [index, part] of parts.entries()) {
193
- const separator = part.indexOf("=");
194
- if (separator <= 0) return false;
195
- const name = part.slice(0, separator).trim().toLowerCase();
196
- const tagValue = part.slice(separator + 1).trim();
197
- if (!DmarcTagNameSchema.safeParse(name).success || !DmarcTagValueSchema.safeParse(tagValue).success || seen.has(name)) return false;
198
- if (index === 0 && (name !== "v" || tagValue !== "DMARC1")) return false;
199
- if (!isValidKnownDmarcTag(name, tagValue)) return false;
200
- seen.add(name);
201
- }
202
- return seen.has("p");
203
- }
204
- function isValidKnownDmarcTag(name, value) {
205
- if (name === "v") return value === "DMARC1";
206
- if ([
207
- "p",
208
- "sp",
209
- "np"
210
- ].includes(name)) return [
211
- "none",
212
- "quarantine",
213
- "reject"
214
- ].includes(value);
215
- if (["adkim", "aspf"].includes(name)) return value === "r" || value === "s";
216
- if (name === "pct") return /^\d{1,3}$/.test(value) && Number(value) <= 100;
217
- if (name === "ri") return /^[1-9]\d*$/.test(value);
218
- if (name === "rf") return value === "afrf";
219
- if (name === "fo") {
220
- const options = value.split(":");
221
- return options.length > 0 && new Set(options).size === options.length && options.every((option) => [
222
- "0",
223
- "1",
224
- "d",
225
- "s"
226
- ].includes(option)) && !(options.includes("0") && options.includes("1"));
227
- }
228
- return true;
229
- }
230
- //#endregion
231
- //#region src/contracts/provider.ts
232
- const ProviderImplementationSchema = z.enum([
233
- "automatic",
234
- "domain_connect",
235
- "manual",
236
- "unverified"
237
- ]).meta({ id: "ProviderImplementation" });
238
- const AuthorizationMethodSchema = z.enum([
239
- "oauth2_pkce",
240
- "oauth2_authorization_code",
241
- "api_token",
242
- "api_key",
243
- "basic",
244
- "session",
245
- "domain_connect",
246
- "manual"
247
- ]).meta({ id: "AuthorizationMethod" });
248
- const ProviderCapabilitiesSchema = z.strictObject({
249
- rootNSModification: z.enum([
250
- "supported",
251
- "unsupported",
252
- "unverified"
253
- ]),
254
- subdomainNSModification: z.enum([
255
- "supported",
256
- "unsupported",
257
- "unverified"
258
- ]),
259
- wwwRedirect: z.enum([
260
- "supported",
261
- "unsupported",
262
- "unverified"
263
- ]),
264
- cnameFlattening: z.enum([
265
- "supported",
266
- "unsupported",
267
- "unverified"
268
- ]),
269
- wildcardRecords: z.enum([
270
- "supported",
271
- "unsupported",
272
- "unverified"
273
- ]),
274
- caaRecords: z.enum([
275
- "supported",
276
- "unsupported",
277
- "unverified"
278
- ]),
279
- spfRecords: z.enum([
280
- "supported",
281
- "unsupported",
282
- "unverified"
283
- ]),
284
- socialLogin: z.enum([
285
- "supported",
286
- "unsupported",
287
- "unverified"
288
- ])
289
- }).meta({ id: "ProviderCapabilities" });
290
- const ProviderDetectionUnavailableReasonCodeSchema = z.enum(["no_stable_public_provider_identity"]).meta({ id: "ProviderDetectionUnavailableReasonCode" });
291
- const ProviderDetectionSchema = z.discriminatedUnion("method", [z.strictObject({ method: z.enum([
292
- "nameserver",
293
- "domain_connect",
294
- "nameserver_or_domain_connect"
295
- ]) }), z.strictObject({
296
- method: z.literal("manual"),
297
- reasonCode: ProviderDetectionUnavailableReasonCodeSchema
298
- })]).meta({ id: "ProviderDetection" });
299
- const ProviderReferenceUrlSchema = z.url({ protocol: /^https$/ }).regex(/^https:\/\//, "Provider reference URL must use HTTPS").refine((value) => {
300
- const url = new URL(value);
301
- return url.username === "" && url.password === "";
302
- }, "Provider reference URL must not contain credentials").meta({ format: "uri" });
303
- const ProviderSchema = z.object({
304
- id: ProviderIdSchema,
305
- name: z.string().trim().min(1),
306
- referenceUrl: ProviderReferenceUrlSchema,
307
- implementation: ProviderImplementationSchema,
308
- availableAuthorizationMethods: z.array(AuthorizationMethodSchema).refine((methods) => new Set(methods).size === methods.length, "Authorization methods must be unique").describe("Available methods ordered from highest to lowest provider autonomy."),
309
- capabilities: ProviderCapabilitiesSchema,
310
- detection: ProviderDetectionSchema,
311
- limitations: z.array(z.string().min(1))
312
- }).strict().superRefine((provider, context) => {
313
- const methods = provider.availableAuthorizationMethods;
314
- if (!(provider.implementation === "automatic" ? methods.every((method) => method !== "domain_connect" && method !== "manual") : provider.implementation === "domain_connect" ? methods.every((method) => method === "domain_connect") : provider.implementation === "manual" ? methods.every((method) => method === "manual") : methods.length === 0)) context.addIssue({
315
- code: "custom",
316
- path: ["availableAuthorizationMethods"],
317
- message: "Authorization methods must match the verified provider implementation"
318
- });
319
- }).meta({ id: "Provider" });
320
- const ListProvidersResponseSchema = z.object({ providers: z.array(ProviderSchema) }).strict().meta({ id: "ListProvidersResponse" });
321
- const ProviderHealthStatusSchema = z.enum(["operational", "unavailable"]).meta({ id: "ProviderHealthStatus" });
322
- const ProviderHealthReasonSchema = z.enum([
323
- "automatic_ready",
324
- "domain_connect_ready",
325
- "runtime_authorization_unavailable",
326
- "manual_only",
327
- "unverified"
328
- ]).meta({ id: "ProviderHealthReason" });
329
- const ProviderHealthSchema = z.object({
330
- providerId: ProviderIdSchema,
331
- providerName: z.string().trim().min(1).max(200),
332
- enabled: z.boolean(),
333
- status: ProviderHealthStatusSchema,
334
- reason: ProviderHealthReasonSchema
335
- }).strict().superRefine((health, context) => {
336
- const readyReason = health.reason === "automatic_ready" || health.reason === "domain_connect_ready";
337
- const matchingStatus = health.enabled ? health.status === "operational" : health.status === "unavailable";
338
- if (health.enabled !== readyReason || !matchingStatus) context.addIssue({
339
- code: "custom",
340
- path: ["enabled"],
341
- message: "Enabled, status, and reason must describe the same provider health state"
342
- });
343
- }).meta({ id: "ProviderHealth" });
344
- const ProviderHealthResponseSchema = z.object({
345
- observedAt: IsoDateTimeSchema,
346
- refreshAfter: IsoDateTimeSchema,
347
- providers: z.array(ProviderHealthSchema)
348
- }).strict().superRefine((report, context) => {
349
- if (Date.parse(report.refreshAfter) <= Date.parse(report.observedAt)) context.addIssue({
350
- code: "custom",
351
- path: ["refreshAfter"],
352
- message: "Provider health refresh deadline must be after its observation time"
353
- });
354
- const providerIds = report.providers.map((provider) => provider.providerId);
355
- if (new Set(providerIds).size !== providerIds.length) context.addIssue({
356
- code: "custom",
357
- path: ["providers"],
358
- message: "Provider health entries must have unique provider IDs"
359
- });
360
- }).meta({ id: "ProviderHealthResponse" });
361
- //#endregion
362
- //#region src/contracts/connection.ts
363
- const ConnectionStateSchema = z.enum([
364
- "requested",
365
- "detecting_provider",
366
- "provider_selected",
367
- "domain_connect_pending",
368
- "authorization_pending",
369
- "authorized",
370
- "planning",
371
- "awaiting_confirmation",
372
- "applying",
373
- "propagation_pending",
374
- "active",
375
- "manual_required",
376
- "failed_retryable",
377
- "failed_terminal",
378
- "cancelled"
379
- ]).meta({ id: "ConnectionState" });
380
- const RetryResumeStateSchema = z.enum([
381
- "authorized",
382
- "awaiting_confirmation",
383
- "applying"
384
- ]).meta({ id: "RetryResumeState" });
385
- const ConnectionFailureCodeSchema = z.enum(["provider_snapshot_timeout", "provider_apply_timeout"]).meta({ id: "ConnectionFailureCode" });
386
- const ConnectionFailureSchema = z.object({
387
- code: ConnectionFailureCodeSchema,
388
- retryable: z.literal(true),
389
- resumeState: RetryResumeStateSchema,
390
- occurredAt: IsoDateTimeSchema
391
- }).strict().meta({ id: "ConnectionFailure" });
392
- const PlanWarningCodeSchema = z.enum(["spf_policy_replaced", "spf_policy_merged"]).meta({ id: "PlanWarningCode" });
393
- const ChangePlanSchema = z.object({
394
- digest: z.string().regex(/^[a-f0-9]{64}$/),
395
- changes: z.array(PlannedChangeSchema).min(1),
396
- warnings: z.array(PlanWarningCodeSchema),
397
- expiresAt: IsoDateTimeSchema
398
- }).strict().meta({ id: "ChangePlan" });
399
- const ConnectionSchema = z.object({
400
- id: ConnectionIdSchema,
401
- applicationId: ApplicationIdSchema,
402
- tenantId: TenantIdSchema,
403
- intent: DnsIntentSchema,
404
- effectiveIntent: ResolvedDnsIntentSchema.optional(),
405
- state: ConnectionStateSchema,
406
- provider: ProviderSchema.optional(),
407
- plan: ChangePlanSchema.optional(),
408
- failure: ConnectionFailureSchema.optional(),
409
- optionalFailures: z.array(z.string()),
410
- createdAt: IsoDateTimeSchema,
411
- updatedAt: IsoDateTimeSchema
412
- }).strict().superRefine((connection, context) => {
413
- const requiresFailure = connection.state === "failed_retryable";
414
- if (requiresFailure !== (connection.failure !== void 0)) context.addIssue({
415
- code: "custom",
416
- path: ["failure"],
417
- message: requiresFailure ? "A retryable failure state requires failure details" : "Failure details are allowed only in a retryable failure state"
418
- });
419
- if (connection.effectiveIntent !== void 0 && connection.effectiveIntent.domain !== connection.intent.domain) context.addIssue({
420
- code: "custom",
421
- path: ["effectiveIntent", "domain"],
422
- message: "Effective intent must use the requested intent domain"
423
- });
424
- }).meta({ id: "Connection" });
425
- const CreateConnectionInputSchema = z.object({
426
- applicationId: ApplicationIdSchema,
427
- tenantId: TenantIdSchema,
428
- intent: DnsIntentSchema,
429
- commandId: CommandIdSchema
430
- }).strict().meta({ id: "CreateConnectionInput" });
431
- const CreateConnectionResponseSchema = z.object({ connection: ConnectionSchema }).strict().meta({ id: "ConnectionResponse" });
432
- const GetConnectionResponseSchema = CreateConnectionResponseSchema;
433
- const ProviderCandidateSchema = z.object({
434
- provider: ProviderSchema,
435
- confidence: z.number().min(0).max(1)
436
- }).strict().meta({ id: "ProviderCandidate" });
437
- const DetectProviderResponseSchema = z.object({
438
- connection: ConnectionSchema,
439
- candidates: z.array(ProviderCandidateSchema)
440
- }).strict().meta({ id: "DetectProviderResponse" });
441
- const SelectProviderInputSchema = z.object({
442
- providerId: ProviderIdSchema,
443
- commandId: CommandIdSchema
444
- }).strict().meta({ id: "SelectProviderInput" });
445
- const DomainConnectIdSchema = z.string().regex(/^[A-Za-z0-9._-]{1,63}$/);
446
- const DomainConnectPropertyNameSchema = z.string().regex(/^[A-Za-z][A-Za-z0-9_-]{0,62}$/);
447
- const reservedDomainConnectProperties = /* @__PURE__ */ new Set([
448
- "domain",
449
- "host",
450
- "groupId",
451
- "providerName",
452
- "serviceName",
453
- "instanceId",
454
- "redirect_uri",
455
- "state",
456
- "sig",
457
- "key"
458
- ]);
459
- const DomainConnectPropertiesSchema = z.record(DomainConnectPropertyNameSchema, z.string().min(1).max(4096).refine((value) => value.trim() === value && !/[\u0000\r\n]/.test(value), "Domain Connect property values must be trimmed and single-line")).refine((properties) => Object.keys(properties).length <= 64, "At most 64 Domain Connect properties are allowed").refine((properties) => Object.keys(properties).every((name) => !reservedDomainConnectProperties.has(name)), "Domain Connect properties must not override reserved protocol parameters");
460
- const DomainConnectTemplateSchema = z.object({
461
- serviceProviderId: DomainConnectIdSchema,
462
- serviceId: DomainConnectIdSchema,
463
- host: z.string().max(253).regex(/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/).optional(),
464
- groupId: DomainConnectIdSchema.optional(),
465
- providerName: z.string().trim().min(1).max(200).optional(),
466
- serviceName: z.string().trim().min(1).max(200).optional(),
467
- instanceId: DomainConnectIdSchema.optional(),
468
- properties: DomainConnectPropertiesSchema
469
- }).strict().meta({ id: "DomainConnectTemplate" });
470
- const StartDomainConnectInputSchema = DomainConnectTemplateSchema.extend({ commandId: CommandIdSchema }).strict().meta({ id: "StartDomainConnectInput" });
471
- const DomainConnectHandoffUrlSchema = z.url({ protocol: /^https$/ }).refine((value) => {
472
- const url = new URL(value);
473
- return url.username === "" && url.password === "" && url.hash === "";
474
- }, "Domain Connect handoff URL must be HTTPS without credentials or a fragment");
475
- const StartDomainConnectResponseSchema = z.object({
476
- connection: ConnectionSchema,
477
- handoffUrl: DomainConnectHandoffUrlSchema
478
- }).strict().meta({ id: "StartDomainConnectResponse" });
479
- const SubmitDomainConnectCompletionInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "SubmitDomainConnectCompletionInput" });
480
- const ConfirmPlanInputSchema = z.object({
481
- digest: z.string().regex(/^[a-f0-9]{64}$/),
482
- allowDestructive: z.boolean(),
483
- commandId: CommandIdSchema
484
- }).strict().meta({ id: "ConfirmPlanInput" });
485
- const StartOAuthInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "StartOAuthInput" });
486
- const StartOAuthResponseSchema = z.object({
487
- connection: ConnectionSchema,
488
- authorizationUrl: z.url({ protocol: /^https$/ }),
489
- expiresAt: IsoDateTimeSchema
490
- }).strict().meta({ id: "StartOAuthResponse" });
491
- const SecretSchema = z.string().min(1).max(16384).refine((value) => value.trim() === value, "Credential values must not have leading or trailing whitespace").meta({
492
- format: "password",
493
- writeOnly: true
494
- });
495
- const ApiTokenCredentialsSchema = z.object({
496
- kind: z.literal("api_token"),
497
- token: SecretSchema
498
- }).strict().meta({ id: "ApiTokenCredentials" });
499
- const AccessKeyCredentialsSchema = z.object({
500
- kind: z.literal("access_key"),
501
- keyId: SecretSchema,
502
- secret: SecretSchema
503
- }).strict().meta({ id: "AccessKeyCredentials" });
504
- const UsernamePasswordCredentialsSchema = z.object({
505
- kind: z.literal("username_password"),
506
- username: SecretSchema,
507
- password: SecretSchema
508
- }).strict().meta({ id: "UsernamePasswordCredentials" });
509
- const AccountTokenCredentialsSchema = z.object({
510
- kind: z.literal("account_token"),
511
- accountId: SecretSchema,
512
- token: SecretSchema
513
- }).strict().meta({ id: "AccountTokenCredentials" });
514
- const UsernameTokenCredentialsSchema = z.object({
515
- kind: z.literal("username_token"),
516
- username: SecretSchema,
517
- token: SecretSchema
518
- }).strict().meta({ id: "UsernameTokenCredentials" });
519
- const OvhCredentialsSchema = z.object({
520
- kind: z.literal("ovh"),
521
- endpoint: z.enum([
522
- "ovh-eu",
523
- "ovh-us",
524
- "ovh-ca",
525
- "kimsufi-eu",
526
- "kimsufi-ca",
527
- "soyoustart-eu",
528
- "soyoustart-ca"
529
- ]),
530
- applicationKey: SecretSchema,
531
- applicationSecret: SecretSchema,
532
- consumerKey: SecretSchema
533
- }).strict().meta({ id: "OvhCredentials" });
534
- const PrivateKeyCredentialsSchema = z.object({
535
- kind: z.literal("private_key"),
536
- login: SecretSchema,
537
- privateKey: SecretSchema.refine((value) => /^(-----BEGIN (?:RSA )?PRIVATE KEY-----)[\s\S]+(-----END (?:RSA )?PRIVATE KEY-----)$/.test(value), "A PKCS#8 or PKCS#1 PEM private key is required")
538
- }).strict().meta({ id: "PrivateKeyCredentials" });
539
- const AwsSessionCredentialsSchema = z.object({
540
- kind: z.literal("aws_session"),
541
- keyId: SecretSchema.regex(/^[A-Z0-9]{16,128}$/),
542
- secret: SecretSchema,
543
- sessionToken: SecretSchema,
544
- hostedZoneId: z.string().regex(/^Z[A-Z0-9]{1,63}$/),
545
- expiresAt: IsoDateTimeSchema
546
- }).strict().meta({ id: "AwsSessionCredentials" });
547
- const CPanelEndpointSchema = z.url({ protocol: /^https$/ }).refine((value) => {
548
- const url = new URL(value);
549
- return url.port === "2083" && url.username === "" && url.password === "" && (url.pathname === "" || url.pathname === "/") && url.search === "" && url.hash === "";
550
- }, "cPanel endpoint must be an HTTPS origin on port 2083");
551
- const CPanelCredentialsSchema = z.object({
552
- kind: z.literal("cpanel"),
553
- endpoint: CPanelEndpointSchema,
554
- username: SecretSchema,
555
- token: SecretSchema
556
- }).strict().meta({ id: "CPanelCredentials" });
557
- const ClientCredentialsSchema = z.object({
558
- kind: z.literal("client_credentials"),
559
- clientId: SecretSchema,
560
- clientSecret: SecretSchema
561
- }).strict().meta({ id: "ClientCredentials" });
562
- function credentialInput(providerId, credentials) {
563
- return z.object({
564
- providerId: z.literal(providerId),
565
- credentials,
566
- commandId: CommandIdSchema
567
- }).strict();
568
- }
569
- const directCredentialAuthorizationOptions = [
570
- credentialInput("alibaba-cloud", AccessKeyCredentialsSchema),
571
- credentialInput("all-inkl", UsernamePasswordCredentialsSchema),
572
- credentialInput("amazon-route-53", AwsSessionCredentialsSchema),
573
- credentialInput("cloudflare", ApiTokenCredentialsSchema),
574
- credentialInput("cloudns", AccountTokenCredentialsSchema),
575
- credentialInput("digitalocean", ApiTokenCredentialsSchema),
576
- credentialInput("dnsimple", AccountTokenCredentialsSchema),
577
- credentialInput("dreamhost", ApiTokenCredentialsSchema),
578
- credentialInput("dynadot", AccessKeyCredentialsSchema),
579
- credentialInput("easydns", AccessKeyCredentialsSchema),
580
- credentialInput("gandi", ApiTokenCredentialsSchema),
581
- credentialInput("godaddy", ApiTokenCredentialsSchema),
582
- credentialInput("hetzner", ApiTokenCredentialsSchema),
583
- credentialInput("hostgator", CPanelCredentialsSchema),
584
- credentialInput("hostinger", ApiTokenCredentialsSchema),
585
- credentialInput("hosting-com", CPanelCredentialsSchema),
586
- credentialInput("inmotion-hosting", CPanelCredentialsSchema),
587
- credentialInput("ionos", ApiTokenCredentialsSchema),
588
- credentialInput("name-com", UsernameTokenCredentialsSchema),
589
- credentialInput("namesilo", ApiTokenCredentialsSchema),
590
- credentialInput("netlify", ApiTokenCredentialsSchema),
591
- credentialInput("o2switch", CPanelCredentialsSchema),
592
- credentialInput("openprovider", ApiTokenCredentialsSchema),
593
- credentialInput("opensrs", ClientCredentialsSchema),
594
- credentialInput("ovh", OvhCredentialsSchema),
595
- credentialInput("porkbun", AccessKeyCredentialsSchema),
596
- credentialInput("simply", ApiTokenCredentialsSchema),
597
- credentialInput("spaceship", AccessKeyCredentialsSchema),
598
- credentialInput("transip", PrivateKeyCredentialsSchema),
599
- credentialInput("united-domains", ApiTokenCredentialsSchema),
600
- credentialInput("vercel", ApiTokenCredentialsSchema),
601
- credentialInput("wix", AccountTokenCredentialsSchema)
602
- ];
603
- const directCredentialKindByProvider = Object.freeze(Object.fromEntries(directCredentialAuthorizationOptions.map((option) => [option.shape.providerId.value, option.shape.credentials.shape.kind.value])));
604
- const AuthorizeWithCredentialInputSchema = z.discriminatedUnion("providerId", directCredentialAuthorizationOptions).meta({ id: "AuthorizeWithCredentialInput" });
605
- const OAuthCallbackResponseSchema = z.object({ completed: z.literal(true) }).strict().meta({ id: "OAuthCallbackResponse" });
606
- const PreparePlanInputSchema = z.object({
607
- conflictPolicy: ConflictPolicySchema,
608
- spfPolicy: SpfConflictPolicySchema.default("merge"),
609
- commandId: CommandIdSchema
610
- }).strict().meta({ id: "PreparePlanInput" });
611
- const ApplyPlanInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "ApplyPlanInput" });
612
- const VerifyPropagationInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "VerifyPropagationInput" });
613
- const StartManualConfigurationInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "StartManualConfigurationInput" });
614
- const SubmitManualCompletionInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "SubmitManualCompletionInput" });
615
- const CancelConnectionInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "CancelConnectionInput" });
616
- const RetryConnectionInputSchema = z.object({ commandId: CommandIdSchema }).strict().meta({ id: "RetryConnectionInput" });
617
- const IssueConnectionTokenInputSchema = z.object({ origin: z.url().refine((value) => {
618
- const url = new URL(value);
619
- return url.username === "" && url.password === "" && url.search === "" && url.hash === "" && (url.pathname === "" || url.pathname === "/") && (url.protocol === "https:" || url.protocol === "http:" && isLoopbackHost(url.hostname));
620
- }, "Origin must be an HTTPS origin without a path, query, or fragment") }).strict().meta({ id: "IssueConnectionTokenInput" });
621
- const IssueConnectionTokenResponseSchema = z.object({
622
- accessToken: z.string().min(1).max(8192),
623
- tokenType: z.literal("Bearer"),
624
- expiresAt: IsoDateTimeSchema
625
- }).strict().meta({ id: "IssueConnectionTokenResponse" });
626
- function isLoopbackHost(hostname) {
627
- return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
628
- }
629
- //#endregion
630
- //#region src/contracts/connection-flow.ts
631
- const ConnectionFlowIdSchema = z.string().trim().min(1).max(200).meta({ id: "ConnectionFlowId" });
632
- const ConditionalDnsRecordsSchema = z.strictObject({
633
- domain: z.array(DnsRecordSchema).min(1).max(100),
634
- subDomain: z.array(DnsRecordSchema).min(1).max(100).optional(),
635
- rootNS: z.array(DnsRecordSchema).min(1).max(100).optional()
636
- }).superRefine((records, context) => {
637
- records.rootNS?.forEach((record, index) => {
638
- if (record.host !== "@" || record.type !== "NS") context.addIssue({
639
- code: "custom",
640
- path: ["rootNS", index],
641
- message: "rootNS accepts only NS records at the zone apex"
642
- });
643
- });
644
- }).meta({ id: "ConditionalDnsRecords" });
645
- const DirectConnectionFlowTargetInputSchema = z.strictObject({
646
- domain: DomainNameSchema,
647
- records: z.array(DnsRecordSchema).min(1).max(100)
648
- });
649
- const ConditionalConnectionFlowTargetInputSchema = z.strictObject({
650
- domain: DomainNameSchema,
651
- conditionalRecords: ConditionalDnsRecordsSchema
652
- });
653
- const ConnectionFlowTargetInputSchema = z.union([DirectConnectionFlowTargetInputSchema, ConditionalConnectionFlowTargetInputSchema]).meta({ id: "ConnectionFlowTargetInput" });
654
- const CreateConnectionFlowInputSchema = z.strictObject({
655
- applicationId: ApplicationIdSchema,
656
- tenantId: TenantIdSchema,
657
- existingRecordPolicy: ExistingRecordPolicySchema.default({
658
- validateDmarc: false,
659
- validateCAA: false
660
- }),
661
- targets: z.array(ConnectionFlowTargetInputSchema).min(2).max(100).superRefine((targets, context) => {
662
- const seen = /* @__PURE__ */ new Set();
663
- targets.forEach((target, index) => {
664
- if (seen.has(target.domain)) context.addIssue({
665
- code: "custom",
666
- path: [index, "domain"],
667
- message: "Flow target domains must be unique"
668
- });
669
- seen.add(target.domain);
670
- });
671
- }),
672
- commandId: CommandIdSchema
673
- }).meta({ id: "CreateConnectionFlowInput" });
674
- const ConnectionFlowTargetSchema = z.strictObject({
675
- domain: DomainNameSchema,
676
- state: z.enum(["pending", "provisioned"]),
677
- connectionId: ConnectionIdSchema.optional()
678
- }).superRefine((target, context) => {
679
- if (target.state === "provisioned" !== (target.connectionId !== void 0)) context.addIssue({
680
- code: "custom",
681
- path: ["connectionId"],
682
- message: target.state === "provisioned" ? "A provisioned target requires a connection id" : "A pending target cannot have a connection id"
683
- });
684
- }).meta({ id: "ConnectionFlowTarget" });
685
- const ConnectionFlowSchema = z.strictObject({
686
- id: ConnectionFlowIdSchema,
687
- applicationId: ApplicationIdSchema,
688
- tenantId: TenantIdSchema,
689
- state: z.enum(["provisioning", "ready"]),
690
- targets: z.array(ConnectionFlowTargetSchema).min(2).max(100),
691
- createdAt: IsoDateTimeSchema,
692
- updatedAt: IsoDateTimeSchema
693
- }).superRefine((flow, context) => {
694
- const allProvisioned = flow.targets.every((target) => target.state === "provisioned");
695
- if (flow.state === "ready" !== allProvisioned) context.addIssue({
696
- code: "custom",
697
- path: ["state"],
698
- message: "Flow state must match target provisioning state"
699
- });
700
- }).meta({ id: "ConnectionFlow" });
701
- const ConnectionFlowResponseSchema = z.strictObject({ flow: ConnectionFlowSchema }).meta({ id: "ConnectionFlowResponse" });
702
- //#endregion
703
- //#region src/contracts/shared-flow.ts
704
- const SharedFlowIdSchema = z.string().min(1).max(200).brand();
705
- const SharedFlowTokenSchema = z.string().regex(/^[A-Za-z0-9_-]{43}$/).brand();
706
- const CreateSharedFlowInputSchema = z.strictObject({
707
- connectionId: ConnectionIdSchema,
708
- expiresAt: IsoDateTimeSchema
709
- });
710
- const CreateSharedFlowResponseSchema = z.strictObject({
711
- sharedFlowId: SharedFlowIdSchema,
712
- token: SharedFlowTokenSchema,
713
- expiresAt: IsoDateTimeSchema
714
- });
715
- const ResolveSharedFlowInputSchema = z.strictObject({
716
- token: SharedFlowTokenSchema,
717
- origin: z.string().url().max(2048)
718
- });
719
- const ResolveSharedFlowResponseSchema = z.strictObject({
720
- sharedFlowId: SharedFlowIdSchema,
721
- connectionId: ConnectionIdSchema,
722
- accessToken: z.string().min(1).max(8192),
723
- expiresAt: IsoDateTimeSchema
724
- });
725
- const SharedFlowUrlSchema = z.string().url().max(4096);
726
- const SharedFlowInvitationUrlSchema = SharedFlowUrlSchema.superRefine((value, context) => {
727
- const url = new URL(value);
728
- const secure = url.protocol === "https:";
729
- const loopback = url.protocol === "http:" && isLoopbackHostname(url.hostname);
730
- if (!secure && !loopback) context.addIssue({
731
- code: "custom",
732
- message: "Shared-flow invitation URLs must use HTTPS, except on loopback development hosts"
733
- });
734
- if (url.username !== "" || url.password !== "") context.addIssue({
735
- code: "custom",
736
- message: "Shared-flow invitation URLs cannot contain user information"
737
- });
738
- const fragment = new URLSearchParams(url.hash.slice(1));
739
- const token = fragment.get("domain0");
740
- if (fragment.size !== 1 || !SharedFlowTokenSchema.safeParse(token).success) context.addIssue({
741
- code: "custom",
742
- message: "Shared-flow invitation URLs require one valid domain0 capability in the fragment"
743
- });
744
- }).meta({ id: "SharedFlowInvitationUrl" });
745
- const SharedFlowInvitationSchema = z.object({
746
- sharedFlowId: SharedFlowIdSchema,
747
- url: SharedFlowInvitationUrlSchema,
748
- expiresAt: IsoDateTimeSchema
749
- }).strict().meta({ id: "SharedFlowInvitation" });
750
- function isLoopbackHostname(hostname) {
751
- const normalized = hostname.toLowerCase();
752
- return normalized === "localhost" || normalized === "[::1]" || /^127(?:\.[0-9]{1,3}){3}$/.test(normalized);
753
- }
754
- //#endregion
755
- //#region src/contracts/dkim-guidance.ts
756
- const DkimSelectorSchema = z.string().trim().toLowerCase().min(1).max(63).regex(/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/).brand().meta({ id: "DkimSelector" });
757
- const DkimGuidanceInputSchema = z.object({ selectors: z.array(DkimSelectorSchema).max(10).default([]) }).strict().superRefine((input, context) => {
758
- if (new Set(input.selectors).size !== input.selectors.length) context.addIssue({
759
- code: "custom",
760
- path: ["selectors"],
761
- message: "DKIM selectors must be unique"
762
- });
763
- }).meta({ id: "DkimGuidanceInput" });
764
- const Domain0DkimGuidanceOptionsSchema = z.object({
765
- enableDkim: z.boolean().default(false),
766
- dkimSelectors: z.array(DkimSelectorSchema).max(10).default([])
767
- }).strict().superRefine((input, context) => {
768
- if (new Set(input.dkimSelectors).size !== input.dkimSelectors.length) context.addIssue({
769
- code: "custom",
770
- path: ["dkimSelectors"],
771
- message: "DKIM selectors must be unique"
772
- });
773
- }).meta({ id: "Domain0DkimGuidanceOptions" });
774
- const GoogleWorkspaceEmailProviderSchema = z.object({
775
- id: z.literal("google_workspace"),
776
- name: z.literal("Google Workspace"),
777
- guideUrl: z.literal("https://support.google.com/a/answer/174124")
778
- }).strict();
779
- const Microsoft365EmailProviderSchema = z.object({
780
- id: z.literal("microsoft_365"),
781
- name: z.literal("Microsoft 365"),
782
- guideUrl: z.literal("https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dkim-configure")
783
- }).strict();
784
- const ZohoMailEmailProviderSchema = z.object({
785
- id: z.literal("zoho_mail"),
786
- name: z.literal("Zoho Mail"),
787
- guideUrl: z.literal("https://www.zoho.com/mail/help/adminconsole/dkim-configuration.html")
788
- }).strict();
789
- const EmailProviderSchema = z.discriminatedUnion("id", [
790
- GoogleWorkspaceEmailProviderSchema,
791
- Microsoft365EmailProviderSchema,
792
- ZohoMailEmailProviderSchema
793
- ]).meta({ id: "EmailProvider" });
794
- const EmailProviderDetectionStatusSchema = z.enum([
795
- "detected",
796
- "ambiguous",
797
- "unknown"
798
- ]).meta({ id: "EmailProviderDetectionStatus" });
799
- const DkimDnsRecordTypeSchema = z.enum(["TXT", "CNAME"]).meta({ id: "DkimDnsRecordType" });
800
- const DkimDnsEvidenceStatusSchema = z.enum([
801
- "record_observed",
802
- "no_record_observed",
803
- "not_checked",
804
- "lookup_unavailable"
805
- ]).meta({ id: "DkimDnsEvidenceStatus" });
806
- const DkimDnsRecordEvidenceSchema = z.object({
807
- selector: DkimSelectorSchema,
808
- types: z.array(DkimDnsRecordTypeSchema).min(1).max(2).refine((types) => new Set(types).size === types.length, "Observed DKIM DNS record types must be unique")
809
- }).strict().meta({ id: "DkimDnsRecordEvidence" });
810
- const DkimDnsEvidenceSchema = z.object({
811
- status: DkimDnsEvidenceStatusSchema,
812
- selectorsChecked: z.array(DkimSelectorSchema).max(12).refine((selectors) => new Set(selectors).size === selectors.length, "Checked DKIM selectors must be unique"),
813
- records: z.array(DkimDnsRecordEvidenceSchema).max(12)
814
- }).strict().superRefine((evidence, context) => {
815
- const checked = new Set(evidence.selectorsChecked);
816
- if (evidence.records.some((record) => !checked.has(record.selector))) context.addIssue({
817
- code: "custom",
818
- path: ["records"],
819
- message: "Observed records must belong to checked selectors"
820
- });
821
- if (evidence.status === "not_checked" && (evidence.selectorsChecked.length !== 0 || evidence.records.length !== 0)) context.addIssue({
822
- code: "custom",
823
- path: ["status"],
824
- message: "Not-checked evidence cannot include selector observations"
825
- });
826
- if (evidence.status === "record_observed" && evidence.records.length === 0) context.addIssue({
827
- code: "custom",
828
- path: ["records"],
829
- message: "Observed status requires at least one DNS record"
830
- });
831
- if (evidence.status !== "record_observed" && evidence.records.length !== 0) context.addIssue({
832
- code: "custom",
833
- path: ["records"],
834
- message: "Only observed status can include DNS records"
835
- });
836
- if (["no_record_observed", "lookup_unavailable"].includes(evidence.status) && evidence.selectorsChecked.length === 0) context.addIssue({
837
- code: "custom",
838
- path: ["selectorsChecked"],
839
- message: "A DNS lookup status requires at least one checked selector"
840
- });
841
- }).meta({ id: "DkimDnsEvidence" });
842
- const DkimGuidanceResponseSchema = z.object({
843
- domain: DomainNameSchema,
844
- detectionStatus: EmailProviderDetectionStatusSchema,
845
- candidates: z.array(EmailProviderSchema).max(3),
846
- provider: EmailProviderSchema.optional(),
847
- mxHosts: z.array(DomainNameSchema).max(20).refine((hosts) => new Set(hosts).size === hosts.length, "MX hosts must be unique"),
848
- dkimDns: DkimDnsEvidenceSchema,
849
- observedAt: IsoDateTimeSchema
850
- }).strict().superRefine((result, context) => {
851
- const candidateIds = result.candidates.map((candidate) => candidate.id);
852
- if (new Set(candidateIds).size !== candidateIds.length) context.addIssue({
853
- code: "custom",
854
- path: ["candidates"],
855
- message: "Email provider candidates must be unique"
856
- });
857
- if (result.detectionStatus === "detected" && (result.candidates.length !== 1 || result.provider?.id !== result.candidates[0]?.id)) context.addIssue({
858
- code: "custom",
859
- path: ["provider"],
860
- message: "Detected status requires exactly one matching provider"
861
- });
862
- if (result.detectionStatus === "ambiguous" && (result.candidates.length < 2 || result.provider !== void 0)) context.addIssue({
863
- code: "custom",
864
- path: ["candidates"],
865
- message: "Ambiguous status requires multiple candidates and no resolved provider"
866
- });
867
- if (result.detectionStatus === "unknown" && (result.candidates.length !== 0 || result.provider !== void 0)) context.addIssue({
868
- code: "custom",
869
- path: ["candidates"],
870
- message: "Unknown status cannot include an email provider"
871
- });
872
- }).meta({ id: "DkimGuidanceResponse" });
873
- //#endregion
874
- //#region src/contracts/connect-events.ts
875
- const Domain0ConnectStepSchema = z.union([z.enum([
876
- "loading",
877
- "provider_detection",
878
- "provider_selection",
879
- "cancellation_confirmation"
880
- ]), ConnectionStateSchema]).meta({ id: "Domain0ConnectStep" });
881
- const Domain0ConnectCloseReasonSchema = z.enum([
882
- "close_button",
883
- "escape",
884
- "programmatic",
885
- "destroyed",
886
- "success"
887
- ]).meta({ id: "Domain0ConnectCloseReason" });
888
- const ActiveConnectionSchema = ConnectionSchema.and(z.object({ state: z.literal("active") }));
889
- const ManualConnectionSchema = ConnectionSchema.and(z.object({ state: z.literal("manual_required") }));
890
- const Domain0ConnectSuccessEventSchema = z.object({
891
- type: z.literal("success"),
892
- connection: ActiveConnectionSchema
893
- }).strict().meta({ id: "Domain0ConnectSuccessEvent" });
894
- const Domain0ConnectCloseEventSchema = z.object({
895
- type: z.literal("close"),
896
- reason: Domain0ConnectCloseReasonSchema,
897
- connection: ConnectionSchema.optional(),
898
- step: Domain0ConnectStepSchema.optional()
899
- }).strict().meta({ id: "Domain0ConnectCloseEvent" });
900
- const Domain0ConnectStepChangeEventSchema = z.object({
901
- type: z.literal("step_change"),
902
- step: Domain0ConnectStepSchema,
903
- previousStep: Domain0ConnectStepSchema.optional(),
904
- connection: ConnectionSchema.optional()
905
- }).strict().meta({ id: "Domain0ConnectStepChangeEvent" });
906
- const Domain0ManualSetupDocumentationClickEventSchema = z.object({
907
- type: z.literal("manual_setup_documentation_click"),
908
- connection: ManualConnectionSchema
909
- }).strict().meta({ id: "Domain0ManualSetupDocumentationClickEvent" });
910
- const Domain0RequestCloseEventSchema = z.object({
911
- type: z.literal("request_close"),
912
- connection: ConnectionSchema.optional(),
913
- step: Domain0ConnectStepSchema
914
- }).strict().meta({ id: "Domain0RequestCloseEvent" });
915
- const Domain0SharedFlowSentEventSchema = z.object({
916
- type: z.literal("shared_flow_sent"),
917
- connection: ManualConnectionSchema,
918
- sharedFlowId: SharedFlowIdSchema,
919
- url: SharedFlowInvitationUrlSchema,
920
- expiresAt: IsoDateTimeSchema
921
- }).strict().meta({ id: "Domain0SharedFlowSentEvent" });
922
- const Domain0DkimSetupDocumentationClickEventSchema = z.object({
923
- type: z.literal("dkim_setup_documentation_click"),
924
- connection: ActiveConnectionSchema,
925
- emailProvider: EmailProviderSchema
926
- }).strict().meta({ id: "Domain0DkimSetupDocumentationClickEvent" });
927
- const Domain0ConnectEventSchema = z.discriminatedUnion("type", [
928
- Domain0ConnectSuccessEventSchema,
929
- Domain0ConnectCloseEventSchema,
930
- Domain0ConnectStepChangeEventSchema,
931
- Domain0ManualSetupDocumentationClickEventSchema,
932
- Domain0RequestCloseEventSchema,
933
- Domain0SharedFlowSentEventSchema,
934
- Domain0DkimSetupDocumentationClickEventSchema
935
- ]).meta({ id: "Domain0ConnectEvent" });
936
- //#endregion
937
- //#region src/contracts/setup-policy.ts
938
- const Domain0SetupPolicySchema = z.object({ mode: z.enum(["automatic", "manual"]).default("automatic") }).strict();
939
- //#endregion
940
- //#region src/contracts/white-label.ts
941
- const opaqueHexColorPattern = /^#[0-9A-F]{6}$/;
942
- const backdropHexColorPattern = /^#[0-9A-F]{8}$/;
943
- const OpaqueHexColorSchema = z.string().trim().toUpperCase().regex(opaqueHexColorPattern, "Expected an opaque #RRGGBB color");
944
- const BackdropHexColorSchema = z.string().trim().toUpperCase().regex(backdropHexColorPattern, "Expected a #RRGGBBAA backdrop color");
945
- const WhiteLabelTextSchema = z.string().trim().min(1).max(500).refine((value) => !/[<>\u0000-\u001F\u007F]/.test(value), "White-label copy must be plain text without markup or control characters");
946
- const Domain0ApplicationNameSchema = WhiteLabelTextSchema.max(120).meta({ id: "Domain0ApplicationName" });
947
- const Domain0WhiteLabelLogoUrlSchema = z.string().trim().min(1).max(2048).refine((value) => {
948
- try {
949
- const parsed = new URL(value);
950
- return parsed.protocol === "https:" && parsed.username === "" && parsed.password === "";
951
- } catch {
952
- return false;
953
- }
954
- }, "Logo must be an HTTPS URL without embedded credentials").meta({ id: "Domain0WhiteLabelLogoUrl" });
955
- function copyWithPlaceholders(...allowed) {
956
- return WhiteLabelTextSchema.refine((value) => {
957
- const withoutAllowedPlaceholders = allowed.reduce((copy, placeholder) => copy.replaceAll(placeholder, ""), value);
958
- return !/[{}]/.test(withoutAllowedPlaceholders);
959
- }, `Only these placeholders are allowed: ${allowed.join(", ") || "none"}`);
960
- }
961
- function localizedCopy(message) {
962
- const localized = z.object({
963
- en: message,
964
- es: message.optional(),
965
- pt: message.optional(),
966
- "pt-br": message.optional(),
967
- "pt-pt": message.optional(),
968
- fr: message.optional(),
969
- it: message.optional(),
970
- de: message.optional(),
971
- nl: message.optional(),
972
- pl: message.optional(),
973
- tr: message.optional(),
974
- ja: message.optional(),
975
- da: message.optional(),
976
- sv: message.optional()
977
- }).strict();
978
- return z.union([message.transform((en) => ({ en })), localized]);
979
- }
980
- function colorContrastRatio(foreground, background) {
981
- return parsedColorContrastRatio(OpaqueHexColorSchema.parse(foreground), OpaqueHexColorSchema.parse(background));
982
- }
983
- function parsedColorContrastRatio(foreground, background) {
984
- const foregroundLuminance = relativeLuminance(foreground);
985
- const backgroundLuminance = relativeLuminance(background);
986
- const lighter = Math.max(foregroundLuminance, backgroundLuminance);
987
- const darker = Math.min(foregroundLuminance, backgroundLuminance);
988
- return (lighter + .05) / (darker + .05);
989
- }
990
- function isSafeFontFamilyStack(value) {
991
- const families = value.split(",");
992
- return families.length <= 10 && families.every((family) => {
993
- const trimmed = family.trim();
994
- if (trimmed.length === 0) return false;
995
- const quote = trimmed.at(0);
996
- if (quote === "\"" || quote === "'") return trimmed.at(-1) === quote && /^[A-Za-z0-9 -]+$/.test(trimmed.slice(1, -1));
997
- return /^-?[A-Za-z][A-Za-z0-9 -]*$/.test(trimmed);
998
- });
999
- }
1000
- function relativeLuminance(color) {
1001
- const [red, green, blue] = [
1002
- 1,
1003
- 3,
1004
- 5
1005
- ].map((start) => Number.parseInt(color.slice(start, start + 2), 16) / 255).map((channel) => channel <= .04045 ? channel / 12.92 : ((channel + .055) / 1.055) ** 2.4);
1006
- return .2126 * red + .7152 * green + .0722 * blue;
1007
- }
1008
- const contrastPairs = [
1009
- {
1010
- foreground: "text",
1011
- background: "surface",
1012
- minimum: 4.5,
1013
- purpose: "body text"
1014
- },
1015
- {
1016
- foreground: "mutedText",
1017
- background: "surface",
1018
- minimum: 4.5,
1019
- purpose: "secondary text"
1020
- },
1021
- {
1022
- foreground: "onPrimary",
1023
- background: "primary",
1024
- minimum: 4.5,
1025
- purpose: "primary control text"
1026
- },
1027
- {
1028
- foreground: "danger",
1029
- background: "surface",
1030
- minimum: 4.5,
1031
- purpose: "error text"
1032
- },
1033
- {
1034
- foreground: "onDanger",
1035
- background: "danger",
1036
- minimum: 4.5,
1037
- purpose: "danger control text"
1038
- },
1039
- {
1040
- foreground: "link",
1041
- background: "surface",
1042
- minimum: 4.5,
1043
- purpose: "link text"
1044
- },
1045
- {
1046
- foreground: "border",
1047
- background: "surface",
1048
- minimum: 3,
1049
- purpose: "control boundaries"
1050
- },
1051
- {
1052
- foreground: "primary",
1053
- background: "surface",
1054
- minimum: 3,
1055
- purpose: "primary control boundaries"
1056
- },
1057
- {
1058
- foreground: "focus",
1059
- background: "surface",
1060
- minimum: 3,
1061
- purpose: "focus indicators"
1062
- }
1063
- ];
1064
- const lightPaletteDefaults = {
1065
- surface: "#FFFFFF",
1066
- text: "#0A0A0A",
1067
- mutedText: "#6B6B6B",
1068
- border: "#73737C",
1069
- primary: "#0A0A0A",
1070
- onPrimary: "#FFFFFF",
1071
- link: "#2B21FF",
1072
- focus: "#2B21FF",
1073
- danger: "#B3261E",
1074
- onDanger: "#FFFFFF"
1075
- };
1076
- const darkPaletteDefaults = {
1077
- surface: "#111827",
1078
- text: "#F9FAFB",
1079
- mutedText: "#D1D5DB",
1080
- border: "#D1D5DB",
1081
- primary: "#BFDBFE",
1082
- onPrimary: "#172554",
1083
- link: "#BFDBFE",
1084
- focus: "#FBBF24",
1085
- danger: "#FCA5A5",
1086
- onDanger: "#450A0A"
1087
- };
1088
- function themePaletteSchema(defaults) {
1089
- return z.object({
1090
- surface: OpaqueHexColorSchema.default(defaults.surface),
1091
- text: OpaqueHexColorSchema.default(defaults.text),
1092
- mutedText: OpaqueHexColorSchema.default(defaults.mutedText),
1093
- border: OpaqueHexColorSchema.default(defaults.border),
1094
- primary: OpaqueHexColorSchema.default(defaults.primary),
1095
- onPrimary: OpaqueHexColorSchema.default(defaults.onPrimary),
1096
- link: OpaqueHexColorSchema.default(defaults.link),
1097
- focus: OpaqueHexColorSchema.default(defaults.focus),
1098
- danger: OpaqueHexColorSchema.default(defaults.danger),
1099
- onDanger: OpaqueHexColorSchema.default(defaults.onDanger)
1100
- }).strict().superRefine((palette, context) => {
1101
- for (const pair of contrastPairs) {
1102
- const ratio = parsedColorContrastRatio(palette[pair.foreground], palette[pair.background]);
1103
- if (ratio < pair.minimum) context.addIssue({
1104
- code: "custom",
1105
- path: [pair.foreground],
1106
- message: `${pair.purpose} requires ${pair.minimum}:1 contrast against ${pair.background}; received ${ratio.toFixed(2)}:1`
1107
- });
1108
- }
1109
- });
1110
- }
1111
- const LightThemePaletteSchema = themePaletteSchema(lightPaletteDefaults);
1112
- const DarkThemePaletteSchema = themePaletteSchema(darkPaletteDefaults);
1113
- const Domain0WhiteLabelThemeSchema = z.object({
1114
- colorMode: z.enum([
1115
- "light",
1116
- "dark",
1117
- "system"
1118
- ]).default("light"),
1119
- light: LightThemePaletteSchema.prefault({}),
1120
- dark: DarkThemePaletteSchema.prefault({}),
1121
- backdrop: BackdropHexColorSchema.default("#2B21FF26"),
1122
- widthPx: z.number().int().min(320).max(960).default(672),
1123
- dialogRadiusPx: z.number().int().min(0).max(48).default(20),
1124
- buttonRadiusPx: z.number().int().min(0).max(999).default(999),
1125
- inputRadiusPx: z.number().int().min(0).max(32).default(12),
1126
- fontFamily: z.string().trim().min(1).max(200).refine(isSafeFontFamilyStack, "Use a comma-separated system font stack without URLs or CSS syntax").default("\"PP Neue Montreal\", \"Inter Tight\", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif"),
1127
- fontWeight: z.number().int().min(100).max(900).multipleOf(50).default(400),
1128
- boldFontWeight: z.number().int().min(100).max(900).multipleOf(50).default(500)
1129
- }).strict().superRefine((theme, context) => {
1130
- if (theme.boldFontWeight < theme.fontWeight) context.addIssue({
1131
- code: "custom",
1132
- path: ["boldFontWeight"],
1133
- message: "Bold font weight must be at least the normal font weight"
1134
- });
1135
- });
1136
- const Domain0WhiteLabelCopySchema = z.object({
1137
- initialSubtitle: localizedCopy(copyWithPlaceholders()).optional(),
1138
- providerLoginMessage: localizedCopy(copyWithPlaceholders("{PROVIDER}")).optional(),
1139
- successTitle: localizedCopy(copyWithPlaceholders("{DOMAIN}")).optional(),
1140
- successDescription: localizedCopy(copyWithPlaceholders("{DOMAIN}")).optional(),
1141
- successButton: localizedCopy(copyWithPlaceholders()).optional(),
1142
- manuallyScreen: z.object({
1143
- disableManualSetupDocumentationLink: z.boolean().default(false),
1144
- stepByStepGuide: localizedCopy(copyWithPlaceholders()).optional()
1145
- }).strict().prefault({})
1146
- }).strict();
1147
- const DisabledControlSchema = z.object({ disable: z.boolean().default(false) }).strict();
1148
- const Domain0WhiteLabelCustomPropertiesSchema = z.object({
1149
- manualConfiguration: z.object({ disableScreen: z.boolean().default(false) }).strict().prefault({}),
1150
- providerLogin: z.object({
1151
- forwardLink: DisabledControlSchema.prefault({}),
1152
- gotoManualLink: DisabledControlSchema.prefault({})
1153
- }).strict().prefault({})
1154
- }).strict();
1155
- const Domain0WhiteLabelSchema = z.object({
1156
- theme: Domain0WhiteLabelThemeSchema.prefault({}),
1157
- copy: Domain0WhiteLabelCopySchema.prefault({}),
1158
- logo: Domain0WhiteLabelLogoUrlSchema.optional(),
1159
- logoBackgroundColor: OpaqueHexColorSchema.optional(),
1160
- removeLogoBorder: z.boolean().default(false),
1161
- hideCompanyLogo: z.boolean().default(false),
1162
- hideCompanyName: z.boolean().default(false),
1163
- removeShareLogin: z.boolean().default(false),
1164
- skipCongratulationsScreen: z.boolean().default(false),
1165
- customProperties: Domain0WhiteLabelCustomPropertiesSchema.prefault({})
1166
- }).strict();
1167
- //#endregion
1168
- //#region src/contracts/manual-setup-documentation.ts
1169
- const ManualSetupDocumentationUrlSchema = z.url({ protocol: /^https$/ }).max(2048).refine((value) => {
1170
- const url = new URL(value);
1171
- return url.username === "" && url.password === "";
1172
- }, "Manual setup documentation URL must not contain credentials").brand().meta({ id: "ManualSetupDocumentationUrl" });
1173
- //#endregion
1174
- //#region src/contracts/connect-configuration.ts
1175
- const Domain0ConnectConfigurationSchema = z.object({
1176
- applicationName: Domain0ApplicationNameSchema.optional(),
1177
- whiteLabel: Domain0WhiteLabelSchema.prefault({}),
1178
- setupPolicy: Domain0SetupPolicySchema.prefault({}),
1179
- dkim: Domain0DkimGuidanceOptionsSchema.prefault({}),
1180
- manualSetupDocumentation: ManualSetupDocumentationUrlSchema.optional()
1181
- }).strict().superRefine((configuration, context) => {
1182
- const { customProperties } = configuration.whiteLabel;
1183
- const forcedManual = configuration.setupPolicy.mode === "manual";
1184
- if (forcedManual && customProperties.manualConfiguration.disableScreen) context.addIssue({
1185
- code: "custom",
1186
- path: [
1187
- "whiteLabel",
1188
- "customProperties",
1189
- "manualConfiguration",
1190
- "disableScreen"
1191
- ],
1192
- message: "Forced manual setup requires the manual configuration screen"
1193
- });
1194
- if (forcedManual && customProperties.providerLogin.gotoManualLink.disable) context.addIssue({
1195
- code: "custom",
1196
- path: [
1197
- "whiteLabel",
1198
- "customProperties",
1199
- "providerLogin",
1200
- "gotoManualLink",
1201
- "disable"
1202
- ],
1203
- message: "Forced manual setup cannot disable entry into manual configuration"
1204
- });
1205
- if (configuration.dkim.enableDkim && configuration.whiteLabel.skipCongratulationsScreen) context.addIssue({
1206
- code: "custom",
1207
- path: ["whiteLabel", "skipCongratulationsScreen"],
1208
- message: "DKIM guidance requires the success screen"
1209
- });
1210
- }).meta({ id: "Domain0ConnectConfiguration" });
1211
- //#endregion
1212
- //#region src/contracts/conformance.ts
1213
- const CompiledProviderIdSchema = z.enum([
1214
- "alibaba-cloud",
1215
- "all-inkl",
1216
- "amazon-route-53",
1217
- "cloudflare",
1218
- "cloudns",
1219
- "digitalocean",
1220
- "dnsimple",
1221
- "dreamhost",
1222
- "dynadot",
1223
- "easydns",
1224
- "gandi",
1225
- "godaddy",
1226
- "hetzner",
1227
- "hostgator",
1228
- "hostinger",
1229
- "hosting-com",
1230
- "inmotion-hosting",
1231
- "ionos",
1232
- "name-com",
1233
- "namecheap",
1234
- "namesilo",
1235
- "netlify",
1236
- "o2switch",
1237
- "openprovider",
1238
- "opensrs",
1239
- "ovh",
1240
- "porkbun",
1241
- "simply",
1242
- "spaceship",
1243
- "transip",
1244
- "united-domains",
1245
- "vercel",
1246
- "wix"
1247
- ]).meta({ id: "CompiledProviderId" });
1248
- const ProviderConformanceCheckNameSchema = z.enum([
1249
- "authenticated_snapshot",
1250
- "reserved_name_available",
1251
- "create_sibling",
1252
- "create_target",
1253
- "rrset_sibling_preservation",
1254
- "idempotent_replay",
1255
- "replace_target",
1256
- "authoritative_propagation",
1257
- "delete_target",
1258
- "scoped_cleanup"
1259
- ]).meta({ id: "ProviderConformanceCheckName" });
1260
- const expectedProviderConformanceChecks = [
1261
- "authenticated_snapshot",
1262
- "reserved_name_available",
1263
- "create_sibling",
1264
- "create_target",
1265
- "rrset_sibling_preservation",
1266
- "idempotent_replay",
1267
- "replace_target",
1268
- "authoritative_propagation",
1269
- "delete_target",
1270
- "scoped_cleanup"
1271
- ];
1272
- const ProviderConformanceCheckSchema = z.object({ name: ProviderConformanceCheckNameSchema }).strict();
1273
- const SourceRevisionSchema = z.union([z.literal("unknown"), z.string().regex(/^[a-f0-9]{40,64}$/)]);
1274
- const ProviderConformanceEvidenceSchema = z.object({
1275
- schemaVersion: z.literal(1),
1276
- providerId: CompiledProviderIdSchema,
1277
- adapterVersion: z.string().min(1).max(200).refine(isTrimmedSingleLine),
1278
- sourceRevision: SourceRevisionSchema,
1279
- sourceModified: z.boolean(),
1280
- binarySha256: z.string().regex(/^[a-f0-9]{64}$/),
1281
- zone: DomainNameSchema,
1282
- runId: z.string().regex(/^[a-f0-9]{16,64}$/),
1283
- host: z.string(),
1284
- startedAt: IsoDateTimeSchema,
1285
- completedAt: IsoDateTimeSchema,
1286
- passed: z.boolean(),
1287
- checks: z.array(ProviderConformanceCheckSchema).max(expectedProviderConformanceChecks.length),
1288
- cleanupAttempted: z.boolean(),
1289
- cleanupCompleted: z.boolean()
1290
- }).strict().superRefine((evidence, context) => {
1291
- if (evidence.host !== `_domain0-conformance-${evidence.runId}`) context.addIssue({
1292
- code: "custom",
1293
- path: ["host"],
1294
- message: "Conformance hostname must be derived from the random run ID"
1295
- });
1296
- if (Date.parse(evidence.completedAt) < Date.parse(evidence.startedAt)) context.addIssue({
1297
- code: "custom",
1298
- path: ["completedAt"],
1299
- message: "Conformance completion must not precede its start"
1300
- });
1301
- const names = evidence.checks.map((check) => check.name);
1302
- if (!validCheckSequence(names)) context.addIssue({
1303
- code: "custom",
1304
- path: ["checks"],
1305
- message: "Conformance checks must be an ordered prefix followed optionally by scoped cleanup"
1306
- });
1307
- const cleanupCheck = names.includes("scoped_cleanup");
1308
- if (evidence.cleanupCompleted && !evidence.cleanupAttempted || cleanupCheck !== evidence.cleanupCompleted) context.addIssue({
1309
- code: "custom",
1310
- path: ["cleanupCompleted"],
1311
- message: "Completed cleanup requires an attempted cleanup and the scoped-cleanup check"
1312
- });
1313
- }).meta({ id: "ProviderConformanceEvidence" });
1314
- const VerifiedProviderConformanceEvidenceSchema = ProviderConformanceEvidenceSchema.refine((evidence) => evidence.passed && !evidence.sourceModified && evidence.sourceRevision !== "unknown" && evidence.cleanupAttempted && evidence.cleanupCompleted && evidence.checks.every((check, index) => check.name === expectedProviderConformanceChecks[index]) && evidence.checks.length === expectedProviderConformanceChecks.length, "Verified live-suite evidence requires clean traceable source, every ordered check, and completed cleanup").meta({ id: "VerifiedProviderConformanceEvidence" });
1315
- function validCheckSequence(checks) {
1316
- let position = 0;
1317
- let cleanupSeen = false;
1318
- for (const check of checks) {
1319
- if (check === "scoped_cleanup") {
1320
- if (cleanupSeen) return false;
1321
- cleanupSeen = true;
1322
- continue;
1323
- }
1324
- if (cleanupSeen || check !== expectedProviderConformanceChecks[position]) return false;
1325
- position += 1;
1326
- }
1327
- return true;
1328
- }
1329
- function isTrimmedSingleLine(value) {
1330
- return value.trim() === value && !/[\u0000\r\n]/.test(value);
1331
- }
1332
- //#endregion
1333
- //#region src/contracts/domain-check.ts
1334
- const DomainDelegationStatusSchema = z.enum([
1335
- "delegated",
1336
- "undelegated",
1337
- "unknown"
1338
- ]).meta({ id: "DomainDelegationStatus" });
1339
- const DomainSetupSupportSchema = z.enum([
1340
- "automatic",
1341
- "manual",
1342
- "unavailable",
1343
- "ambiguous",
1344
- "unknown"
1345
- ]).meta({ id: "DomainSetupSupport" });
1346
- const RecordConflictReasonSchema = z.enum([
1347
- "same_name_and_type",
1348
- "cname_collision",
1349
- "mx_set_collision",
1350
- "spf_collision",
1351
- "ns_delegation"
1352
- ]).meta({ id: "RecordConflictReason" });
1353
- const CheckDomainInputSchema = z.object({
1354
- domain: DomainNameSchema,
1355
- records: z.array(ResolvedDnsRecordSchema).max(100).default([]),
1356
- checkConflicts: z.boolean().default(false)
1357
- }).strict().superRefine((input, context) => {
1358
- if (input.checkConflicts && input.records.length === 0) context.addIssue({
1359
- code: "custom",
1360
- path: ["records"],
1361
- message: "Record conflict analysis requires at least one requested record"
1362
- });
1363
- }).meta({ id: "CheckDomainInput" });
1364
- const DomainProviderCandidateSchema = z.object({
1365
- provider: ProviderSchema,
1366
- confidence: z.number().min(0).max(1),
1367
- exact: z.boolean()
1368
- }).strict().meta({ id: "DomainProviderCandidate" });
1369
- const DomainRecordConflictSchema = z.object({
1370
- requested: ResolvedDnsRecordSchema,
1371
- existing: z.array(ResolvedDnsRecordSchema).max(1e3),
1372
- reasons: z.array(RecordConflictReasonSchema).min(1).max(5).refine((reasons) => new Set(reasons).size === reasons.length, "Conflict reasons must be unique")
1373
- }).strict().meta({ id: "DomainRecordConflict" });
1374
- const ConflictAnalysisSchema = z.object({
1375
- status: z.enum([
1376
- "not_requested",
1377
- "complete",
1378
- "partial"
1379
- ]),
1380
- authoritativeServers: z.number().int().min(0).max(16),
1381
- respondingServers: z.number().int().min(0).max(16),
1382
- conflicts: z.array(DomainRecordConflictSchema).max(100)
1383
- }).strict().superRefine((analysis, context) => {
1384
- if (analysis.respondingServers > analysis.authoritativeServers) context.addIssue({
1385
- code: "custom",
1386
- path: ["respondingServers"],
1387
- message: "Responding nameservers cannot exceed authoritative nameservers"
1388
- });
1389
- if (analysis.status === "complete" && analysis.respondingServers !== analysis.authoritativeServers) context.addIssue({
1390
- code: "custom",
1391
- path: ["status"],
1392
- message: "Complete analysis requires every authoritative nameserver to respond"
1393
- });
1394
- if (analysis.status === "partial" && (analysis.respondingServers === 0 || analysis.respondingServers >= analysis.authoritativeServers)) context.addIssue({
1395
- code: "custom",
1396
- path: ["status"],
1397
- message: "Partial analysis requires some but not all authoritative nameservers to respond"
1398
- });
1399
- if (analysis.status === "not_requested" && analysis.conflicts.length !== 0) context.addIssue({
1400
- code: "custom",
1401
- path: ["conflicts"],
1402
- message: "Conflict results cannot exist when analysis was not requested"
1403
- });
1404
- }).meta({ id: "ConflictAnalysis" });
1405
- const CheckDomainResponseSchema = z.object({
1406
- domain: DomainNameSchema,
1407
- delegationStatus: DomainDelegationStatusSchema,
1408
- candidates: z.array(DomainProviderCandidateSchema).max(65),
1409
- provider: ProviderSchema.optional(),
1410
- setupSupport: DomainSetupSupportSchema,
1411
- conflictAnalysis: ConflictAnalysisSchema
1412
- }).strict().superRefine((result, context) => {
1413
- const candidateIds = result.candidates.map((candidate) => candidate.provider.id);
1414
- if (new Set(candidateIds).size !== candidateIds.length) context.addIssue({
1415
- code: "custom",
1416
- path: ["candidates"],
1417
- message: "Provider candidates must be unique"
1418
- });
1419
- if (result.delegationStatus === "undelegated" && (result.candidates.length !== 0 || result.provider !== void 0 || result.setupSupport !== "unavailable")) context.addIssue({
1420
- code: "custom",
1421
- path: ["delegationStatus"],
1422
- message: "Undelegated domains cannot have provider support"
1423
- });
1424
- if (result.provider !== void 0 && !result.candidates.some((candidate) => candidate.exact && candidate.provider.id === result.provider?.id)) context.addIssue({
1425
- code: "custom",
1426
- path: ["provider"],
1427
- message: "Resolved provider must be an exact provider candidate"
1428
- });
1429
- if (["automatic", "manual"].includes(result.setupSupport) && result.provider === void 0) context.addIssue({
1430
- code: "custom",
1431
- path: ["setupSupport"],
1432
- message: "Available setup support requires a resolved provider"
1433
- });
1434
- if (result.setupSupport === "automatic" && !result.provider?.availableAuthorizationMethods.some((method) => method !== "manual")) context.addIssue({
1435
- code: "custom",
1436
- path: ["setupSupport"],
1437
- message: "Automatic setup requires a configured non-manual authorization method"
1438
- });
1439
- if (result.setupSupport === "manual" && (result.provider?.availableAuthorizationMethods.length !== 1 || result.provider.availableAuthorizationMethods[0] !== "manual")) context.addIssue({
1440
- code: "custom",
1441
- path: ["setupSupport"],
1442
- message: "Manual setup requires the manual authorization method"
1443
- });
1444
- if (result.setupSupport === "ambiguous" && result.candidates.length === 0) context.addIssue({
1445
- code: "custom",
1446
- path: ["candidates"],
1447
- message: "Ambiguous setup requires provider candidates"
1448
- });
1449
- if (result.setupSupport === "unknown" && result.candidates.length !== 0) context.addIssue({
1450
- code: "custom",
1451
- path: ["candidates"],
1452
- message: "Unknown setup cannot include provider candidates"
1453
- });
1454
- if (["ambiguous", "unknown"].includes(result.setupSupport) && result.provider !== void 0) context.addIssue({
1455
- code: "custom",
1456
- path: ["provider"],
1457
- message: "Ambiguous or unknown support cannot resolve one provider"
1458
- });
1459
- }).meta({ id: "CheckDomainResponse" });
1460
- //#endregion
1461
- //#region src/contracts/error.ts
1462
- const Domain0ErrorCodeSchema = z.enum([
1463
- "invalid_request",
1464
- "unauthorized",
1465
- "forbidden",
1466
- "not_found",
1467
- "conflict",
1468
- "rate_limited",
1469
- "dns_unavailable",
1470
- "provider_unavailable",
1471
- "provider_authorization_failed",
1472
- "provider_limitation",
1473
- "plan_expired",
1474
- "propagation_pending",
1475
- "internal_error"
1476
- ]).meta({ id: "Domain0ErrorCode" });
1477
- const Domain0ErrorResponseSchema = z.object({ error: z.object({
1478
- code: Domain0ErrorCodeSchema,
1479
- message: z.string().min(1),
1480
- requestId: z.string().min(1),
1481
- retryable: z.boolean(),
1482
- details: z.record(z.string(), z.unknown()).optional()
1483
- }).strict() }).strict().meta({ id: "ErrorResponse" });
1484
- //#endregion
1485
- //#region src/contracts/localization.ts
1486
- /** Locale identifiers supported by Entri Connect's public configuration contract. */
1487
- const domain0Locales = [
1488
- "en",
1489
- "es",
1490
- "pt",
1491
- "pt-br",
1492
- "pt-pt",
1493
- "fr",
1494
- "it",
1495
- "de",
1496
- "nl",
1497
- "pl",
1498
- "tr",
1499
- "ja",
1500
- "da",
1501
- "sv"
1502
- ];
1503
- const Domain0LocaleSchema = z.enum(domain0Locales).meta({ id: "Domain0Locale" });
1504
- //#endregion
1505
- //#region src/contracts/platform.ts
1506
- /** Public platform request. Application and tenant identity come from the API key. */
1507
- const PlatformCreateConnectionInputSchema = z.strictObject({ intent: DnsIntentSchema }).meta({ id: "PlatformCreateConnectionInput" });
1508
- //#endregion
1509
- //#region src/contracts/webhook.ts
1510
- const Domain0WebhookEventTypeSchema = z.enum([
1511
- "connection.requested",
1512
- "provider.detection_started",
1513
- "provider.selected",
1514
- "authorization.required",
1515
- "domain_connect.started",
1516
- "domain_connect.submitted",
1517
- "authorization.completed",
1518
- "connection.planning_started",
1519
- "connection.plan_prepared",
1520
- "connection.planning_restarted",
1521
- "connection.already_configured",
1522
- "connection.plan_confirmed",
1523
- "connection.changes_applied",
1524
- "connection.propagation_checked",
1525
- "connection.propagation_timed_out",
1526
- "connection.activated",
1527
- "connection.manual_required",
1528
- "connection.manual_submitted",
1529
- "connection.failed_retryable",
1530
- "connection.retry_started",
1531
- "connection.cancelled"
1532
- ]).meta({ id: "Domain0WebhookEventType" });
1533
- const Domain0WebhookEventIdSchema = z.string().regex(/^[0-9a-f]{64}$/).brand().meta({ id: "Domain0WebhookEventId" });
1534
- const Domain0WebhookAttributesSchema = z.record(z.string().min(1).max(100), z.string().max(4e3)).superRefine((attributes, context) => {
1535
- if (Object.keys(attributes).length > 64) context.addIssue({
1536
- code: "custom",
1537
- message: "Webhook attributes must contain at most 64 entries"
1538
- });
1539
- }).meta({ id: "Domain0WebhookAttributes" });
1540
- const Domain0WebhookEventSchema = z.strictObject({
1541
- schemaVersion: z.literal(1),
1542
- eventId: Domain0WebhookEventIdSchema,
1543
- type: Domain0WebhookEventTypeSchema,
1544
- connectionId: ConnectionIdSchema,
1545
- applicationId: ApplicationIdSchema,
1546
- tenantId: TenantIdSchema,
1547
- sequence: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
1548
- occurredAt: IsoDateTimeSchema,
1549
- attributes: Domain0WebhookAttributesSchema
1550
- }).meta({ id: "Domain0WebhookEvent" });
1551
- const Domain0WebhookVerificationErrorCodeSchema = z.enum([
1552
- "invalid_headers",
1553
- "stale_timestamp",
1554
- "invalid_signature",
1555
- "invalid_payload",
1556
- "crypto_unavailable"
1557
- ]).meta({ id: "Domain0WebhookVerificationErrorCode" });
1558
- var Domain0WebhookVerificationError = class extends Error {
1559
- code;
1560
- name = "Domain0WebhookVerificationError";
1561
- constructor(code, message, options) {
1562
- super(message, options);
1563
- this.code = code;
1564
- }
1565
- };
1566
- const DOMAIN0_WEBHOOK_HEADER_NAMES = {
1567
- eventId: "x-domain0-event-id",
1568
- eventType: "x-domain0-event-type",
1569
- deliveryAttempt: "x-domain0-delivery-attempt",
1570
- schemaVersion: "x-domain0-schema-version",
1571
- signatureKeyId: "x-domain0-signature-key-id",
1572
- timestamp: "x-domain0-timestamp",
1573
- signature: "x-domain0-signature"
1574
- };
1575
- const normalizedHeadersSchema = z.strictObject({
1576
- eventId: Domain0WebhookEventIdSchema,
1577
- eventType: z.string().regex(/^domain0\.[a-z_]+\.[a-z_]+$/).max(100),
1578
- deliveryAttempt: z.string().regex(/^[1-9][0-9]{0,8}$/).transform(Number),
1579
- schemaVersion: z.literal("1"),
1580
- signatureKeyId: z.string().regex(/^[A-Za-z0-9._-]{1,64}$/),
1581
- timestamp: z.string().regex(/^[0-9]{1,12}$/).transform(Number),
1582
- signature: z.string().regex(/^v1=[0-9a-f]{64}$/)
1583
- });
1584
- const textEncoder = new TextEncoder();
1585
- async function verifyDomain0Webhook(input) {
1586
- const body = typeof input.body === "string" ? textEncoder.encode(input.body) : new Uint8Array(input.body);
1587
- const maxBodyBytes = boundedPositiveInteger(input.maxBodyBytes ?? 1048576, 16777216);
1588
- if (!(body instanceof Uint8Array) || body.byteLength === 0 || body.byteLength > maxBodyBytes) throw verificationError("invalid_payload", "Webhook body is empty or exceeds the configured limit");
1589
- const headers = parseHeaders(input.headers);
1590
- const now = boundedNonNegativeInteger(input.nowUnixSeconds ?? Math.floor(Date.now() / 1e3), Number.MAX_SAFE_INTEGER);
1591
- const maxAgeSeconds = boundedPositiveInteger(input.maxAgeSeconds ?? 300, 86400);
1592
- if (Math.abs(now - headers.timestamp) > maxAgeSeconds) throw verificationError("stale_timestamp", "Webhook timestamp is outside the accepted replay window");
1593
- const secret = Object.prototype.hasOwnProperty.call(input.secretKeyring, headers.signatureKeyId) ? input.secretKeyring[headers.signatureKeyId] : void 0;
1594
- if (!(secret instanceof Uint8Array) || secret.byteLength !== 32) throw verificationError("invalid_signature", "Webhook signature is invalid");
1595
- const crypto = input.crypto ?? globalThis.crypto;
1596
- if (crypto?.subtle === void 0) throw verificationError("crypto_unavailable", "Web Crypto is unavailable");
1597
- const signature = hexToBytes(headers.signature.slice(3));
1598
- const prefix = textEncoder.encode(`v1.${headers.signatureKeyId}.${headers.timestamp}.`);
1599
- const signedBytes = new Uint8Array(prefix.byteLength + body.byteLength);
1600
- signedBytes.set(prefix);
1601
- signedBytes.set(body, prefix.byteLength);
1602
- const key = await crypto.subtle.importKey("raw", new Uint8Array(secret), {
1603
- name: "HMAC",
1604
- hash: "SHA-256"
1605
- }, false, ["verify"]);
1606
- if (!await crypto.subtle.verify("HMAC", key, new Uint8Array(signature), signedBytes)) throw verificationError("invalid_signature", "Webhook signature is invalid");
1607
- let decoded;
1608
- try {
1609
- const text = new TextDecoder("utf-8", { fatal: true }).decode(body);
1610
- decoded = JSON.parse(text);
1611
- } catch (error) {
1612
- throw verificationError("invalid_payload", "Verified webhook body is not valid UTF-8 JSON", error);
1613
- }
1614
- const parsed = Domain0WebhookEventSchema.safeParse(decoded);
1615
- if (!parsed.success) throw verificationError("invalid_payload", "Verified webhook body does not match schema version 1", parsed.error);
1616
- if (parsed.data.eventId !== headers.eventId || `domain0.${parsed.data.type}` !== headers.eventType || String(parsed.data.schemaVersion) !== headers.schemaVersion) throw verificationError("invalid_payload", "Verified webhook headers do not match the event body");
1617
- return parsed.data;
1618
- }
1619
- function parseHeaders(source) {
1620
- const values = {
1621
- eventId: void 0,
1622
- eventType: void 0,
1623
- deliveryAttempt: void 0,
1624
- schemaVersion: void 0,
1625
- signatureKeyId: void 0,
1626
- timestamp: void 0,
1627
- signature: void 0
1628
- };
1629
- if ("get" in source && typeof source.get === "function") for (const [key, name] of Object.entries(DOMAIN0_WEBHOOK_HEADER_NAMES)) values[key] = source.get(name) ?? void 0;
1630
- else {
1631
- const accepted = /* @__PURE__ */ new Map();
1632
- for (const key of Object.keys(DOMAIN0_WEBHOOK_HEADER_NAMES)) accepted.set(DOMAIN0_WEBHOOK_HEADER_NAMES[key], key);
1633
- const observed = /* @__PURE__ */ new Set();
1634
- for (const [providedName, providedValue] of Object.entries(source)) {
1635
- const name = providedName.toLowerCase();
1636
- const key = accepted.get(name);
1637
- if (key === void 0) continue;
1638
- if (observed.has(name) || typeof providedValue !== "string") throw verificationError("invalid_headers", "Webhook headers are missing, duplicated, or malformed");
1639
- observed.add(name);
1640
- values[key] = providedValue;
1641
- }
1642
- }
1643
- const parsed = normalizedHeadersSchema.safeParse(values);
1644
- if (!parsed.success) throw verificationError("invalid_headers", "Webhook headers are missing, duplicated, or malformed", parsed.error);
1645
- return parsed.data;
1646
- }
1647
- function boundedPositiveInteger(value, maximum) {
1648
- if (!Number.isSafeInteger(value) || value < 1 || value > maximum) throw verificationError("invalid_headers", "Webhook verification limits are invalid");
1649
- return value;
1650
- }
1651
- function boundedNonNegativeInteger(value, maximum) {
1652
- if (!Number.isSafeInteger(value) || value < 0 || value > maximum) throw verificationError("invalid_headers", "Webhook verification time is invalid");
1653
- return value;
1654
- }
1655
- function hexToBytes(value) {
1656
- const result = new Uint8Array(value.length / 2);
1657
- for (let index = 0; index < value.length; index += 2) result[index / 2] = Number.parseInt(value.slice(index, index + 2), 16);
1658
- return result;
1659
- }
1660
- function verificationError(code, message, cause) {
1661
- return new Domain0WebhookVerificationError(code, message, cause === void 0 ? void 0 : { cause });
1662
- }
1663
- //#endregion
1664
- export { AccessKeyCredentialsSchema, AccountTokenCredentialsSchema, AdvancedDmarcOptionsSchema, ApiTokenCredentialsSchema, ApplicationIdSchema, ApplyPlanInputSchema, AuthorizationMethodSchema, AuthorizeWithCredentialInputSchema, AwsSessionCredentialsSchema, CPanelCredentialsSchema, CancelConnectionInputSchema, ChangeActionSchema, ChangePlanSchema, CheckDomainInputSchema, CheckDomainResponseSchema, CheckRecordsInputSchema, CheckRecordsResponseSchema, CheckedRecordSchema, ClientCredentialsSchema, CommandIdSchema, CompiledProviderIdSchema, ConditionalDnsRecordsSchema, ConfirmPlanInputSchema, ConflictAnalysisSchema, ConflictPolicySchema, ConnectionFailureCodeSchema, ConnectionFailureSchema, ConnectionFlowIdSchema, ConnectionFlowResponseSchema, ConnectionFlowSchema, ConnectionFlowTargetInputSchema, ConnectionFlowTargetSchema, ConnectionIdSchema, ConnectionSchema, ConnectionStateSchema, CreateConnectionFlowInputSchema, CreateConnectionInputSchema, CreateConnectionResponseSchema, CreateSharedFlowInputSchema, CreateSharedFlowResponseSchema, DOMAIN0_WEBHOOK_HEADER_NAMES, DetectProviderResponseSchema, DkimDnsEvidenceSchema, DkimDnsEvidenceStatusSchema, DkimDnsRecordEvidenceSchema, DkimDnsRecordTypeSchema, DkimGuidanceInputSchema, DkimGuidanceResponseSchema, DkimSelectorSchema, DnsIntentSchema, DnsRecordSchema, DnsRecordTypeSchema, Domain0ApplicationNameSchema, Domain0ConnectCloseEventSchema, Domain0ConnectCloseReasonSchema, Domain0ConnectConfigurationSchema, Domain0ConnectEventSchema, Domain0ConnectStepChangeEventSchema, Domain0ConnectStepSchema, Domain0ConnectSuccessEventSchema, Domain0DkimGuidanceOptionsSchema, Domain0DkimSetupDocumentationClickEventSchema, Domain0ErrorCodeSchema, Domain0ErrorResponseSchema, Domain0LocaleSchema, Domain0ManualSetupDocumentationClickEventSchema, Domain0RequestCloseEventSchema, Domain0SetupPolicySchema, Domain0SharedFlowSentEventSchema, Domain0WebhookAttributesSchema, Domain0WebhookEventIdSchema, Domain0WebhookEventSchema, Domain0WebhookEventTypeSchema, Domain0WebhookVerificationError, Domain0WebhookVerificationErrorCodeSchema, Domain0WhiteLabelCopySchema, Domain0WhiteLabelCustomPropertiesSchema, Domain0WhiteLabelLogoUrlSchema, Domain0WhiteLabelSchema, Domain0WhiteLabelThemeSchema, DomainConnectTemplateSchema, DomainDelegationStatusSchema, DomainNameSchema, DomainProviderCandidateSchema, DomainRecordConflictSchema, DomainSetupSupportSchema, EmailProviderDetectionStatusSchema, EmailProviderSchema, ExistingRecordPolicySchema, GetConnectionResponseSchema, IsoDateTimeSchema, IssueConnectionTokenInputSchema, IssueConnectionTokenResponseSchema, ListProvidersResponseSchema, ManualSetupDocumentationUrlSchema, OAuthCallbackResponseSchema, OvhCredentialsSchema, PlanWarningCodeSchema, PlannedChangeSchema, PlatformCreateConnectionInputSchema, PreparePlanInputSchema, PrivateKeyCredentialsSchema, ProviderCandidateSchema, ProviderCapabilitiesSchema, ProviderConformanceCheckNameSchema, ProviderConformanceEvidenceSchema, ProviderDetectionSchema, ProviderDetectionUnavailableReasonCodeSchema, ProviderHealthReasonSchema, ProviderHealthResponseSchema, ProviderHealthSchema, ProviderHealthStatusSchema, ProviderIdSchema, ProviderImplementationSchema, ProviderSchema, RecordConflictReasonSchema, ResolveSharedFlowInputSchema, ResolveSharedFlowResponseSchema, ResolvedDnsIntentSchema, ResolvedDnsRecordSchema, RetryConnectionInputSchema, RetryResumeStateSchema, SelectProviderInputSchema, SharedFlowIdSchema, SharedFlowInvitationSchema, SharedFlowInvitationUrlSchema, SharedFlowTokenSchema, SharedFlowUrlSchema, SpfConflictPolicySchema, StartDomainConnectInputSchema, StartDomainConnectResponseSchema, StartManualConfigurationInputSchema, StartOAuthInputSchema, StartOAuthResponseSchema, SubmitDomainConnectCompletionInputSchema, SubmitManualCompletionInputSchema, TenantIdSchema, UsernamePasswordCredentialsSchema, UsernameTokenCredentialsSchema, VerifiedProviderConformanceEvidenceSchema, VerifyPropagationInputSchema, colorContrastRatio, directCredentialKindByProvider, domain0Locales, expectedProviderConformanceChecks, verifyDomain0Webhook };
1665
-
1
+ import{z as e}from"zod";const t=e.string().trim().min(1).max(200),n=t.brand().meta({id:`ConnectionId`}),r=t.brand().meta({id:`ApplicationId`}),i=t.brand().meta({id:`TenantId`}),a=e.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).brand().meta({id:`ProviderId`}),o=t.brand().meta({id:`CommandId`}),s=e.string().trim().toLowerCase().overwrite(e=>e.replace(/\.$/,``)).min(3).max(253).regex(/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/).refine(e=>!/^\d+(?:\.\d+){3}$/.test(e),`IP addresses are not domain names`).brand().meta({id:`DomainName`}),c=e.iso.datetime({offset:!0}).meta({id:`IsoDateTime`}),l=e.string().trim().toLowerCase().overwrite(e=>e.replace(/\.$/,``)).min(1).max(253).refine(ce,`Host must be @ or a valid relative DNS name`),u=/^([0-9]{1,3})[\t ]+([A-Za-z0-9-]{1,15})[\t ]+(?:"([^\r\n"]*)"|([^\r\n"]+))$/,d=e.enum([`A`,`AAAA`,`CNAME`,`CAA`,`MX`,`TXT`,`NS`]).meta({id:`DnsRecordType`}),f=e.string().regex(/^[a-z]{1,32}$/),p=e.string().min(1).max(4096).refine(e=>e.trim()===e&&/^[\x20-\x3a\x3c-\x7e]+$/.test(e),{message:`DMARC tag values must be trimmed printable ASCII without semicolons`}),ee=e.record(f,p).refine(e=>Object.keys(e).length<=32,`At most 32 DMARC tags are allowed`),m=e.object({inheritRootDmarc:e.boolean().default(!1),overrideTags:ee.default({}),removeTags:e.array(f).max(32).refine(e=>new Set(e).size===e.length,`DMARC tags to remove must be unique`).default([]),addTagsIfNotExist:ee.default({})}).strict().refine(e=>e.inheritRootDmarc||Object.keys(e.overrideTags).length>0||e.removeTags.length>0||Object.keys(e.addTagsIfNotExist).length>0,`At least one advanced DMARC option is required`).superRefine((e,t)=>{for(let[n,r]of[[`overrideTags`,e.overrideTags],[`addTagsIfNotExist`,e.addTagsIfNotExist]])for(let[e,i]of Object.entries(r))ue(e,i)||t.addIssue({code:`custom`,path:[n,e],message:`Invalid value for the ${e} DMARC tag`})}).meta({id:`AdvancedDmarcOptions`}),h=e.object({host:l,type:d,value:e.string().trim().min(1).max(65535),ttl:e.number().int().min(1).max(2147483647).default(300),priority:e.number().int().min(0).max(65535).optional(),optional:e.boolean().default(!1)}).strict().superRefine((t,n)=>{if(t.type===`MX`&&t.priority===void 0&&n.addIssue({code:`custom`,path:[`priority`],message:`MX records require a priority`}),t.type!==`MX`&&t.priority!==void 0&&n.addIssue({code:`custom`,path:[`priority`],message:`Only MX records accept a priority`}),t.type===`A`&&!e.ipv4().safeParse(t.value).success&&n.addIssue({code:`custom`,path:[`value`],message:`A records require an IPv4 address`}),t.type===`AAAA`&&!e.ipv6().safeParse(t.value).success&&n.addIssue({code:`custom`,path:[`value`],message:`AAAA records require an IPv6 address`}),[`CNAME`,`MX`,`NS`].includes(t.type)&&!s.safeParse(t.value).success&&n.addIssue({code:`custom`,path:[`value`],message:`${t.type} records require a domain name`}),t.type===`CAA`){let e=u.exec(t.value);(e===null||Number(e[1])>255)&&n.addIssue({code:`custom`,path:[`value`],message:`CAA values must contain flags, a tag, and a quoted value`})}t.type===`TXT`&&/[\u0000\r\n]/.test(t.value)&&n.addIssue({code:`custom`,path:[`value`],message:`TXT values cannot contain NUL or newlines`})}),g=h.meta({id:`ResolvedDnsRecord`}),_=h.safeExtend({advancedDmarcOptions:m.optional()}).superRefine((e,t)=>{e.advancedDmarcOptions!==void 0&&((e.type!==`TXT`||e.host!==`_dmarc`&&!e.host.startsWith(`_dmarc.`))&&t.addIssue({code:`custom`,path:[`advancedDmarcOptions`],message:`Advanced DMARC options require a TXT record at a _dmarc host`}),le(e.value)||t.addIssue({code:`custom`,path:[`value`],message:`Advanced DMARC options require a valid DMARC1 value with a policy tag`}))}).meta({id:`DnsRecord`}),v=e.object({validateDmarc:e.boolean().default(!1),validateCAA:e.boolean().default(!1)}).strict().meta({id:`ExistingRecordPolicy`}),y=e.object({domain:s,records:e.array(_).min(1).max(100),existingRecordPolicy:v.default({validateDmarc:!1,validateCAA:!1})}).strict().meta({id:`DnsIntent`}),b=e.object({domain:s,records:e.array(g).max(100)}).strict().meta({id:`ResolvedDnsIntent`}),te=b.meta({id:`CheckRecordsInput`}),ne=e.object({record:g,authoritativeServers:e.number().int().min(1).max(16),matchingServers:e.number().int().min(0).max(16),propagated:e.boolean()}).strict().superRefine((e,t)=>{e.matchingServers>e.authoritativeServers&&t.addIssue({code:`custom`,path:[`matchingServers`],message:`Matching nameservers cannot exceed authoritative nameservers`}),e.propagated!==(e.matchingServers===e.authoritativeServers)&&t.addIssue({code:`custom`,path:[`propagated`],message:`Propagation state must match the authoritative nameserver counts`})}).meta({id:`CheckedRecord`}),re=e.object({domain:s,allPropagated:e.boolean(),records:e.array(ne).min(1).max(100)}).strict().superRefine((e,t)=>{e.allPropagated!==e.records.every(e=>e.propagated)&&t.addIssue({code:`custom`,path:[`allPropagated`],message:`Overall propagation state must match every record result`})}).meta({id:`CheckRecordsResponse`}),ie=e.enum([`preserve`,`replace_same_name_and_type`,`replace_all_at_name`]).meta({id:`ConflictPolicy`}),ae=e.enum([`merge`,`replace`]).meta({id:`SpfConflictPolicy`}),oe=e.enum([`create`,`replace`,`delete`]).meta({id:`ChangeAction`}),se=e.object({action:oe,before:g.optional(),after:g.optional(),destructive:e.boolean()}).strict().superRefine((e,t)=>{e.action===`create`&&e.after===void 0&&t.addIssue({code:`custom`,path:[`after`],message:`Create requires the resulting record`}),e.action===`replace`&&(e.before===void 0||e.after===void 0)&&t.addIssue({code:`custom`,message:`Replace requires both current and resulting records`}),e.action===`delete`&&e.before===void 0&&t.addIssue({code:`custom`,path:[`before`],message:`Delete requires the current record`})}).meta({id:`PlannedChange`});function ce(e){return e===`@`||e.split(`.`).every((e,t)=>e===`*`?t===0:e.length>=1&&e.length<=63&&!e.startsWith(`-`)&&!e.endsWith(`-`)&&/^[a-z0-9_-]+$/.test(e))}function le(e){let t=e.split(`;`).map(e=>e.trim()).filter(Boolean),n=new Set;if(t.length<2)return!1;for(let[e,r]of t.entries()){let t=r.indexOf(`=`);if(t<=0)return!1;let i=r.slice(0,t).trim().toLowerCase(),a=r.slice(t+1).trim();if(!f.safeParse(i).success||!p.safeParse(a).success||n.has(i)||e===0&&(i!==`v`||a!==`DMARC1`)||!ue(i,a))return!1;n.add(i)}return n.has(`p`)}function ue(e,t){if(e===`v`)return t===`DMARC1`;if([`p`,`sp`,`np`].includes(e))return[`none`,`quarantine`,`reject`].includes(t);if([`adkim`,`aspf`].includes(e))return t===`r`||t===`s`;if(e===`pct`)return/^\d{1,3}$/.test(t)&&Number(t)<=100;if(e===`ri`)return/^[1-9]\d*$/.test(t);if(e===`rf`)return t===`afrf`;if(e===`fo`){let e=t.split(`:`);return e.length>0&&new Set(e).size===e.length&&e.every(e=>[`0`,`1`,`d`,`s`].includes(e))&&!(e.includes(`0`)&&e.includes(`1`))}return!0}const de=e.enum([`automatic`,`domain_connect`,`manual`,`unverified`]).meta({id:`ProviderImplementation`}),fe=e.enum([`oauth2_pkce`,`oauth2_authorization_code`,`api_token`,`api_key`,`basic`,`session`,`domain_connect`,`manual`]).meta({id:`AuthorizationMethod`}),pe=e.strictObject({rootNSModification:e.enum([`supported`,`unsupported`,`unverified`]),subdomainNSModification:e.enum([`supported`,`unsupported`,`unverified`]),wwwRedirect:e.enum([`supported`,`unsupported`,`unverified`]),cnameFlattening:e.enum([`supported`,`unsupported`,`unverified`]),wildcardRecords:e.enum([`supported`,`unsupported`,`unverified`]),caaRecords:e.enum([`supported`,`unsupported`,`unverified`]),spfRecords:e.enum([`supported`,`unsupported`,`unverified`]),socialLogin:e.enum([`supported`,`unsupported`,`unverified`])}).meta({id:`ProviderCapabilities`}),me=e.enum([`no_stable_public_provider_identity`]).meta({id:`ProviderDetectionUnavailableReasonCode`}),x=e.discriminatedUnion(`method`,[e.strictObject({method:e.enum([`nameserver`,`domain_connect`,`nameserver_or_domain_connect`])}),e.strictObject({method:e.literal(`manual`),reasonCode:me})]).meta({id:`ProviderDetection`}),he=e.url({protocol:/^https$/}).regex(/^https:\/\//,`Provider reference URL must use HTTPS`).refine(e=>{let t=new URL(e);return t.username===``&&t.password===``},`Provider reference URL must not contain credentials`).meta({format:`uri`}),S=e.object({id:a,name:e.string().trim().min(1),referenceUrl:he,implementation:de,availableAuthorizationMethods:e.array(fe).refine(e=>new Set(e).size===e.length,`Authorization methods must be unique`).describe(`Available methods ordered from highest to lowest provider autonomy.`),capabilities:pe,detection:x,limitations:e.array(e.string().min(1))}).strict().superRefine((e,t)=>{let n=e.availableAuthorizationMethods;(e.implementation===`automatic`?n.every(e=>e!==`domain_connect`&&e!==`manual`):e.implementation===`domain_connect`?n.every(e=>e===`domain_connect`):e.implementation===`manual`?n.every(e=>e===`manual`):n.length===0)||t.addIssue({code:`custom`,path:[`availableAuthorizationMethods`],message:`Authorization methods must match the verified provider implementation`})}).meta({id:`Provider`}),ge=e.object({providers:e.array(S)}).strict().meta({id:`ListProvidersResponse`}),_e=e.enum([`operational`,`unavailable`]).meta({id:`ProviderHealthStatus`}),ve=e.enum([`automatic_ready`,`domain_connect_ready`,`runtime_authorization_unavailable`,`manual_only`,`unverified`]).meta({id:`ProviderHealthReason`}),C=e.object({providerId:a,providerName:e.string().trim().min(1).max(200),enabled:e.boolean(),status:_e,reason:ve}).strict().superRefine((e,t)=>{let n=e.reason===`automatic_ready`||e.reason===`domain_connect_ready`,r=e.enabled?e.status===`operational`:e.status===`unavailable`;(e.enabled!==n||!r)&&t.addIssue({code:`custom`,path:[`enabled`],message:`Enabled, status, and reason must describe the same provider health state`})}).meta({id:`ProviderHealth`}),ye=e.object({observedAt:c,refreshAfter:c,providers:e.array(C)}).strict().superRefine((e,t)=>{Date.parse(e.refreshAfter)<=Date.parse(e.observedAt)&&t.addIssue({code:`custom`,path:[`refreshAfter`],message:`Provider health refresh deadline must be after its observation time`});let n=e.providers.map(e=>e.providerId);new Set(n).size!==n.length&&t.addIssue({code:`custom`,path:[`providers`],message:`Provider health entries must have unique provider IDs`})}).meta({id:`ProviderHealthResponse`}),w=e.enum([`requested`,`detecting_provider`,`provider_selected`,`domain_connect_pending`,`authorization_pending`,`authorized`,`planning`,`awaiting_confirmation`,`applying`,`propagation_pending`,`active`,`manual_required`,`failed_retryable`,`failed_terminal`,`cancelled`]).meta({id:`ConnectionState`}),be=e.enum([`authorized`,`awaiting_confirmation`,`applying`]).meta({id:`RetryResumeState`}),xe=e.enum([`provider_snapshot_timeout`,`provider_apply_timeout`]).meta({id:`ConnectionFailureCode`}),T=e.object({code:xe,retryable:e.literal(!0),resumeState:be,occurredAt:c}).strict().meta({id:`ConnectionFailure`}),Se=e.enum([`spf_policy_replaced`,`spf_policy_merged`]).meta({id:`PlanWarningCode`}),Ce=e.object({digest:e.string().regex(/^[a-f0-9]{64}$/),changes:e.array(se).min(1),warnings:e.array(Se),expiresAt:c}).strict().meta({id:`ChangePlan`}),E=e.object({id:n,applicationId:r,tenantId:i,intent:y,effectiveIntent:b.optional(),state:w,provider:S.optional(),plan:Ce.optional(),failure:T.optional(),optionalFailures:e.array(e.string()),createdAt:c,updatedAt:c}).strict().superRefine((e,t)=>{let n=e.state===`failed_retryable`;n!==(e.failure!==void 0)&&t.addIssue({code:`custom`,path:[`failure`],message:n?`A retryable failure state requires failure details`:`Failure details are allowed only in a retryable failure state`}),e.effectiveIntent!==void 0&&e.effectiveIntent.domain!==e.intent.domain&&t.addIssue({code:`custom`,path:[`effectiveIntent`,`domain`],message:`Effective intent must use the requested intent domain`})}).meta({id:`Connection`}),we=e.object({applicationId:r,tenantId:i,intent:y,commandId:o}).strict().meta({id:`CreateConnectionInput`}),Te=e.object({connection:E}).strict().meta({id:`ConnectionResponse`}),Ee=Te,De=e.object({provider:S,confidence:e.number().min(0).max(1)}).strict().meta({id:`ProviderCandidate`}),Oe=e.object({connection:E,candidates:e.array(De)}).strict().meta({id:`DetectProviderResponse`}),ke=e.object({providerId:a,commandId:o}).strict().meta({id:`SelectProviderInput`}),D=e.string().regex(/^[A-Za-z0-9._-]{1,63}$/),Ae=e.string().regex(/^[A-Za-z][A-Za-z0-9_-]{0,62}$/),je=new Set([`domain`,`host`,`groupId`,`providerName`,`serviceName`,`instanceId`,`redirect_uri`,`state`,`sig`,`key`]),Me=e.record(Ae,e.string().min(1).max(4096).refine(e=>e.trim()===e&&!/[\u0000\r\n]/.test(e),`Domain Connect property values must be trimmed and single-line`)).refine(e=>Object.keys(e).length<=64,`At most 64 Domain Connect properties are allowed`).refine(e=>Object.keys(e).every(e=>!je.has(e)),`Domain Connect properties must not override reserved protocol parameters`),Ne=e.object({serviceProviderId:D,serviceId:D,host:e.string().max(253).regex(/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/).optional(),groupId:D.optional(),providerName:e.string().trim().min(1).max(200).optional(),serviceName:e.string().trim().min(1).max(200).optional(),instanceId:D.optional(),properties:Me}).strict().meta({id:`DomainConnectTemplate`}),Pe=Ne.extend({commandId:o}).strict().meta({id:`StartDomainConnectInput`}),Fe=e.url({protocol:/^https$/}).refine(e=>{let t=new URL(e);return t.username===``&&t.password===``&&t.hash===``},`Domain Connect handoff URL must be HTTPS without credentials or a fragment`),Ie=e.object({connection:E,handoffUrl:Fe}).strict().meta({id:`StartDomainConnectResponse`}),Le=e.object({commandId:o}).strict().meta({id:`SubmitDomainConnectCompletionInput`}),Re=e.object({digest:e.string().regex(/^[a-f0-9]{64}$/),allowDestructive:e.boolean(),commandId:o}).strict().meta({id:`ConfirmPlanInput`}),ze=e.object({commandId:o}).strict().meta({id:`StartOAuthInput`}),Be=e.object({connection:E,authorizationUrl:e.url({protocol:/^https$/}),expiresAt:c}).strict().meta({id:`StartOAuthResponse`}),O=e.string().min(1).max(16384).refine(e=>e.trim()===e,`Credential values must not have leading or trailing whitespace`).meta({format:`password`,writeOnly:!0}),k=e.object({kind:e.literal(`api_token`),token:O}).strict().meta({id:`ApiTokenCredentials`}),A=e.object({kind:e.literal(`access_key`),keyId:O,secret:O}).strict().meta({id:`AccessKeyCredentials`}),j=e.object({kind:e.literal(`username_password`),username:O,password:O}).strict().meta({id:`UsernamePasswordCredentials`}),M=e.object({kind:e.literal(`account_token`),accountId:O,token:O}).strict().meta({id:`AccountTokenCredentials`}),N=e.object({kind:e.literal(`username_token`),username:O,token:O}).strict().meta({id:`UsernameTokenCredentials`}),P=e.object({kind:e.literal(`ovh`),endpoint:e.enum([`ovh-eu`,`ovh-us`,`ovh-ca`,`kimsufi-eu`,`kimsufi-ca`,`soyoustart-eu`,`soyoustart-ca`]),applicationKey:O,applicationSecret:O,consumerKey:O}).strict().meta({id:`OvhCredentials`}),F=e.object({kind:e.literal(`private_key`),login:O,privateKey:O.refine(e=>/^(-----BEGIN (?:RSA )?PRIVATE KEY-----)[\s\S]+(-----END (?:RSA )?PRIVATE KEY-----)$/.test(e),`A PKCS#8 or PKCS#1 PEM private key is required`)}).strict().meta({id:`PrivateKeyCredentials`}),Ve=e.object({kind:e.literal(`aws_session`),keyId:O.regex(/^[A-Z0-9]{16,128}$/),secret:O,sessionToken:O,hostedZoneId:e.string().regex(/^Z[A-Z0-9]{1,63}$/),expiresAt:c}).strict().meta({id:`AwsSessionCredentials`}),He=e.url({protocol:/^https$/}).refine(e=>{let t=new URL(e);return t.port===`2083`&&t.username===``&&t.password===``&&(t.pathname===``||t.pathname===`/`)&&t.search===``&&t.hash===``},`cPanel endpoint must be an HTTPS origin on port 2083`),I=e.object({kind:e.literal(`cpanel`),endpoint:He,username:O,token:O}).strict().meta({id:`CPanelCredentials`}),Ue=e.object({kind:e.literal(`client_credentials`),clientId:O,clientSecret:O}).strict().meta({id:`ClientCredentials`});function L(t,n){return e.object({providerId:e.literal(t),credentials:n,commandId:o}).strict()}const We=[L(`alibaba-cloud`,A),L(`all-inkl`,j),L(`amazon-route-53`,Ve),L(`cloudflare`,k),L(`cloudns`,M),L(`digitalocean`,k),L(`dnsimple`,M),L(`dreamhost`,k),L(`dynadot`,A),L(`easydns`,A),L(`gandi`,k),L(`godaddy`,k),L(`hetzner`,k),L(`hostgator`,I),L(`hostinger`,k),L(`hosting-com`,I),L(`inmotion-hosting`,I),L(`ionos`,k),L(`name-com`,N),L(`namesilo`,k),L(`netlify`,k),L(`o2switch`,I),L(`openprovider`,k),L(`opensrs`,Ue),L(`ovh`,P),L(`porkbun`,A),L(`simply`,k),L(`spaceship`,A),L(`transip`,F),L(`united-domains`,k),L(`vercel`,k),L(`wix`,M)],Ge=Object.freeze(Object.fromEntries(We.map(e=>[e.shape.providerId.value,e.shape.credentials.shape.kind.value]))),Ke=e.discriminatedUnion(`providerId`,We).meta({id:`AuthorizeWithCredentialInput`}),qe=e.object({completed:e.literal(!0)}).strict().meta({id:`OAuthCallbackResponse`}),Je=e.object({conflictPolicy:ie,spfPolicy:ae.default(`merge`),commandId:o}).strict().meta({id:`PreparePlanInput`}),Ye=e.object({commandId:o}).strict().meta({id:`ApplyPlanInput`}),Xe=e.object({commandId:o}).strict().meta({id:`VerifyPropagationInput`}),Ze=e.object({commandId:o}).strict().meta({id:`StartManualConfigurationInput`}),Qe=e.object({commandId:o}).strict().meta({id:`SubmitManualCompletionInput`}),$e=e.object({commandId:o}).strict().meta({id:`CancelConnectionInput`}),et=e.object({commandId:o}).strict().meta({id:`RetryConnectionInput`}),tt=e.object({origin:e.url().refine(e=>{let t=new URL(e);return t.username===``&&t.password===``&&t.search===``&&t.hash===``&&(t.pathname===``||t.pathname===`/`)&&(t.protocol===`https:`||t.protocol===`http:`&&rt(t.hostname))},`Origin must be an HTTPS origin without a path, query, or fragment`)}).strict().meta({id:`IssueConnectionTokenInput`}),nt=e.object({accessToken:e.string().min(1).max(8192),tokenType:e.literal(`Bearer`),expiresAt:c}).strict().meta({id:`IssueConnectionTokenResponse`});function rt(e){return e===`localhost`||e===`127.0.0.1`||e===`[::1]`}const it=e.string().trim().min(1).max(200).meta({id:`ConnectionFlowId`}),at=e.strictObject({domain:e.array(_).min(1).max(100),subDomain:e.array(_).min(1).max(100).optional(),rootNS:e.array(_).min(1).max(100).optional()}).superRefine((e,t)=>{e.rootNS?.forEach((e,n)=>{(e.host!==`@`||e.type!==`NS`)&&t.addIssue({code:`custom`,path:[`rootNS`,n],message:`rootNS accepts only NS records at the zone apex`})})}).meta({id:`ConditionalDnsRecords`}),ot=e.strictObject({domain:s,records:e.array(_).min(1).max(100)}),st=e.strictObject({domain:s,conditionalRecords:at}),ct=e.union([ot,st]).meta({id:`ConnectionFlowTargetInput`}),lt=e.strictObject({applicationId:r,tenantId:i,existingRecordPolicy:v.default({validateDmarc:!1,validateCAA:!1}),targets:e.array(ct).min(2).max(100).superRefine((e,t)=>{let n=new Set;e.forEach((e,r)=>{n.has(e.domain)&&t.addIssue({code:`custom`,path:[r,`domain`],message:`Flow target domains must be unique`}),n.add(e.domain)})}),commandId:o}).meta({id:`CreateConnectionFlowInput`}),ut=e.strictObject({domain:s,state:e.enum([`pending`,`provisioned`]),connectionId:n.optional()}).superRefine((e,t)=>{e.state===`provisioned`!=(e.connectionId!==void 0)&&t.addIssue({code:`custom`,path:[`connectionId`],message:e.state===`provisioned`?`A provisioned target requires a connection id`:`A pending target cannot have a connection id`})}).meta({id:`ConnectionFlowTarget`}),dt=e.strictObject({id:it,applicationId:r,tenantId:i,state:e.enum([`provisioning`,`ready`]),targets:e.array(ut).min(2).max(100),createdAt:c,updatedAt:c}).superRefine((e,t)=>{let n=e.targets.every(e=>e.state===`provisioned`);e.state===`ready`!==n&&t.addIssue({code:`custom`,path:[`state`],message:`Flow state must match target provisioning state`})}).meta({id:`ConnectionFlow`}),ft=e.strictObject({flow:dt}).meta({id:`ConnectionFlowResponse`}),R=e.enum([`invalid_request`,`unauthorized`,`forbidden`,`not_found`,`conflict`,`rate_limited`,`dns_unavailable`,`provider_unavailable`,`provider_authorization_failed`,`provider_limitation`,`plan_expired`,`propagation_pending`,`internal_error`]).meta({id:`Domain0ErrorCode`}),pt=e.object({error:e.object({code:R,message:e.string().min(1),requestId:e.string().min(1),retryable:e.boolean(),details:e.record(e.string(),e.unknown()).optional()}).strict()}).strict().meta({id:`ErrorResponse`}),z=e.string().min(1).max(200).brand(),B=e.string().regex(/^[A-Za-z0-9_-]{43}$/).brand(),mt=e.strictObject({connectionId:n,expiresAt:c}),ht=e.strictObject({sharedFlowId:z,token:B,expiresAt:c}),gt=e.strictObject({token:B,origin:e.string().url().max(2048)}),_t=e.strictObject({sharedFlowId:z,connectionId:n,accessToken:e.string().min(1).max(8192),expiresAt:c}),vt=e.string().url().max(4096),V=vt.superRefine((e,t)=>{let n=new URL(e),r=n.protocol===`https:`,i=n.protocol===`http:`&&bt(n.hostname);!r&&!i&&t.addIssue({code:`custom`,message:`Shared-flow invitation URLs must use HTTPS, except on loopback development hosts`}),(n.username!==``||n.password!==``)&&t.addIssue({code:`custom`,message:`Shared-flow invitation URLs cannot contain user information`});let a=new URLSearchParams(n.hash.slice(1)),o=a.get(`domain0`);(a.size!==1||!B.safeParse(o).success)&&t.addIssue({code:`custom`,message:`Shared-flow invitation URLs require one valid domain0 capability in the fragment`})}).meta({id:`SharedFlowInvitationUrl`}),yt=e.object({sharedFlowId:z,url:V,expiresAt:c}).strict().meta({id:`SharedFlowInvitation`});function bt(e){let t=e.toLowerCase();return t===`localhost`||t===`[::1]`||/^127(?:\.[0-9]{1,3}){3}$/.test(t)}const H=e.string().trim().toLowerCase().min(1).max(63).regex(/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/).brand().meta({id:`DkimSelector`}),xt=e.object({selectors:e.array(H).max(10).default([])}).strict().superRefine((e,t)=>{new Set(e.selectors).size!==e.selectors.length&&t.addIssue({code:`custom`,path:[`selectors`],message:`DKIM selectors must be unique`})}).meta({id:`DkimGuidanceInput`}),St=e.object({enableDkim:e.boolean().default(!1),dkimSelectors:e.array(H).max(10).default([])}).strict().superRefine((e,t)=>{new Set(e.dkimSelectors).size!==e.dkimSelectors.length&&t.addIssue({code:`custom`,path:[`dkimSelectors`],message:`DKIM selectors must be unique`})}).meta({id:`Domain0DkimGuidanceOptions`}),Ct=e.object({id:e.literal(`google_workspace`),name:e.literal(`Google Workspace`),guideUrl:e.literal(`https://support.google.com/a/answer/174124`)}).strict(),wt=e.object({id:e.literal(`microsoft_365`),name:e.literal(`Microsoft 365`),guideUrl:e.literal(`https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dkim-configure`)}).strict(),Tt=e.object({id:e.literal(`zoho_mail`),name:e.literal(`Zoho Mail`),guideUrl:e.literal(`https://www.zoho.com/mail/help/adminconsole/dkim-configuration.html`)}).strict(),U=e.discriminatedUnion(`id`,[Ct,wt,Tt]).meta({id:`EmailProvider`}),Et=e.enum([`detected`,`ambiguous`,`unknown`]).meta({id:`EmailProviderDetectionStatus`}),Dt=e.enum([`TXT`,`CNAME`]).meta({id:`DkimDnsRecordType`}),Ot=e.enum([`record_observed`,`no_record_observed`,`not_checked`,`lookup_unavailable`]).meta({id:`DkimDnsEvidenceStatus`}),kt=e.object({selector:H,types:e.array(Dt).min(1).max(2).refine(e=>new Set(e).size===e.length,`Observed DKIM DNS record types must be unique`)}).strict().meta({id:`DkimDnsRecordEvidence`}),At=e.object({status:Ot,selectorsChecked:e.array(H).max(12).refine(e=>new Set(e).size===e.length,`Checked DKIM selectors must be unique`),records:e.array(kt).max(12)}).strict().superRefine((e,t)=>{let n=new Set(e.selectorsChecked);e.records.some(e=>!n.has(e.selector))&&t.addIssue({code:`custom`,path:[`records`],message:`Observed records must belong to checked selectors`}),e.status===`not_checked`&&(e.selectorsChecked.length!==0||e.records.length!==0)&&t.addIssue({code:`custom`,path:[`status`],message:`Not-checked evidence cannot include selector observations`}),e.status===`record_observed`&&e.records.length===0&&t.addIssue({code:`custom`,path:[`records`],message:`Observed status requires at least one DNS record`}),e.status!==`record_observed`&&e.records.length!==0&&t.addIssue({code:`custom`,path:[`records`],message:`Only observed status can include DNS records`}),[`no_record_observed`,`lookup_unavailable`].includes(e.status)&&e.selectorsChecked.length===0&&t.addIssue({code:`custom`,path:[`selectorsChecked`],message:`A DNS lookup status requires at least one checked selector`})}).meta({id:`DkimDnsEvidence`}),jt=e.object({domain:s,detectionStatus:Et,candidates:e.array(U).max(3),provider:U.optional(),mxHosts:e.array(s).max(20).refine(e=>new Set(e).size===e.length,`MX hosts must be unique`),dkimDns:At,observedAt:c}).strict().superRefine((e,t)=>{let n=e.candidates.map(e=>e.id);new Set(n).size!==n.length&&t.addIssue({code:`custom`,path:[`candidates`],message:`Email provider candidates must be unique`}),e.detectionStatus===`detected`&&(e.candidates.length!==1||e.provider?.id!==e.candidates[0]?.id)&&t.addIssue({code:`custom`,path:[`provider`],message:`Detected status requires exactly one matching provider`}),e.detectionStatus===`ambiguous`&&(e.candidates.length<2||e.provider!==void 0)&&t.addIssue({code:`custom`,path:[`candidates`],message:`Ambiguous status requires multiple candidates and no resolved provider`}),e.detectionStatus===`unknown`&&(e.candidates.length!==0||e.provider!==void 0)&&t.addIssue({code:`custom`,path:[`candidates`],message:`Unknown status cannot include an email provider`})}).meta({id:`DkimGuidanceResponse`}),W=e.union([e.enum([`loading`,`provider_detection`,`provider_selection`,`cancellation_confirmation`]),w]).meta({id:`Domain0ConnectStep`}),Mt=e.enum([`close_button`,`escape`,`programmatic`,`destroyed`,`automatic`]).meta({id:`Domain0ConnectCloseTrigger`}),Nt=e.enum([`success`,`failure`,`cancelled`,`incomplete`]).meta({id:`Domain0ConnectOutcome`}),G=E.and(e.object({state:e.literal(`active`)})),Pt=E.and(e.object({state:e.literal(`manual_required`)})),Ft=e.union([E.and(e.object({state:e.literal(`failed_retryable`),failure:T})),E.and(e.object({state:e.literal(`failed_terminal`),failure:e.undefined().optional()}))]),K=e.discriminatedUnion(`source`,[e.object({source:e.literal(`configuration`),code:e.literal(`invalid_configuration`),retryable:e.literal(!1)}).strict(),e.object({source:e.literal(`api`),code:R,retryable:e.boolean(),requestId:e.string().min(1)}).strict(),e.object({source:e.literal(`transport`),code:e.literal(`transport_error`),retryable:e.literal(!0)}).strict(),e.object({source:e.literal(`protocol`),code:e.literal(`protocol_error`),retryable:e.literal(!1)}).strict(),e.object({source:e.literal(`unexpected`),code:e.literal(`unexpected_error`),retryable:e.literal(!1)}).strict()]).meta({id:`Domain0ConnectError`}),It=e.object({type:e.literal(`success`),connection:G}).strict().meta({id:`Domain0ConnectSuccessEvent`}),Lt=e.object({type:e.literal(`failure`),connection:Ft}).strict().meta({id:`Domain0ConnectFailureEvent`}),Rt=e.object({type:e.literal(`error`),error:K,connection:E.optional(),step:W.optional()}).strict().meta({id:`Domain0ConnectErrorEvent`}),zt=e.object({type:e.literal(`close`),trigger:Mt,outcome:Nt,connection:E.optional(),step:W.optional(),error:K.optional()}).strict().superRefine((e,t)=>{let n=Kt(e.connection,e.error);e.outcome!==n&&t.addIssue({code:`custom`,path:[`outcome`],message:`Close outcome must be ${n} for the supplied connection and error`})}).meta({id:`Domain0ConnectCloseEvent`}),Bt=e.object({type:e.literal(`step_change`),step:W,previousStep:W.optional(),connection:E.optional()}).strict().meta({id:`Domain0ConnectStepChangeEvent`}),Vt=e.object({type:e.literal(`manual_setup_documentation_click`),connection:Pt}).strict().meta({id:`Domain0ManualSetupDocumentationClickEvent`}),Ht=e.object({type:e.literal(`request_close`),connection:E.optional(),step:W}).strict().meta({id:`Domain0RequestCloseEvent`}),Ut=e.object({type:e.literal(`shared_flow_sent`),connection:Pt,sharedFlowId:z,url:V,expiresAt:c}).strict().meta({id:`Domain0SharedFlowSentEvent`}),Wt=e.object({type:e.literal(`dkim_setup_documentation_click`),connection:G,emailProvider:U}).strict().meta({id:`Domain0DkimSetupDocumentationClickEvent`}),Gt=e.discriminatedUnion(`type`,[It,Lt,Rt,zt,Bt,Vt,Ht,Ut,Wt]).meta({id:`Domain0ConnectEvent`});function Kt(e,t){return e?.state===`active`?`success`:t!==void 0||e?.state===`failed_retryable`||e?.state===`failed_terminal`?`failure`:e?.state===`cancelled`?`cancelled`:`incomplete`}const qt=e.object({mode:e.enum([`automatic`,`manual`]).default(`automatic`)}).strict(),Jt=/^#[0-9A-F]{6}$/,Yt=/^#[0-9A-F]{8}$/,q=e.string().trim().toUpperCase().regex(Jt,`Expected an opaque #RRGGBB color`),Xt=e.string().trim().toUpperCase().regex(Yt,`Expected a #RRGGBBAA backdrop color`),Zt=e.string().trim().min(1).max(500).refine(e=>!/[<>\u0000-\u001F\u007F]/.test(e),`White-label copy must be plain text without markup or control characters`),Qt=Zt.max(120).meta({id:`Domain0ApplicationName`}),$t=e.string().trim().min(1).max(2048).refine(e=>{try{let t=new URL(e);return t.protocol===`https:`&&t.username===``&&t.password===``}catch{return!1}},`Logo must be an HTTPS URL without embedded credentials`).meta({id:`Domain0WhiteLabelLogoUrl`});function J(...e){return Zt.refine(t=>{let n=e.reduce((e,t)=>e.replaceAll(t,``),t);return!/[{}]/.test(n)},`Only these placeholders are allowed: ${e.join(`, `)||`none`}`)}function Y(t){let n=e.object({en:t,es:t.optional(),pt:t.optional(),"pt-br":t.optional(),"pt-pt":t.optional(),fr:t.optional(),it:t.optional(),de:t.optional(),nl:t.optional(),pl:t.optional(),tr:t.optional(),ja:t.optional(),da:t.optional(),sv:t.optional()}).strict();return e.union([t.transform(e=>({en:e})),n])}function en(e,t){return tn(q.parse(e),q.parse(t))}function tn(e,t){let n=rn(e),r=rn(t),i=Math.max(n,r),a=Math.min(n,r);return(i+.05)/(a+.05)}function nn(e){let t=e.split(`,`);return t.length<=10&&t.every(e=>{let t=e.trim();if(t.length===0)return!1;let n=t.at(0);return n===`"`||n===`'`?t.at(-1)===n&&/^[A-Za-z0-9 -]+$/.test(t.slice(1,-1)):/^-?[A-Za-z][A-Za-z0-9 -]*$/.test(t)})}function rn(e){let[t,n,r]=[1,3,5].map(t=>Number.parseInt(e.slice(t,t+2),16)/255).map(e=>e<=.04045?e/12.92:((e+.055)/1.055)**2.4);return .2126*t+.7152*n+.0722*r}const an=[{foreground:`text`,background:`surface`,minimum:4.5,purpose:`body text`},{foreground:`mutedText`,background:`surface`,minimum:4.5,purpose:`secondary text`},{foreground:`onPrimary`,background:`primary`,minimum:4.5,purpose:`primary control text`},{foreground:`danger`,background:`surface`,minimum:4.5,purpose:`error text`},{foreground:`onDanger`,background:`danger`,minimum:4.5,purpose:`danger control text`},{foreground:`link`,background:`surface`,minimum:4.5,purpose:`link text`},{foreground:`border`,background:`surface`,minimum:3,purpose:`control boundaries`},{foreground:`primary`,background:`surface`,minimum:3,purpose:`primary control boundaries`},{foreground:`focus`,background:`surface`,minimum:3,purpose:`focus indicators`}],on={surface:`#FFFFFF`,text:`#0A0A0A`,mutedText:`#6B6B6B`,border:`#73737C`,primary:`#0A0A0A`,onPrimary:`#FFFFFF`,link:`#2B21FF`,focus:`#2B21FF`,danger:`#B3261E`,onDanger:`#FFFFFF`},sn={surface:`#111827`,text:`#F9FAFB`,mutedText:`#D1D5DB`,border:`#D1D5DB`,primary:`#BFDBFE`,onPrimary:`#172554`,link:`#BFDBFE`,focus:`#FBBF24`,danger:`#FCA5A5`,onDanger:`#450A0A`};function cn(t){return e.object({surface:q.default(t.surface),text:q.default(t.text),mutedText:q.default(t.mutedText),border:q.default(t.border),primary:q.default(t.primary),onPrimary:q.default(t.onPrimary),link:q.default(t.link),focus:q.default(t.focus),danger:q.default(t.danger),onDanger:q.default(t.onDanger)}).strict().superRefine((e,t)=>{for(let n of an){let r=tn(e[n.foreground],e[n.background]);r<n.minimum&&t.addIssue({code:`custom`,path:[n.foreground],message:`${n.purpose} requires ${n.minimum}:1 contrast against ${n.background}; received ${r.toFixed(2)}:1`})}})}const ln=cn(on),un=cn(sn),dn=e.object({colorMode:e.enum([`light`,`dark`,`system`]).default(`light`),light:ln.prefault({}),dark:un.prefault({}),backdrop:Xt.default(`#2B21FF26`),widthPx:e.number().int().min(320).max(960).default(520),dialogRadiusPx:e.number().int().min(0).max(48).default(20),buttonRadiusPx:e.number().int().min(0).max(999).default(999),inputRadiusPx:e.number().int().min(0).max(32).default(12),fontFamily:e.string().trim().min(1).max(200).refine(nn,`Use a comma-separated system font stack without URLs or CSS syntax`).default(`"PP Neue Montreal", "Inter Tight", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`),fontWeight:e.number().int().min(100).max(900).multipleOf(50).default(400),boldFontWeight:e.number().int().min(100).max(900).multipleOf(50).default(500)}).strict().superRefine((e,t)=>{e.boldFontWeight<e.fontWeight&&t.addIssue({code:`custom`,path:[`boldFontWeight`],message:`Bold font weight must be at least the normal font weight`})}),fn=e.object({initialSubtitle:Y(J()).optional(),providerLoginMessage:Y(J(`{PROVIDER}`)).optional(),successTitle:Y(J(`{DOMAIN}`)).optional(),successDescription:Y(J(`{DOMAIN}`)).optional(),successButton:Y(J()).optional(),manuallyScreen:e.object({disableManualSetupDocumentationLink:e.boolean().default(!1),stepByStepGuide:Y(J()).optional()}).strict().prefault({})}).strict(),pn=e.object({disable:e.boolean().default(!1)}).strict(),mn=e.object({manualConfiguration:e.object({disableScreen:e.boolean().default(!1)}).strict().prefault({}),providerLogin:e.object({forwardLink:pn.prefault({}),gotoManualLink:pn.prefault({})}).strict().prefault({})}).strict(),hn=e.object({theme:dn.prefault({}),copy:fn.prefault({}),logo:$t.optional(),logoBackgroundColor:q.optional(),removeLogoBorder:e.boolean().default(!1),hideCompanyLogo:e.boolean().default(!1),hideCompanyName:e.boolean().default(!1),removeShareLogin:e.boolean().default(!1),skipCongratulationsScreen:e.boolean().default(!1),customProperties:mn.prefault({})}).strict(),gn=e.url({protocol:/^https$/}).max(2048).refine(e=>{let t=new URL(e);return t.username===``&&t.password===``},`Manual setup documentation URL must not contain credentials`).brand().meta({id:`ManualSetupDocumentationUrl`}),_n=e.object({applicationName:Qt.optional(),whiteLabel:hn.prefault({}),setupPolicy:qt.prefault({}),dkim:St.prefault({}),manualSetupDocumentation:gn.optional()}).strict().superRefine((e,t)=>{let{customProperties:n}=e.whiteLabel,r=e.setupPolicy.mode===`manual`;r&&n.manualConfiguration.disableScreen&&t.addIssue({code:`custom`,path:[`whiteLabel`,`customProperties`,`manualConfiguration`,`disableScreen`],message:`Forced manual setup requires the manual configuration screen`}),r&&n.providerLogin.gotoManualLink.disable&&t.addIssue({code:`custom`,path:[`whiteLabel`,`customProperties`,`providerLogin`,`gotoManualLink`,`disable`],message:`Forced manual setup cannot disable entry into manual configuration`}),e.dkim.enableDkim&&e.whiteLabel.skipCongratulationsScreen&&t.addIssue({code:`custom`,path:[`whiteLabel`,`skipCongratulationsScreen`],message:`DKIM guidance requires the success screen`})}).meta({id:`Domain0ConnectConfiguration`}),vn=e.enum(`alibaba-cloud.all-inkl.amazon-route-53.cloudflare.cloudns.digitalocean.dnsimple.dreamhost.dynadot.easydns.gandi.godaddy.hetzner.hostgator.hostinger.hosting-com.inmotion-hosting.ionos.name-com.namecheap.namesilo.netlify.o2switch.openprovider.opensrs.ovh.porkbun.simply.spaceship.transip.united-domains.vercel.wix`.split(`.`)).meta({id:`CompiledProviderId`}),yn=e.enum([`authenticated_snapshot`,`reserved_name_available`,`create_sibling`,`create_target`,`rrset_sibling_preservation`,`idempotent_replay`,`replace_target`,`authoritative_propagation`,`delete_target`,`scoped_cleanup`]).meta({id:`ProviderConformanceCheckName`}),X=[`authenticated_snapshot`,`reserved_name_available`,`create_sibling`,`create_target`,`rrset_sibling_preservation`,`idempotent_replay`,`replace_target`,`authoritative_propagation`,`delete_target`,`scoped_cleanup`],bn=e.object({name:yn}).strict(),xn=e.union([e.literal(`unknown`),e.string().regex(/^[a-f0-9]{40,64}$/)]),Sn=e.object({schemaVersion:e.literal(1),providerId:vn,adapterVersion:e.string().min(1).max(200).refine(Tn),sourceRevision:xn,sourceModified:e.boolean(),binarySha256:e.string().regex(/^[a-f0-9]{64}$/),zone:s,runId:e.string().regex(/^[a-f0-9]{16,64}$/),host:e.string(),startedAt:c,completedAt:c,passed:e.boolean(),checks:e.array(bn).max(X.length),cleanupAttempted:e.boolean(),cleanupCompleted:e.boolean()}).strict().superRefine((e,t)=>{e.host!==`_domain0-conformance-${e.runId}`&&t.addIssue({code:`custom`,path:[`host`],message:`Conformance hostname must be derived from the random run ID`}),Date.parse(e.completedAt)<Date.parse(e.startedAt)&&t.addIssue({code:`custom`,path:[`completedAt`],message:`Conformance completion must not precede its start`});let n=e.checks.map(e=>e.name);wn(n)||t.addIssue({code:`custom`,path:[`checks`],message:`Conformance checks must be an ordered prefix followed optionally by scoped cleanup`});let r=n.includes(`scoped_cleanup`);(e.cleanupCompleted&&!e.cleanupAttempted||r!==e.cleanupCompleted)&&t.addIssue({code:`custom`,path:[`cleanupCompleted`],message:`Completed cleanup requires an attempted cleanup and the scoped-cleanup check`})}).meta({id:`ProviderConformanceEvidence`}),Cn=Sn.refine(e=>e.passed&&!e.sourceModified&&e.sourceRevision!==`unknown`&&e.cleanupAttempted&&e.cleanupCompleted&&e.checks.every((e,t)=>e.name===X[t])&&e.checks.length===X.length,`Verified live-suite evidence requires clean traceable source, every ordered check, and completed cleanup`).meta({id:`VerifiedProviderConformanceEvidence`});function wn(e){let t=0,n=!1;for(let r of e){if(r===`scoped_cleanup`){if(n)return!1;n=!0;continue}if(n||r!==X[t])return!1;t+=1}return!0}function Tn(e){return e.trim()===e&&!/[\u0000\r\n]/.test(e)}const En=e.enum([`delegated`,`undelegated`,`unknown`]).meta({id:`DomainDelegationStatus`}),Dn=e.enum([`automatic`,`manual`,`unavailable`,`ambiguous`,`unknown`]).meta({id:`DomainSetupSupport`}),On=e.enum([`same_name_and_type`,`cname_collision`,`mx_set_collision`,`spf_collision`,`ns_delegation`]).meta({id:`RecordConflictReason`}),kn=e.object({domain:s,records:e.array(g).max(100).default([]),checkConflicts:e.boolean().default(!1)}).strict().superRefine((e,t)=>{e.checkConflicts&&e.records.length===0&&t.addIssue({code:`custom`,path:[`records`],message:`Record conflict analysis requires at least one requested record`})}).meta({id:`CheckDomainInput`}),An=e.object({provider:S,confidence:e.number().min(0).max(1),exact:e.boolean()}).strict().meta({id:`DomainProviderCandidate`}),jn=e.object({requested:g,existing:e.array(g).max(1e3),reasons:e.array(On).min(1).max(5).refine(e=>new Set(e).size===e.length,`Conflict reasons must be unique`)}).strict().meta({id:`DomainRecordConflict`}),Mn=e.object({status:e.enum([`not_requested`,`complete`,`partial`]),authoritativeServers:e.number().int().min(0).max(16),respondingServers:e.number().int().min(0).max(16),conflicts:e.array(jn).max(100)}).strict().superRefine((e,t)=>{e.respondingServers>e.authoritativeServers&&t.addIssue({code:`custom`,path:[`respondingServers`],message:`Responding nameservers cannot exceed authoritative nameservers`}),e.status===`complete`&&e.respondingServers!==e.authoritativeServers&&t.addIssue({code:`custom`,path:[`status`],message:`Complete analysis requires every authoritative nameserver to respond`}),e.status===`partial`&&(e.respondingServers===0||e.respondingServers>=e.authoritativeServers)&&t.addIssue({code:`custom`,path:[`status`],message:`Partial analysis requires some but not all authoritative nameservers to respond`}),e.status===`not_requested`&&e.conflicts.length!==0&&t.addIssue({code:`custom`,path:[`conflicts`],message:`Conflict results cannot exist when analysis was not requested`})}).meta({id:`ConflictAnalysis`}),Nn=e.object({domain:s,delegationStatus:En,candidates:e.array(An).max(65),provider:S.optional(),setupSupport:Dn,conflictAnalysis:Mn}).strict().superRefine((e,t)=>{let n=e.candidates.map(e=>e.provider.id);new Set(n).size!==n.length&&t.addIssue({code:`custom`,path:[`candidates`],message:`Provider candidates must be unique`}),e.delegationStatus===`undelegated`&&(e.candidates.length!==0||e.provider!==void 0||e.setupSupport!==`unavailable`)&&t.addIssue({code:`custom`,path:[`delegationStatus`],message:`Undelegated domains cannot have provider support`}),e.provider!==void 0&&!e.candidates.some(t=>t.exact&&t.provider.id===e.provider?.id)&&t.addIssue({code:`custom`,path:[`provider`],message:`Resolved provider must be an exact provider candidate`}),[`automatic`,`manual`].includes(e.setupSupport)&&e.provider===void 0&&t.addIssue({code:`custom`,path:[`setupSupport`],message:`Available setup support requires a resolved provider`}),e.setupSupport===`automatic`&&!e.provider?.availableAuthorizationMethods.some(e=>e!==`manual`)&&t.addIssue({code:`custom`,path:[`setupSupport`],message:`Automatic setup requires a configured non-manual authorization method`}),e.setupSupport===`manual`&&(e.provider?.availableAuthorizationMethods.length!==1||e.provider.availableAuthorizationMethods[0]!==`manual`)&&t.addIssue({code:`custom`,path:[`setupSupport`],message:`Manual setup requires the manual authorization method`}),e.setupSupport===`ambiguous`&&e.candidates.length===0&&t.addIssue({code:`custom`,path:[`candidates`],message:`Ambiguous setup requires provider candidates`}),e.setupSupport===`unknown`&&e.candidates.length!==0&&t.addIssue({code:`custom`,path:[`candidates`],message:`Unknown setup cannot include provider candidates`}),[`ambiguous`,`unknown`].includes(e.setupSupport)&&e.provider!==void 0&&t.addIssue({code:`custom`,path:[`provider`],message:`Ambiguous or unknown support cannot resolve one provider`})}).meta({id:`CheckDomainResponse`}),Pn=[`en`,`es`,`pt`,`pt-br`,`pt-pt`,`fr`,`it`,`de`,`nl`,`pl`,`tr`,`ja`,`da`,`sv`],Fn=e.enum(Pn).meta({id:`Domain0Locale`}),In=e.strictObject({intent:y}).meta({id:`PlatformCreateConnectionInput`}),Ln=e.enum([`connection.requested`,`provider.detection_started`,`provider.selected`,`authorization.required`,`domain_connect.started`,`domain_connect.submitted`,`authorization.completed`,`connection.planning_started`,`connection.plan_prepared`,`connection.planning_restarted`,`connection.already_configured`,`connection.plan_confirmed`,`connection.changes_applied`,`connection.propagation_checked`,`connection.propagation_timed_out`,`connection.activated`,`connection.manual_required`,`connection.manual_submitted`,`connection.failed_retryable`,`connection.retry_started`,`connection.cancelled`]).meta({id:`Domain0WebhookEventType`}),Z=e.string().regex(/^[0-9a-f]{64}$/).brand().meta({id:`Domain0WebhookEventId`}),Rn=e.record(e.string().min(1).max(100),e.string().max(4e3)).superRefine((e,t)=>{Object.keys(e).length>64&&t.addIssue({code:`custom`,message:`Webhook attributes must contain at most 64 entries`})}).meta({id:`Domain0WebhookAttributes`}),zn=e.strictObject({schemaVersion:e.literal(1),eventId:Z,type:Ln,connectionId:n,applicationId:r,tenantId:i,sequence:e.number().int().positive().max(2**53-1),occurredAt:c,attributes:Rn}).meta({id:`Domain0WebhookEvent`}),Bn=e.enum([`invalid_headers`,`stale_timestamp`,`invalid_signature`,`invalid_payload`,`crypto_unavailable`]).meta({id:`Domain0WebhookVerificationErrorCode`});var Vn=class extends Error{code;name=`Domain0WebhookVerificationError`;constructor(e,t,n){super(t,n),this.code=e}};const Q={eventId:`x-domain0-event-id`,eventType:`x-domain0-event-type`,deliveryAttempt:`x-domain0-delivery-attempt`,schemaVersion:`x-domain0-schema-version`,signatureKeyId:`x-domain0-signature-key-id`,timestamp:`x-domain0-timestamp`,signature:`x-domain0-signature`},Hn=e.strictObject({eventId:Z,eventType:e.string().regex(/^domain0\.[a-z_]+\.[a-z_]+$/).max(100),deliveryAttempt:e.string().regex(/^[1-9][0-9]{0,8}$/).transform(Number),schemaVersion:e.literal(`1`),signatureKeyId:e.string().regex(/^[A-Za-z0-9._-]{1,64}$/),timestamp:e.string().regex(/^[0-9]{1,12}$/).transform(Number),signature:e.string().regex(/^v1=[0-9a-f]{64}$/)}),Un=new TextEncoder;async function Wn(e){let t=typeof e.body==`string`?Un.encode(e.body):new Uint8Array(e.body),n=Kn(e.maxBodyBytes??1048576,16777216);if(!(t instanceof Uint8Array)||t.byteLength===0||t.byteLength>n)throw $(`invalid_payload`,`Webhook body is empty or exceeds the configured limit`);let r=Gn(e.headers),i=qn(e.nowUnixSeconds??Math.floor(Date.now()/1e3),2**53-1),a=Kn(e.maxAgeSeconds??300,86400);if(Math.abs(i-r.timestamp)>a)throw $(`stale_timestamp`,`Webhook timestamp is outside the accepted replay window`);let o=Object.prototype.hasOwnProperty.call(e.secretKeyring,r.signatureKeyId)?e.secretKeyring[r.signatureKeyId]:void 0;if(!(o instanceof Uint8Array)||o.byteLength!==32)throw $(`invalid_signature`,`Webhook signature is invalid`);let s=e.crypto??globalThis.crypto;if(s?.subtle===void 0)throw $(`crypto_unavailable`,`Web Crypto is unavailable`);let c=Jn(r.signature.slice(3)),l=Un.encode(`v1.${r.signatureKeyId}.${r.timestamp}.`),u=new Uint8Array(l.byteLength+t.byteLength);u.set(l),u.set(t,l.byteLength);let d=await s.subtle.importKey(`raw`,new Uint8Array(o),{name:`HMAC`,hash:`SHA-256`},!1,[`verify`]);if(!await s.subtle.verify(`HMAC`,d,new Uint8Array(c),u))throw $(`invalid_signature`,`Webhook signature is invalid`);let f;try{let e=new TextDecoder(`utf-8`,{fatal:!0}).decode(t);f=JSON.parse(e)}catch(e){throw $(`invalid_payload`,`Verified webhook body is not valid UTF-8 JSON`,e)}let p=zn.safeParse(f);if(!p.success)throw $(`invalid_payload`,`Verified webhook body does not match schema version 1`,p.error);if(p.data.eventId!==r.eventId||`domain0.${p.data.type}`!==r.eventType||String(p.data.schemaVersion)!==r.schemaVersion)throw $(`invalid_payload`,`Verified webhook headers do not match the event body`);return p.data}function Gn(e){let t={eventId:void 0,eventType:void 0,deliveryAttempt:void 0,schemaVersion:void 0,signatureKeyId:void 0,timestamp:void 0,signature:void 0};if(`get`in e&&typeof e.get==`function`)for(let[n,r]of Object.entries(Q))t[n]=e.get(r)??void 0;else{let n=new Map;for(let e of Object.keys(Q))n.set(Q[e],e);let r=new Set;for(let[i,a]of Object.entries(e)){let e=i.toLowerCase(),o=n.get(e);if(o!==void 0){if(r.has(e)||typeof a!=`string`)throw $(`invalid_headers`,`Webhook headers are missing, duplicated, or malformed`);r.add(e),t[o]=a}}}let n=Hn.safeParse(t);if(!n.success)throw $(`invalid_headers`,`Webhook headers are missing, duplicated, or malformed`,n.error);return n.data}function Kn(e,t){if(!Number.isSafeInteger(e)||e<1||e>t)throw $(`invalid_headers`,`Webhook verification limits are invalid`);return e}function qn(e,t){if(!Number.isSafeInteger(e)||e<0||e>t)throw $(`invalid_headers`,`Webhook verification time is invalid`);return e}function Jn(e){let t=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)t[n/2]=Number.parseInt(e.slice(n,n+2),16);return t}function $(e,t,n){return new Vn(e,t,n===void 0?void 0:{cause:n})}export{A as AccessKeyCredentialsSchema,M as AccountTokenCredentialsSchema,m as AdvancedDmarcOptionsSchema,k as ApiTokenCredentialsSchema,r as ApplicationIdSchema,Ye as ApplyPlanInputSchema,fe as AuthorizationMethodSchema,Ke as AuthorizeWithCredentialInputSchema,Ve as AwsSessionCredentialsSchema,I as CPanelCredentialsSchema,$e as CancelConnectionInputSchema,oe as ChangeActionSchema,Ce as ChangePlanSchema,kn as CheckDomainInputSchema,Nn as CheckDomainResponseSchema,te as CheckRecordsInputSchema,re as CheckRecordsResponseSchema,ne as CheckedRecordSchema,Ue as ClientCredentialsSchema,o as CommandIdSchema,vn as CompiledProviderIdSchema,at as ConditionalDnsRecordsSchema,Re as ConfirmPlanInputSchema,Mn as ConflictAnalysisSchema,ie as ConflictPolicySchema,xe as ConnectionFailureCodeSchema,T as ConnectionFailureSchema,it as ConnectionFlowIdSchema,ft as ConnectionFlowResponseSchema,dt as ConnectionFlowSchema,ct as ConnectionFlowTargetInputSchema,ut as ConnectionFlowTargetSchema,n as ConnectionIdSchema,E as ConnectionSchema,w as ConnectionStateSchema,lt as CreateConnectionFlowInputSchema,we as CreateConnectionInputSchema,Te as CreateConnectionResponseSchema,mt as CreateSharedFlowInputSchema,ht as CreateSharedFlowResponseSchema,Q as DOMAIN0_WEBHOOK_HEADER_NAMES,Oe as DetectProviderResponseSchema,At as DkimDnsEvidenceSchema,Ot as DkimDnsEvidenceStatusSchema,kt as DkimDnsRecordEvidenceSchema,Dt as DkimDnsRecordTypeSchema,xt as DkimGuidanceInputSchema,jt as DkimGuidanceResponseSchema,H as DkimSelectorSchema,y as DnsIntentSchema,_ as DnsRecordSchema,d as DnsRecordTypeSchema,Qt as Domain0ApplicationNameSchema,zt as Domain0ConnectCloseEventSchema,Mt as Domain0ConnectCloseTriggerSchema,_n as Domain0ConnectConfigurationSchema,Rt as Domain0ConnectErrorEventSchema,K as Domain0ConnectErrorSchema,Gt as Domain0ConnectEventSchema,Lt as Domain0ConnectFailureEventSchema,Nt as Domain0ConnectOutcomeSchema,Bt as Domain0ConnectStepChangeEventSchema,W as Domain0ConnectStepSchema,It as Domain0ConnectSuccessEventSchema,St as Domain0DkimGuidanceOptionsSchema,Wt as Domain0DkimSetupDocumentationClickEventSchema,R as Domain0ErrorCodeSchema,pt as Domain0ErrorResponseSchema,Fn as Domain0LocaleSchema,Vt as Domain0ManualSetupDocumentationClickEventSchema,Ht as Domain0RequestCloseEventSchema,qt as Domain0SetupPolicySchema,Ut as Domain0SharedFlowSentEventSchema,Rn as Domain0WebhookAttributesSchema,Z as Domain0WebhookEventIdSchema,zn as Domain0WebhookEventSchema,Ln as Domain0WebhookEventTypeSchema,Vn as Domain0WebhookVerificationError,Bn as Domain0WebhookVerificationErrorCodeSchema,fn as Domain0WhiteLabelCopySchema,mn as Domain0WhiteLabelCustomPropertiesSchema,$t as Domain0WhiteLabelLogoUrlSchema,hn as Domain0WhiteLabelSchema,dn as Domain0WhiteLabelThemeSchema,Ne as DomainConnectTemplateSchema,En as DomainDelegationStatusSchema,s as DomainNameSchema,An as DomainProviderCandidateSchema,jn as DomainRecordConflictSchema,Dn as DomainSetupSupportSchema,Et as EmailProviderDetectionStatusSchema,U as EmailProviderSchema,v as ExistingRecordPolicySchema,Ee as GetConnectionResponseSchema,c as IsoDateTimeSchema,tt as IssueConnectionTokenInputSchema,nt as IssueConnectionTokenResponseSchema,ge as ListProvidersResponseSchema,gn as ManualSetupDocumentationUrlSchema,qe as OAuthCallbackResponseSchema,P as OvhCredentialsSchema,Se as PlanWarningCodeSchema,se as PlannedChangeSchema,In as PlatformCreateConnectionInputSchema,Je as PreparePlanInputSchema,F as PrivateKeyCredentialsSchema,De as ProviderCandidateSchema,pe as ProviderCapabilitiesSchema,yn as ProviderConformanceCheckNameSchema,Sn as ProviderConformanceEvidenceSchema,x as ProviderDetectionSchema,me as ProviderDetectionUnavailableReasonCodeSchema,ve as ProviderHealthReasonSchema,ye as ProviderHealthResponseSchema,C as ProviderHealthSchema,_e as ProviderHealthStatusSchema,a as ProviderIdSchema,de as ProviderImplementationSchema,S as ProviderSchema,On as RecordConflictReasonSchema,gt as ResolveSharedFlowInputSchema,_t as ResolveSharedFlowResponseSchema,b as ResolvedDnsIntentSchema,g as ResolvedDnsRecordSchema,et as RetryConnectionInputSchema,be as RetryResumeStateSchema,ke as SelectProviderInputSchema,z as SharedFlowIdSchema,yt as SharedFlowInvitationSchema,V as SharedFlowInvitationUrlSchema,B as SharedFlowTokenSchema,vt as SharedFlowUrlSchema,ae as SpfConflictPolicySchema,Pe as StartDomainConnectInputSchema,Ie as StartDomainConnectResponseSchema,Ze as StartManualConfigurationInputSchema,ze as StartOAuthInputSchema,Be as StartOAuthResponseSchema,Le as SubmitDomainConnectCompletionInputSchema,Qe as SubmitManualCompletionInputSchema,i as TenantIdSchema,j as UsernamePasswordCredentialsSchema,N as UsernameTokenCredentialsSchema,Cn as VerifiedProviderConformanceEvidenceSchema,Xe as VerifyPropagationInputSchema,en as colorContrastRatio,Ge as directCredentialKindByProvider,Pn as domain0Locales,X as expectedProviderConformanceChecks,Wn as verifyDomain0Webhook};
1666
2
  //# sourceMappingURL=contracts.mjs.map