domainkit 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -12
- package/dist/canonical-json-CQYKsZw7.mjs +310 -0
- package/dist/canonical-json-CQYKsZw7.mjs.map +1 -0
- package/dist/connect-10vHuShV.d.mts +1401 -0
- package/dist/connect-oI8hcMxc.mjs +185 -0
- package/dist/connect-oI8hcMxc.mjs.map +1 -0
- package/dist/connection-C0xsU41C.d.mts +186 -0
- package/dist/connection-api-DW7xUJdj.d.mts +26 -0
- package/dist/index.d.mts +7 -26
- package/dist/index.mjs +12 -5
- package/dist/index.mjs.map +1 -1
- package/dist/managed-dns-connections-C3A_GBaz.mjs +99 -0
- package/dist/managed-dns-connections-C3A_GBaz.mjs.map +1 -0
- package/dist/promise.d.mts +104 -223
- package/dist/promise.mjs +45 -126
- package/dist/promise.mjs.map +1 -1
- package/dist/{resolver-tZU6gEVq.mjs → resolver-DPJs8h0a.mjs} +54 -250
- package/dist/resolver-DPJs8h0a.mjs.map +1 -0
- package/dist/{resolver-BGBLnPjJ.d.mts → resolver-DRrLm_hB.d.mts} +911 -1140
- package/dist/server.d.mts +128 -0
- package/dist/server.mjs +319 -0
- package/dist/server.mjs.map +1 -0
- package/dist/testing.d.mts +5 -4
- package/dist/testing.mjs +13 -18
- package/dist/testing.mjs.map +1 -1
- package/dist/{verify-6xK05pwL.d.mts → verify-C3V_GtzL.d.mts} +45 -20
- package/dist/{verify-B2fPyjde.mjs → verify-DDnK8U7C.mjs} +138 -323
- package/dist/verify-DDnK8U7C.mjs.map +1 -0
- package/package.json +8 -2
- package/dist/resolver-tZU6gEVq.mjs.map +0 -1
- package/dist/verify-B2fPyjde.mjs.map +0 -1
|
@@ -1,177 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { A as Error$4, D as decode$2, E as Schema$3, k as parse$1, n as sha256Encoded, r as stringify } from "./canonical-json-CQYKsZw7.mjs";
|
|
3
|
+
import { Cause, Clock, Context, Data, Effect, Layer, Schema } from "effect";
|
|
3
4
|
import { getDomain } from "tldts";
|
|
4
|
-
//#region src/invalid-input.ts
|
|
5
|
-
var invalid_input_exports = /* @__PURE__ */ __exportAll({ Error: () => Error$5 });
|
|
6
|
-
var Error$5 = class extends Schema.TaggedError()("InvalidInputError", { message: Schema.String }) {};
|
|
7
|
-
//#endregion
|
|
8
|
-
//#region src/domain/domain-name.ts
|
|
9
|
-
var domain_name_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
-
Schema: () => Schema$3,
|
|
11
|
-
decode: () => decode$3,
|
|
12
|
-
parse: () => parse$1
|
|
13
|
-
});
|
|
14
|
-
const labelPattern = /^[a-z0-9_](?:[a-z0-9_-]{0,61}[a-z0-9_])?$/;
|
|
15
|
-
const Type$1 = Schema.String.check(Schema.makeFilter((value) => value.length <= 253 && value.includes(".") && value.split(".").every((label) => labelPattern.test(label)) ? void 0 : "Expected a fully qualified DNS name", { identifier: "DomainName" })).pipe(Schema.brand("DomainName"));
|
|
16
|
-
/** Decodes user and wire strings into canonical domain names. */
|
|
17
|
-
const Schema$3 = Schema.String.pipe(Schema.decodeTo(Type$1, SchemaTransformation.transformOrFail({
|
|
18
|
-
decode: (input, options) => Effect.try({
|
|
19
|
-
try: () => normalize(input),
|
|
20
|
-
catch: (cause) => new SchemaIssue.InvalidValue({ message: cause instanceof Error ? cause.message : String(cause) }, input, options)
|
|
21
|
-
}),
|
|
22
|
-
encode: (domain) => Effect.succeed(domain)
|
|
23
|
-
})));
|
|
24
|
-
const decode$3 = Effect.fn("DomainName.decode")((input) => Schema.decodeUnknownEffect(Schema$3)(input).pipe(Effect.mapError((cause) => new Error$5({ message: cause.message }))));
|
|
25
|
-
function parse$1(input) {
|
|
26
|
-
try {
|
|
27
|
-
return Schema.decodeUnknownSync(Schema$3)(input);
|
|
28
|
-
} catch (cause) {
|
|
29
|
-
throw new Error$5({ message: cause instanceof Error ? cause.message : String(cause) });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function normalize(input) {
|
|
33
|
-
return input.trim().replace(/\.+$/, "").split(".").map((label) => {
|
|
34
|
-
if (label.includes("_") || [...label].every((character) => character.charCodeAt(0) <= 127)) return label.toLowerCase();
|
|
35
|
-
const normalized = new URL(`http://${label}.example`).hostname.split(".")[0];
|
|
36
|
-
if (normalized === void 0) throw new Error("Domain label could not be normalized");
|
|
37
|
-
return normalized.toLowerCase();
|
|
38
|
-
}).join(".");
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/auth/connection.ts
|
|
42
|
-
/** A provider account and authoritative zone selected for one domain attachment. */
|
|
43
|
-
const ProviderTargetEvidence = Schema.Struct({
|
|
44
|
-
/** The account display name observed during discovery, when the provider exposes one. */
|
|
45
|
-
accountName: Schema.optionalKey(Schema.String),
|
|
46
|
-
/** Nameserver and provider-state evidence observed during discovery. */
|
|
47
|
-
nameservers: Schema.Array(Schema$3),
|
|
48
|
-
status: Schema.String,
|
|
49
|
-
/** Provider-specific authoritative-zone type, such as Cloudflare's `full` or Vercel's `external`. */
|
|
50
|
-
zoneType: Schema.String
|
|
51
|
-
});
|
|
52
|
-
const ProviderTarget = Schema.Struct({
|
|
53
|
-
accountId: Schema.String,
|
|
54
|
-
accountKind: Schema.NullOr(Schema.Literals([
|
|
55
|
-
"account",
|
|
56
|
-
"personal",
|
|
57
|
-
"team"
|
|
58
|
-
])),
|
|
59
|
-
evidence: Schema.optionalKey(ProviderTargetEvidence),
|
|
60
|
-
zoneId: Schema.String,
|
|
61
|
-
zoneName: Schema$3
|
|
62
|
-
});
|
|
63
|
-
/** The lifecycle state visible to a host for an organization connection. */
|
|
64
|
-
const ConnectionStatus = Schema.Literals([
|
|
65
|
-
"active",
|
|
66
|
-
"expired",
|
|
67
|
-
"revocation-pending"
|
|
68
|
-
]);
|
|
69
|
-
/** An organization-scoped provider connection. */
|
|
70
|
-
const ProviderConnection = Schema.Struct({
|
|
71
|
-
createdAt: Schema.DateFromString,
|
|
72
|
-
id: Schema.String,
|
|
73
|
-
method: Schema.Literals([
|
|
74
|
-
"integration",
|
|
75
|
-
"oauth2",
|
|
76
|
-
"token"
|
|
77
|
-
]),
|
|
78
|
-
ownerId: Schema.String,
|
|
79
|
-
providerId: Schema.String,
|
|
80
|
-
status: ConnectionStatus
|
|
81
|
-
});
|
|
82
|
-
/** An exact provider target attached to one organization domain. */
|
|
83
|
-
const DomainAttachment = Schema.Struct({
|
|
84
|
-
connectionId: Schema.String,
|
|
85
|
-
createdAt: Schema.DateFromString,
|
|
86
|
-
domain: Schema$3,
|
|
87
|
-
id: Schema.String,
|
|
88
|
-
target: ProviderTarget
|
|
89
|
-
});
|
|
90
|
-
Schema.Struct({
|
|
91
|
-
authorizationId: Schema.String,
|
|
92
|
-
createdAt: Schema.DateFromString,
|
|
93
|
-
id: Schema.String,
|
|
94
|
-
method: Schema.Literals([
|
|
95
|
-
"integration",
|
|
96
|
-
"oauth2",
|
|
97
|
-
"token"
|
|
98
|
-
]),
|
|
99
|
-
ownerId: Schema.String,
|
|
100
|
-
providerId: Schema.String
|
|
101
|
-
});
|
|
102
|
-
var AuthorizationError$1 = class extends Schema.TaggedError()("AuthorizationError", {
|
|
103
|
-
category: Schema.Literal("authorization"),
|
|
104
|
-
message: Schema.String,
|
|
105
|
-
operation: Schema.String,
|
|
106
|
-
retry: Schema.Literals([
|
|
107
|
-
"never",
|
|
108
|
-
"after-user-action",
|
|
109
|
-
"safe",
|
|
110
|
-
"unknown"
|
|
111
|
-
])
|
|
112
|
-
}) {};
|
|
113
|
-
const authorizationError = (message, operation) => new AuthorizationError$1({
|
|
114
|
-
category: "authorization",
|
|
115
|
-
message,
|
|
116
|
-
operation,
|
|
117
|
-
retry: "after-user-action"
|
|
118
|
-
});
|
|
119
|
-
/** Decode a public connection snapshot returned by a host. */
|
|
120
|
-
const decode$2 = Effect.fn("ProviderConnection.decode")((input) => Schema.decodeUnknownEffect(ProviderConnection)(input).pipe(Effect.mapError((cause) => new Error$5({ message: cause.message }))));
|
|
121
|
-
const validate$2 = Effect.fn("ProviderConnection.validate")((input) => Schema.decodeUnknownEffect(Schema.toType(ProviderConnection))(input).pipe(Effect.mapError((cause) => new Error$5({ message: cause.message }))));
|
|
122
|
-
const encode$1 = Schema.encodeSync(ProviderConnection);
|
|
123
|
-
/** Derive a public connection projection from its private authorization state. */
|
|
124
|
-
function project(connection, authorization, now = /* @__PURE__ */ new Date()) {
|
|
125
|
-
const status = authorization.revocation._tag === "Pending" ? "revocation-pending" : authorization.expiresAt !== null && authorization.expiresAt <= now ? "expired" : "active";
|
|
126
|
-
return {
|
|
127
|
-
createdAt: connection.createdAt,
|
|
128
|
-
id: connection.id,
|
|
129
|
-
method: connection.method,
|
|
130
|
-
ownerId: connection.ownerId,
|
|
131
|
-
providerId: connection.providerId,
|
|
132
|
-
status
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
/** Assert that an exact attachment is usable for one DNS operation. */
|
|
136
|
-
function assertAttachment(input) {
|
|
137
|
-
if (input.connection.providerId !== input.providerId || input.authorization.providerId !== input.providerId || input.authorization.revocation._tag !== "Active" || input.attachment.connectionId !== input.connection.id) throw authorizationError("Domain attachment is not active for this provider", "Connection.assertAttachment");
|
|
138
|
-
if (input.authorization.expiresAt !== null) {
|
|
139
|
-
if (Number.isNaN(input.authorization.expiresAt.getTime())) throw authorizationError("Provider authorization expiration is invalid", "Connection.assertAttachment");
|
|
140
|
-
if (input.authorization.expiresAt <= (input.now ?? /* @__PURE__ */ new Date())) throw authorizationError("Provider authorization has expired", "Connection.assertAttachment");
|
|
141
|
-
}
|
|
142
|
-
if (!input.authorization.requiredCapabilities.includes(input.capability)) throw authorizationError(`Provider authorization lacks the ${input.capability} capability`, "Connection.assertAttachment");
|
|
143
|
-
if (!input.authorization.capabilityEvidence.some((item) => item.capability === input.capability)) throw authorizationError(`Provider authorization has no evidence for the ${input.capability} capability`, "Connection.assertAttachment");
|
|
144
|
-
let domain;
|
|
145
|
-
try {
|
|
146
|
-
domain = parse$1(input.domain);
|
|
147
|
-
} catch (cause) {
|
|
148
|
-
if (cause instanceof Error$5) throw cause;
|
|
149
|
-
throw new Error$5({ message: cause instanceof Error ? cause.message : String(cause) });
|
|
150
|
-
}
|
|
151
|
-
if (input.attachment.domain !== domain && !domain.endsWith(`.${input.attachment.domain}`)) throw authorizationError("Domain attachment does not match the requested domain", "Connection.assertAttachment");
|
|
152
|
-
return domain;
|
|
153
|
-
}
|
|
154
|
-
//#endregion
|
|
155
|
-
//#region src/auth/lifecycle-repository.ts
|
|
156
|
-
var Error$4 = class extends Schema.TaggedError()("ManagedDnsLifecycleError", {
|
|
157
|
-
category: Schema.Literal("storage"),
|
|
158
|
-
message: Schema.String,
|
|
159
|
-
operation: Schema.String,
|
|
160
|
-
retry: Schema.Literals([
|
|
161
|
-
"never",
|
|
162
|
-
"after-user-action",
|
|
163
|
-
"safe",
|
|
164
|
-
"unknown"
|
|
165
|
-
])
|
|
166
|
-
}) {};
|
|
167
|
-
var Service$3 = class extends Context.Service()("@domainkit/ManagedDnsConnections") {};
|
|
168
|
-
//#endregion
|
|
169
5
|
//#region src/discovery/zones.ts
|
|
170
6
|
var zones_exports = /* @__PURE__ */ __exportAll({ candidates: () => candidates });
|
|
171
7
|
function candidates(input) {
|
|
172
8
|
const domain = parse$1(input);
|
|
173
9
|
const registrable = getDomain(domain, { allowPrivateDomains: true });
|
|
174
|
-
if (registrable === null) throw new Error$
|
|
10
|
+
if (registrable === null) throw new Error$4({ message: "Domain does not have a registrable DNS zone" });
|
|
175
11
|
const labels = domain.split(".");
|
|
176
12
|
const registrableLabels = registrable.split(".").length;
|
|
177
13
|
const values = [];
|
|
@@ -348,20 +184,19 @@ const Schema$2 = Schema.TaggedUnion({
|
|
|
348
184
|
});
|
|
349
185
|
const { A, AAAA: Aaaa, CAA: Caa, CNAME: Cname, MX: Mx, NS: Ns, SRV: Srv, TXT: Txt } = Schema$2.cases;
|
|
350
186
|
/** Provider state that DomainKit cannot create but must retain for safe reconciliation. */
|
|
351
|
-
const Opaque = Schema.
|
|
352
|
-
_tag: Schema.Literal("Opaque"),
|
|
187
|
+
const Opaque = Schema.TaggedStruct("Opaque", {
|
|
353
188
|
name: Schema.String.check(Schema.isMinLength(1)),
|
|
354
189
|
providerRecordId: Schema.NullOr(Schema.String),
|
|
355
190
|
providerType: Schema.String.check(Schema.isMinLength(1))
|
|
356
191
|
});
|
|
357
192
|
/** Any DNS record observed through a provider, including non-portable record types. */
|
|
358
193
|
const Observed = Schema.Union([Schema$2, Opaque]);
|
|
359
|
-
const decode$1 = Effect.fn("DnsRecord.decode")((input) => Schema.decodeUnknownEffect(Schema$2)(input).pipe(Effect.mapError((cause) => new Error$
|
|
194
|
+
const decode$1 = Effect.fn("DnsRecord.decode")((input) => Schema.decodeUnknownEffect(Schema$2)(input).pipe(Effect.mapError((cause) => new Error$4({ message: cause.message }))));
|
|
360
195
|
function parse(input) {
|
|
361
196
|
try {
|
|
362
197
|
return Schema.decodeUnknownSync(Schema$2)(input);
|
|
363
198
|
} catch (cause) {
|
|
364
|
-
throw new Error$
|
|
199
|
+
throw new Error$4({ message: cause instanceof Error ? cause.message : String(cause) });
|
|
365
200
|
}
|
|
366
201
|
}
|
|
367
202
|
function data(record) {
|
|
@@ -470,58 +305,6 @@ function failure(provider, operation, cause) {
|
|
|
470
305
|
});
|
|
471
306
|
}
|
|
472
307
|
//#endregion
|
|
473
|
-
//#region src/plan/canonical-json.ts
|
|
474
|
-
var canonical_json_exports = /* @__PURE__ */ __exportAll({
|
|
475
|
-
CryptoError: () => CryptoError,
|
|
476
|
-
sha256Encoded: () => sha256Encoded,
|
|
477
|
-
sha256Json: () => sha256Json,
|
|
478
|
-
sha256Text: () => sha256Text,
|
|
479
|
-
stringify: () => stringify,
|
|
480
|
-
webCryptoLayer: () => webCryptoLayer
|
|
481
|
-
});
|
|
482
|
-
var CryptoError = class extends Schema.TaggedError()("CryptoError", { message: Schema.String }) {};
|
|
483
|
-
/** Deterministic JSON serialization for already schema-encoded protocol values. */
|
|
484
|
-
function stringify(value) {
|
|
485
|
-
if (value === null || typeof value !== "object") {
|
|
486
|
-
const encoded = JSON.stringify(value);
|
|
487
|
-
if (encoded === void 0) throw new TypeError("Value is not representable as JSON");
|
|
488
|
-
return encoded;
|
|
489
|
-
}
|
|
490
|
-
if (isJsonArray(value)) return `[${value.map(stringify).join(",")}]`;
|
|
491
|
-
return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, entry]) => `${JSON.stringify(key)}:${stringify(entry)}`).join(",")}}`;
|
|
492
|
-
}
|
|
493
|
-
function isJsonArray(value) {
|
|
494
|
-
return Array.isArray(value);
|
|
495
|
-
}
|
|
496
|
-
const sha256Text = Effect.fn("Digest.sha256Text")(function* (value) {
|
|
497
|
-
return [...yield* (yield* Crypto.Crypto).digest("SHA-256", new TextEncoder().encode(value)).pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })))].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
498
|
-
});
|
|
499
|
-
const sha256Json = Effect.fn("Digest.sha256Json")((value) => Effect.try({
|
|
500
|
-
try: () => stringify(value),
|
|
501
|
-
catch: (cause) => new CryptoError({ message: cause instanceof Error ? cause.message : String(cause) })
|
|
502
|
-
}).pipe(Effect.flatMap(sha256Text)));
|
|
503
|
-
function sha256EncodedProgram(schema, value) {
|
|
504
|
-
return Schema.encodeEffect(schema)(value).pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })), Effect.flatMap(Schema.decodeUnknownEffect(Schema.Json)), Effect.mapError((cause) => new CryptoError({ message: cause.message })), Effect.flatMap(sha256Json));
|
|
505
|
-
}
|
|
506
|
-
const sha256Encoded = Effect.fn("Digest.sha256Encoded")(sha256EncodedProgram);
|
|
507
|
-
/** Portable Web Crypto implementation for hosts that want a ready-made Layer. */
|
|
508
|
-
const webCryptoLayer = Layer.succeed(Crypto.Crypto, Crypto.make({
|
|
509
|
-
randomBytes: (size) => crypto.getRandomValues(new Uint8Array(size)),
|
|
510
|
-
digest: (algorithm, data) => Effect.tryPromise({
|
|
511
|
-
try: async () => {
|
|
512
|
-
const bytes = new Uint8Array(data.byteLength);
|
|
513
|
-
bytes.set(data);
|
|
514
|
-
return new Uint8Array(await crypto.subtle.digest(algorithm, bytes.buffer));
|
|
515
|
-
},
|
|
516
|
-
catch: (cause) => PlatformError.systemError({
|
|
517
|
-
_tag: "Unknown",
|
|
518
|
-
module: "WebCrypto",
|
|
519
|
-
method: "digest",
|
|
520
|
-
cause
|
|
521
|
-
})
|
|
522
|
-
})
|
|
523
|
-
}));
|
|
524
|
-
//#endregion
|
|
525
308
|
//#region src/plan/types.ts
|
|
526
309
|
var types_exports = /* @__PURE__ */ __exportAll({
|
|
527
310
|
Authorization: () => Authorization$1,
|
|
@@ -533,7 +316,7 @@ var types_exports = /* @__PURE__ */ __exportAll({
|
|
|
533
316
|
encode: () => encode,
|
|
534
317
|
encodeReceipt: () => encodeReceipt
|
|
535
318
|
});
|
|
536
|
-
const
|
|
319
|
+
const OperationSchema = Schema.TaggedUnion({
|
|
537
320
|
create: {
|
|
538
321
|
id: Schema.String,
|
|
539
322
|
requirement: Schema$2
|
|
@@ -550,9 +333,16 @@ const Operation$1 = Schema.TaggedUnion({
|
|
|
550
333
|
requirement: Schema$2
|
|
551
334
|
}
|
|
552
335
|
});
|
|
336
|
+
/** DNS plan operation schema and callable constructors for trusted plan values. */
|
|
337
|
+
const Operation$1 = {
|
|
338
|
+
Schema: OperationSchema,
|
|
339
|
+
conflict: (input) => OperationSchema.cases.conflict.make(input),
|
|
340
|
+
create: (input) => OperationSchema.cases.create.make(input),
|
|
341
|
+
noop: (input) => OperationSchema.cases.noop.make(input)
|
|
342
|
+
};
|
|
553
343
|
const Schema$1 = Schema.Struct({
|
|
554
344
|
digest: Schema.String,
|
|
555
|
-
operations: Schema.Array(Operation$1),
|
|
345
|
+
operations: Schema.Array(Operation$1.Schema),
|
|
556
346
|
providerId: Schema.String,
|
|
557
347
|
version: Schema.Literal("domainkit.dns-plan.v1"),
|
|
558
348
|
zone: Schema$3
|
|
@@ -575,9 +365,9 @@ const Receipt$1 = Schema.Struct({
|
|
|
575
365
|
version: Schema.Literal("domainkit.apply-receipt.v1"),
|
|
576
366
|
zone: Schema$3
|
|
577
367
|
});
|
|
578
|
-
const decode = Effect.fn("DnsPlan.decode")((input) => Schema.decodeUnknownEffect(Schema$1)(input).pipe(Effect.mapError((cause) => new Error$
|
|
368
|
+
const decode = Effect.fn("DnsPlan.decode")((input) => Schema.decodeUnknownEffect(Schema$1)(input).pipe(Effect.mapError((cause) => new Error$4({ message: cause.message }))));
|
|
579
369
|
const encode = Schema.encodeSync(Schema$1);
|
|
580
|
-
const decodeReceipt = Effect.fn("DnsPlan.decodeReceipt")((input) => Schema.decodeUnknownEffect(Receipt$1)(input).pipe(Effect.mapError((cause) => new Error$
|
|
370
|
+
const decodeReceipt = Effect.fn("DnsPlan.decodeReceipt")((input) => Schema.decodeUnknownEffect(Receipt$1)(input).pipe(Effect.mapError((cause) => new Error$4({ message: cause.message }))));
|
|
581
371
|
const encodeReceipt = Schema.encodeSync(Receipt$1);
|
|
582
372
|
//#endregion
|
|
583
373
|
//#region src/plan/plan.ts
|
|
@@ -595,7 +385,7 @@ var plan_exports = /* @__PURE__ */ __exportAll({
|
|
|
595
385
|
validate: () => validate$1
|
|
596
386
|
});
|
|
597
387
|
const UnsignedPlan$1 = Schema.Struct({
|
|
598
|
-
operations: Schema.Array(Operation$1),
|
|
388
|
+
operations: Schema.Array(Operation$1.Schema),
|
|
599
389
|
providerId: Schema.String,
|
|
600
390
|
version: Schema.Literal("domainkit.dns-plan.v1"),
|
|
601
391
|
zone: Schema$3
|
|
@@ -625,7 +415,7 @@ function create$1(input) {
|
|
|
625
415
|
const target = input.target;
|
|
626
416
|
if (target._tag === "ExactZone") return Effect.gen(function* () {
|
|
627
417
|
const provider = yield* Service$1;
|
|
628
|
-
const zone = yield* decode$
|
|
418
|
+
const zone = yield* decode$2(target.zone);
|
|
629
419
|
return CreateResult.Resolved({
|
|
630
420
|
candidate: null,
|
|
631
421
|
plan: yield* planAgainst(provider, zone, input.requirements)
|
|
@@ -633,7 +423,7 @@ function create$1(input) {
|
|
|
633
423
|
}).pipe(Effect.withSpan("Provisioning.create"));
|
|
634
424
|
return Effect.gen(function* () {
|
|
635
425
|
const discovery = yield* Service$2;
|
|
636
|
-
const domain = yield* decode$
|
|
426
|
+
const domain = yield* decode$2(target.domain);
|
|
637
427
|
const outcome = yield* discovery.discover(domain);
|
|
638
428
|
switch (outcome._tag) {
|
|
639
429
|
case "NotFound": return CreateResult.NotFound({ domain: outcome.domain });
|
|
@@ -690,7 +480,7 @@ const apply$1 = Effect.fn("Provisioning.apply")(function* (input) {
|
|
|
690
480
|
if (provider.id !== plan.providerId) return yield* new AuthorizationError({ message: "Provider does not match the approved plan" });
|
|
691
481
|
const conflicts = plan.operations.filter((operation) => operation._tag === "conflict");
|
|
692
482
|
if (conflicts.length > 0) return yield* new ConflictError({ operationIds: conflicts.map(({ id }) => id) });
|
|
693
|
-
const creates = plan.operations.filter(
|
|
483
|
+
const creates = plan.operations.filter((operation) => operation._tag === "create");
|
|
694
484
|
const approved = new Set(authorization.operationIds);
|
|
695
485
|
const unknown = authorization.operationIds.filter((id) => !creates.some((operation) => operation.id === id));
|
|
696
486
|
if (unknown.length > 0) return yield* new AuthorizationError({ message: `Authorization contains unknown operations: ${unknown.join(", ")}` });
|
|
@@ -760,31 +550,27 @@ function reconcileRequirement(requirement, allExisting) {
|
|
|
760
550
|
const sameSet = sameName.filter((record) => record._tag !== "Opaque" && record._tag === requirement._tag);
|
|
761
551
|
const exact = sameSet.find((record) => equals(record, requirement));
|
|
762
552
|
const id = yield* sha256Encoded(RequirementDigest, { requirement });
|
|
763
|
-
if (exact !== void 0) return {
|
|
764
|
-
_tag: "noop",
|
|
553
|
+
if (exact !== void 0) return Operation$1.noop({
|
|
765
554
|
id,
|
|
766
555
|
requirement,
|
|
767
556
|
ttlDrift: exact.ttl !== requirement.ttl
|
|
768
|
-
};
|
|
769
|
-
if (sameName.length > 0 && (requirement._tag === "CNAME" || sameName.some((record) => record._tag === "CNAME"))) return {
|
|
770
|
-
_tag: "conflict",
|
|
557
|
+
});
|
|
558
|
+
if (sameName.length > 0 && (requirement._tag === "CNAME" || sameName.some((record) => record._tag === "CNAME"))) return Operation$1.conflict({
|
|
771
559
|
existing: sameName,
|
|
772
560
|
id,
|
|
773
561
|
reason: "CNAME records cannot coexist with other records at the same name",
|
|
774
562
|
requirement
|
|
775
|
-
};
|
|
776
|
-
if (sameSet.length > 0 && (requirement.policy === "exclusive" || sameSet.some(({ policy }) => policy === "exclusive"))) return {
|
|
777
|
-
_tag: "conflict",
|
|
563
|
+
});
|
|
564
|
+
if (sameSet.length > 0 && (requirement.policy === "exclusive" || sameSet.some(({ policy }) => policy === "exclusive"))) return Operation$1.conflict({
|
|
778
565
|
existing: sameSet,
|
|
779
566
|
id,
|
|
780
567
|
reason: "The exclusive record set already contains incompatible data",
|
|
781
568
|
requirement
|
|
782
|
-
};
|
|
783
|
-
return {
|
|
784
|
-
_tag: "create",
|
|
569
|
+
});
|
|
570
|
+
return Operation$1.create({
|
|
785
571
|
id,
|
|
786
572
|
requirement
|
|
787
|
-
};
|
|
573
|
+
});
|
|
788
574
|
});
|
|
789
575
|
}
|
|
790
576
|
function validate$1(plan) {
|
|
@@ -995,6 +781,7 @@ function makeReceipt(plan, operations, status) {
|
|
|
995
781
|
//#region src/verification/resolver.ts
|
|
996
782
|
var resolver_exports = /* @__PURE__ */ __exportAll({
|
|
997
783
|
Answer: () => Answer,
|
|
784
|
+
AsyncResolution: () => AsyncResolution,
|
|
998
785
|
Error: () => Error$1,
|
|
999
786
|
Resolution: () => Resolution,
|
|
1000
787
|
Service: () => Service,
|
|
@@ -1007,10 +794,16 @@ const Answer = Schema.Struct({
|
|
|
1007
794
|
ttl: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
1008
795
|
type: Type
|
|
1009
796
|
});
|
|
1010
|
-
const
|
|
797
|
+
const ResolutionSchema = Schema.TaggedUnion({
|
|
1011
798
|
answer: { answers: Schema.Array(Answer) },
|
|
1012
799
|
nodata: {}
|
|
1013
800
|
});
|
|
801
|
+
/** DNS answer schema and callable constructors for trusted resolver values. */
|
|
802
|
+
const Resolution = {
|
|
803
|
+
Schema: ResolutionSchema,
|
|
804
|
+
answer: (input) => ResolutionSchema.cases.answer.make(input),
|
|
805
|
+
nodata: () => ResolutionSchema.cases.nodata.make({})
|
|
806
|
+
};
|
|
1014
807
|
var Error$1 = class extends Schema.TaggedError()("ResolverError", {
|
|
1015
808
|
cause: Schema.optionalKey(Schema.Unknown),
|
|
1016
809
|
message: Schema.String,
|
|
@@ -1021,6 +814,20 @@ var Error$1 = class extends Schema.TaggedError()("ResolverError", {
|
|
|
1021
814
|
])
|
|
1022
815
|
}) {};
|
|
1023
816
|
var Service = class extends Context.Service()("@domainkit/DnsResolver") {};
|
|
817
|
+
const AsyncResolutionSchema = Schema.TaggedUnion({
|
|
818
|
+
answer: { answers: Schema.Array(Answer) },
|
|
819
|
+
nodata: {},
|
|
820
|
+
timeout: {},
|
|
821
|
+
failure: { message: Schema.String }
|
|
822
|
+
});
|
|
823
|
+
/** Promise bridge result schema and callable constructors, including typed failures. */
|
|
824
|
+
const AsyncResolution = {
|
|
825
|
+
Schema: AsyncResolutionSchema,
|
|
826
|
+
answer: (input) => AsyncResolutionSchema.cases.answer.make(input),
|
|
827
|
+
failure: (input) => AsyncResolutionSchema.cases.failure.make(input),
|
|
828
|
+
nodata: () => AsyncResolutionSchema.cases.nodata.make({}),
|
|
829
|
+
timeout: () => AsyncResolutionSchema.cases.timeout.make({})
|
|
830
|
+
};
|
|
1024
831
|
const layerFromAsync = (resolver) => Layer.succeed(Service, { resolve: Effect.fn("DnsResolver.resolve")((query) => Effect.tryPromise({
|
|
1025
832
|
try: () => resolver.resolve(query),
|
|
1026
833
|
catch: (cause) => new Error$1({
|
|
@@ -1043,13 +850,10 @@ const layerFromAsync = (resolver) => Layer.succeed(Service, { resolve: Effect.fn
|
|
|
1043
850
|
}
|
|
1044
851
|
}))) });
|
|
1045
852
|
const toAsync = (resolver) => ({ resolve: (query) => Effect.runPromise(resolver.resolve(query).pipe(Effect.match({
|
|
1046
|
-
onFailure: (failure) => failure.reason === "timeout" ? {
|
|
1047
|
-
_tag: "failure",
|
|
1048
|
-
message: failure.message
|
|
1049
|
-
},
|
|
853
|
+
onFailure: (failure) => failure.reason === "timeout" ? AsyncResolution.timeout() : AsyncResolution.failure({ message: failure.message }),
|
|
1050
854
|
onSuccess: (resolution) => resolution
|
|
1051
855
|
}))) });
|
|
1052
856
|
//#endregion
|
|
1053
|
-
export { Txt as $,
|
|
857
|
+
export { Txt as $, Schema$1 as A, provider_exports as B, authorize$1 as C, Authorization$1 as D, renderManualInstructions as E, types_exports as F, Cname as G, A as H, Error$3 as I, Observed as J, Mx as K, Service$1 as L, decodeReceipt as M, encode as N, Operation$1 as O, encodeReceipt as P, Srv as Q, fromAsync as R, apply$1 as S, plan_exports as T, Aaaa as U, toAsync$1 as V, Caa as W, RequirementMetadata as X, Opaque as Y, Schema$2 as Z, ConflictError as _, resolver_exports as a, parse as at, StaleError as b, Error$2 as c, make as ct, Plan as d, zones_exports as dt, Type as et, Receipt as f, deletion_exports as g, create as h, Service as i, equals as it, decode as j, Receipt$1 as k, Operation as l, zone_discovery_exports as lt, authorize as m, Error$1 as n, decode$1 as nt, toAsync as o, Candidate as ot, apply as p, Ns as q, Resolution as r, dns_record_exports as rt, Authorization as s, Service$2 as st, AsyncResolution as t, data as tt, PartialError as u, candidates as ut, CreateResult as v, create$1 as w, Target as x, PartialApplyError as y, layerFromAsync$1 as z };
|
|
1054
858
|
|
|
1055
|
-
//# sourceMappingURL=resolver-
|
|
859
|
+
//# sourceMappingURL=resolver-DPJs8h0a.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver-DPJs8h0a.mjs","names":["DomainName.parse","InvalidInputError","Domain.Schema","Service","Zones.candidates","S","DomainName.Schema","Schema","decode","InvalidInputError","Error","Service","layerFromAsync","toAsync","S","DnsRecord.Schema","DnsRecord.Observed","Operation","Schema","DomainName.Schema","Authorization","Receipt","InvalidInputError","UnsignedPlan","S","DomainName.Schema","DnsRecord.Schema","DnsPlan.Receipt","create","DnsProvider.Service","DomainName.decode","ZoneDiscovery.Service","DnsRecord.decode","authorize","validate","apply","makeReceipt","data","DnsRecord.data","DnsRecord.equals","DnsRecord.Observed","S","DnsRecord.Schema","DomainName.Schema","Error","DnsProvider.Service","Provisioning.validate","DnsRecord.equals","DomainName.Schema","DnsRecord.Type","Error"],"sources":["../src/discovery/zones.ts","../src/discovery/zone-discovery.ts","../src/domain/dns-record.ts","../src/provider/provider.ts","../src/plan/types.ts","../src/plan/plan.ts","../src/plan/deletion.ts","../src/verification/resolver.ts"],"sourcesContent":["import { getDomain } from \"tldts\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\nexport function candidates(input: string): ReadonlyArray<DomainName.DomainName> {\n const domain = DomainName.parse(input);\n const registrable = getDomain(domain, { allowPrivateDomains: true });\n if (registrable === null) {\n throw new InvalidInputError({ message: \"Domain does not have a registrable DNS zone\" });\n }\n const labels = domain.split(\".\");\n const registrableLabels = registrable.split(\".\").length;\n const values: Array<DomainName.DomainName> = [];\n for (let index = 0; index <= labels.length - registrableLabels; index += 1) {\n values.push(DomainName.parse(labels.slice(index).join(\".\")));\n }\n return values;\n}\n","import { Context, Data, Effect, Schema } from \"effect\";\n\nimport type * as DomainName from \"../domain/domain-name.ts\";\nimport * as Domain from \"../domain/domain-name.ts\";\nimport * as DnsProvider from \"../provider/provider.ts\";\nimport * as Zones from \"./zones.ts\";\n\n/** Display-safe identity and nameserver evidence for one provider-owned zone. */\nexport const Candidate = Schema.Struct({\n accountId: Schema.String,\n id: Schema.String,\n name: Domain.Schema,\n nameservers: Schema.Array(Domain.Schema),\n providerId: Schema.String,\n status: Schema.Literals([\"active\", \"pending\", \"unknown\"]),\n});\nexport interface Candidate extends Schema.Schema.Type<typeof Candidate> {}\n\nexport interface Source {\n readonly listZones: (\n name: DomainName.DomainName,\n ) => Effect.Effect<ReadonlyArray<Omit<Candidate, \"providerId\">>, DnsProvider.Error>;\n readonly provider: DnsProvider.Interface;\n}\n\nexport type Outcome = Data.TaggedEnum<{\n NotFound: { readonly domain: DomainName.DomainName };\n Resolved: { readonly candidate: Candidate; readonly provider: DnsProvider.Interface };\n SelectionRequired: { readonly candidates: ReadonlyArray<Candidate> };\n}>;\nexport const Outcome = Data.taggedEnum<Outcome>();\n\nexport interface Interface {\n readonly discover: (domain: DomainName.DomainName) => Effect.Effect<Outcome, DnsProvider.Error>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@domainkit/ZoneDiscovery\") {}\n\n/** Compose provider-account discovery sources without expanding the record-provider contract. */\nexport function make(sources: ReadonlyArray<Source>): Interface {\n return Service.of({\n discover: Effect.fn(\"ZoneDiscovery.discover\")(function* (domain) {\n for (const name of Zones.candidates(domain)) {\n const matches = deduplicate(\n (yield* Effect.forEach(\n sources,\n (source) =>\n source.listZones(name).pipe(\n Effect.map((zones) =>\n zones\n .filter((zone) => zone.name === name)\n .map((zone) => ({\n candidate: { ...zone, providerId: source.provider.id },\n provider: source.provider,\n })),\n ),\n ),\n { concurrency: \"unbounded\" },\n )).flat(),\n );\n const match = matches[0];\n if (matches.length === 1 && match !== undefined) {\n return Outcome.Resolved(match);\n }\n if (matches.length > 1) {\n return Outcome.SelectionRequired({\n candidates: matches.map(({ candidate }) => candidate),\n });\n }\n }\n return Outcome.NotFound({ domain });\n }),\n });\n}\n\nfunction deduplicate(\n matches: ReadonlyArray<{\n readonly candidate: Candidate;\n readonly provider: DnsProvider.Interface;\n }>,\n): ReadonlyArray<{\n readonly candidate: Candidate;\n readonly provider: DnsProvider.Interface;\n}> {\n const unique = new Map<string, (typeof matches)[number]>();\n for (const match of matches) {\n const key = [\n match.candidate.providerId,\n match.candidate.accountId,\n match.candidate.id,\n match.candidate.name,\n ].join(\":\");\n const existing = unique.get(key);\n if (existing === undefined) unique.set(key, match);\n }\n return [...unique.values()].sort((left, right) =>\n candidateKey(left.candidate).localeCompare(candidateKey(right.candidate)),\n );\n}\n\nfunction candidateKey(candidate: Candidate): string {\n return [candidate.name, candidate.providerId, candidate.accountId, candidate.id].join(\":\");\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport * as DomainName from \"./domain-name.ts\";\n\nexport const Type = S.Literals([\"A\", \"AAAA\", \"CNAME\", \"TXT\", \"MX\", \"CAA\", \"NS\", \"SRV\"]);\nexport type Type = typeof Type.Type;\n\nexport const RequirementMetadata = S.Struct({\n ownership: S.String.check(S.isMinLength(1)),\n provenance: S.String.check(S.isMinLength(1)),\n purpose: S.String.check(S.isMinLength(1)),\n});\nexport interface RequirementMetadata extends S.Schema.Type<typeof RequirementMetadata> {}\n\nconst CommonFields = {\n metadata: RequirementMetadata,\n name: DomainName.Schema,\n policy: S.Literals([\"exclusive\", \"append\"]),\n ttl: S.NullOr(S.Int.check(S.isBetween({ minimum: 60, maximum: 2_147_483_647 }))),\n};\n\nconst ExclusiveCommonFields = { ...CommonFields, policy: S.Literal(\"exclusive\") };\nconst Address = S.String.check(\n S.makeFilter((value) => (isIpv4(value) ? undefined : \"Expected an IPv4 address\")),\n);\nconst Ipv6Address = S.String.check(\n S.makeFilter((value) => (isIpv6(value) ? undefined : \"Expected an IPv6 address\")),\n);\nconst Port = S.Int.check(S.isBetween({ minimum: 0, maximum: 65_535 }));\nconst Priority = S.Int.check(S.isBetween({ minimum: 0, maximum: 65_535 }));\n\nexport const Schema = S.TaggedUnion({\n A: { ...CommonFields, address: Address },\n AAAA: { ...CommonFields, address: Ipv6Address },\n CNAME: { ...ExclusiveCommonFields, target: DomainName.Schema },\n TXT: { ...CommonFields, value: S.String.check(S.isMinLength(1)) },\n MX: { ...CommonFields, exchange: DomainName.Schema, priority: Priority },\n CAA: {\n ...CommonFields,\n flags: S.Int.check(S.isBetween({ minimum: 0, maximum: 255 })),\n tag: S.Literals([\"issue\", \"issuewild\", \"iodef\"]),\n value: S.String.check(S.isMinLength(1)),\n },\n NS: { ...CommonFields, target: DomainName.Schema },\n SRV: {\n ...CommonFields,\n port: Port,\n priority: Priority,\n target: DomainName.Schema,\n weight: Priority,\n },\n});\nexport const {\n A,\n AAAA: Aaaa,\n CAA: Caa,\n CNAME: Cname,\n MX: Mx,\n NS: Ns,\n SRV: Srv,\n TXT: Txt,\n} = Schema.cases;\nexport type DnsRecord = typeof Schema.Type;\nexport type Encoded = typeof Schema.Encoded;\n\n/** Provider state that DomainKit cannot create but must retain for safe reconciliation. */\nexport const Opaque = S.TaggedStruct(\"Opaque\", {\n name: S.String.check(S.isMinLength(1)),\n providerRecordId: S.NullOr(S.String),\n providerType: S.String.check(S.isMinLength(1)),\n});\nexport interface Opaque extends S.Schema.Type<typeof Opaque> {}\n\n/** Any DNS record observed through a provider, including non-portable record types. */\nexport const Observed = S.Union([Schema, Opaque]);\nexport type Observed = typeof Observed.Type;\n\nexport const decode = Effect.fn(\"DnsRecord.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport function parse(input: unknown): DnsRecord {\n try {\n return S.decodeUnknownSync(Schema)(input);\n } catch (cause) {\n throw new InvalidInputError({\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n}\n\nexport function data(record: DnsRecord): Readonly<Record<string, number | string>> {\n switch (record._tag) {\n case \"A\":\n case \"AAAA\":\n return { address: record.address };\n case \"CNAME\":\n case \"NS\":\n return { target: record.target };\n case \"TXT\":\n return { value: record.value };\n case \"MX\":\n return { exchange: record.exchange, priority: record.priority };\n case \"CAA\":\n return { flags: record.flags, tag: record.tag, value: record.value };\n case \"SRV\":\n return {\n port: record.port,\n priority: record.priority,\n target: record.target,\n weight: record.weight,\n };\n }\n}\n\nexport function equals(left: DnsRecord, right: DnsRecord): boolean {\n return (\n left._tag === right._tag &&\n left.name === right.name &&\n JSON.stringify(data(left)) === JSON.stringify(data(right))\n );\n}\n\nfunction isIpv4(value: string): boolean {\n const parts = value.split(\".\");\n return (\n parts.length === 4 &&\n parts.every(\n (part) => /^\\d{1,3}$/.test(part) && Number(part) <= 255 && String(Number(part)) === part,\n )\n );\n}\n\nfunction isIpv6(value: string): boolean {\n try {\n return new URL(`http://[${value}]/`).hostname.startsWith(\"[\");\n } catch {\n return false;\n }\n}\n","import { Context, Effect, Layer, Schema } from \"effect\";\n\nimport type * as DomainName from \"../domain/domain-name.ts\";\nimport type * as DnsRecord from \"../domain/dns-record.ts\";\n\nexport interface CreateResult {\n readonly providerRecordId: string | null;\n}\n\nexport const ErrorReason = Schema.Literals([\n \"authentication\",\n \"authorization\",\n \"conflict\",\n \"not_found\",\n \"rate_limit\",\n \"request\",\n \"response\",\n \"transport\",\n \"unsupported\",\n]);\nexport type ErrorReason = typeof ErrorReason.Type;\n\nexport class Error extends Schema.TaggedError<Error>()(\"ProviderError\", {\n cause: Schema.optionalKey(Schema.Unknown),\n code: Schema.optionalKey(Schema.Union([Schema.Number, Schema.String])),\n message: Schema.String,\n operation: Schema.String,\n providerId: Schema.String,\n reason: Schema.optionalKey(ErrorReason),\n retryAfterMs: Schema.optionalKey(Schema.Number),\n status: Schema.optionalKey(Schema.Number),\n}) {}\n\n/** The provider capability used by DNS planning, application, and verification. */\nexport interface Interface {\n readonly id: string;\n readonly createRecord: (\n zone: DomainName.DomainName,\n record: DnsRecord.DnsRecord,\n ) => Effect.Effect<CreateResult, Error>;\n readonly deleteRecord: (\n zone: DomainName.DomainName,\n providerRecordId: string,\n ) => Effect.Effect<void, Error>;\n readonly getRecord: (\n zone: DomainName.DomainName,\n providerRecordId: string,\n ) => Effect.Effect<DnsRecord.Observed | null, Error>;\n readonly listRecords: (\n zone: DomainName.DomainName,\n ) => Effect.Effect<ReadonlyArray<DnsRecord.Observed>, Error>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@domainkit/DnsProvider\") {}\n\n/** Minimal Promise-shaped provider contract for hosts that do not use Effect directly. */\nexport interface AsyncInterface {\n readonly id: string;\n readonly createRecord: (\n zone: DomainName.DomainName,\n record: DnsRecord.DnsRecord,\n ) => Promise<CreateResult>;\n readonly deleteRecord: (zone: DomainName.DomainName, providerRecordId: string) => Promise<void>;\n readonly getRecord: (\n zone: DomainName.DomainName,\n providerRecordId: string,\n ) => Promise<DnsRecord.Observed | null>;\n readonly listRecords: (zone: DomainName.DomainName) => Promise<ReadonlyArray<DnsRecord.Observed>>;\n}\n\nexport const fromAsync = (provider: AsyncInterface): Interface =>\n Service.of({\n id: provider.id,\n createRecord: Effect.fn(\"DnsProvider.createRecord\")((zone, record) =>\n Effect.tryPromise({\n try: () => provider.createRecord(zone, record),\n catch: (cause) => failure(provider, \"createRecord\", cause),\n }),\n ),\n deleteRecord: Effect.fn(\"DnsProvider.deleteRecord\")((zone, providerRecordId) =>\n Effect.tryPromise({\n try: () => provider.deleteRecord(zone, providerRecordId),\n catch: (cause) => failure(provider, \"deleteRecord\", cause),\n }),\n ),\n getRecord: Effect.fn(\"DnsProvider.getRecord\")((zone, providerRecordId) =>\n Effect.tryPromise({\n try: () => provider.getRecord(zone, providerRecordId),\n catch: (cause) => failure(provider, \"getRecord\", cause),\n }),\n ),\n listRecords: Effect.fn(\"DnsProvider.listRecords\")((zone) =>\n Effect.tryPromise({\n try: () => provider.listRecords(zone),\n catch: (cause) => failure(provider, \"listRecords\", cause),\n }),\n ),\n });\n\nexport const layerFromAsync = (provider: AsyncInterface): Layer.Layer<Service> =>\n Layer.succeed(Service, fromAsync(provider));\n\nexport const toAsync = (provider: Interface): AsyncInterface => ({\n id: provider.id,\n createRecord: (zone, record) => Effect.runPromise(provider.createRecord(zone, record)),\n deleteRecord: (zone, providerRecordId) =>\n Effect.runPromise(provider.deleteRecord(zone, providerRecordId)),\n getRecord: (zone, providerRecordId) =>\n Effect.runPromise(provider.getRecord(zone, providerRecordId)),\n listRecords: (zone) => Effect.runPromise(provider.listRecords(zone)),\n});\n\nfunction failure(provider: AsyncInterface, operation: string, cause: unknown): Error {\n return cause instanceof Error\n ? cause\n : new Error({\n cause,\n message: cause instanceof globalThis.Error ? cause.message : String(cause),\n operation,\n providerId: provider.id,\n });\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport * as DnsRecord from \"../domain/dns-record.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\nconst OperationSchema = S.TaggedUnion({\n create: {\n id: S.String,\n requirement: DnsRecord.Schema,\n },\n noop: {\n id: S.String,\n requirement: DnsRecord.Schema,\n ttlDrift: S.Boolean,\n },\n conflict: {\n existing: S.Array(DnsRecord.Observed),\n id: S.String,\n reason: S.String,\n requirement: DnsRecord.Schema,\n },\n});\n/** DNS plan operation schema and callable constructors for trusted plan values. */\nexport const Operation = {\n Schema: OperationSchema,\n conflict: (input: Parameters<typeof OperationSchema.cases.conflict.make>[0]) =>\n OperationSchema.cases.conflict.make(input),\n create: (input: Parameters<typeof OperationSchema.cases.create.make>[0]) =>\n OperationSchema.cases.create.make(input),\n noop: (input: Parameters<typeof OperationSchema.cases.noop.make>[0]) =>\n OperationSchema.cases.noop.make(input),\n};\nexport type Operation = typeof OperationSchema.Type;\n\nexport const Schema = S.Struct({\n digest: S.String,\n operations: S.Array(Operation.Schema),\n providerId: S.String,\n version: S.Literal(\"domainkit.dns-plan.v1\"),\n zone: DomainName.Schema,\n});\nexport interface DnsPlan extends S.Schema.Type<typeof Schema> {}\n\nexport const Authorization = S.Struct({\n allowPartial: S.Boolean,\n operationIds: S.Array(S.String),\n planDigest: S.String,\n version: S.Literal(\"domainkit.plan-authorization.v1\"),\n});\nexport interface PlanAuthorization extends S.Schema.Type<typeof Authorization> {}\n\nexport const Receipt = S.Struct({\n appliedAt: S.DateFromString,\n operations: S.Array(\n S.Struct({\n operationId: S.String,\n providerRecordId: S.NullOr(S.String),\n }),\n ),\n planDigest: S.String,\n providerId: S.String,\n status: S.Literals([\"complete\", \"partial\"]),\n version: S.Literal(\"domainkit.apply-receipt.v1\"),\n zone: DomainName.Schema,\n});\nexport interface ApplyReceipt extends S.Schema.Type<typeof Receipt> {}\n\nexport const decode = Effect.fn(\"DnsPlan.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = S.encodeSync(Schema);\nexport const decodeReceipt = Effect.fn(\"DnsPlan.decodeReceipt\")((input: unknown) =>\n S.decodeUnknownEffect(Receipt)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\nexport const encodeReceipt = S.encodeSync(Receipt);\n","import { Cause, Clock, Crypto, Data, Effect, Schema as S } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport * as DnsRecord from \"../domain/dns-record.ts\";\nimport * as ZoneDiscovery from \"../discovery/zone-discovery.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport * as DnsProvider from \"../provider/provider.ts\";\nimport { CryptoError, sha256Encoded, stringify } from \"./canonical-json.ts\";\nimport * as DnsPlan from \"./types.ts\";\n\nconst UnsignedPlan = S.Struct({\n operations: S.Array(DnsPlan.Operation.Schema),\n providerId: S.String,\n version: S.Literal(\"domainkit.dns-plan.v1\"),\n zone: DomainName.Schema,\n});\n\nconst RequirementDigest = S.Struct({ requirement: DnsRecord.Schema });\n\nexport class ConflictError extends S.TaggedError<ConflictError>()(\"PlanConflictError\", {\n operationIds: S.Array(S.String),\n}) {}\n\nexport class AuthorizationError extends S.TaggedError<AuthorizationError>()(\"AuthorizationError\", {\n message: S.String,\n}) {}\n\nexport class StaleError extends S.TaggedError<StaleError>()(\"StalePlanError\", {\n approvedPlanDigest: S.String,\n currentPlanDigest: S.String,\n}) {}\n\nexport class PartialApplyError extends S.TaggedError<PartialApplyError>()(\"PartialApplyError\", {\n causeTag: S.Literals([\n \"CryptoError\",\n \"InvalidInputError\",\n \"Interrupted\",\n \"ProviderError\",\n \"StalePlanError\",\n ]),\n failedOperationId: S.String,\n message: S.String,\n receipt: DnsPlan.Receipt,\n}) {}\n\nexport type Target = Data.TaggedEnum<{\n DiscoverFromDomain: { readonly domain: string };\n ExactZone: { readonly zone: string };\n}>;\nexport const Target = Data.taggedEnum<Target>();\n\nexport type CreateResult = Data.TaggedEnum<{\n NotFound: { readonly domain: DomainName.DomainName };\n Resolved: {\n readonly candidate: ZoneDiscovery.Candidate | null;\n readonly plan: DnsPlan.DnsPlan;\n };\n SelectionRequired: { readonly candidates: ReadonlyArray<ZoneDiscovery.Candidate> };\n}>;\nexport const CreateResult = Data.taggedEnum<CreateResult>();\nexport type ResolvedCreateResult = Extract<CreateResult, { readonly _tag: \"Resolved\" }>;\n\nexport interface CreateInput {\n readonly requirements: ReadonlyArray<DnsRecord.Encoded | DnsRecord.DnsRecord>;\n readonly target: Target;\n}\nexport type ExactCreateInput = Omit<CreateInput, \"target\"> & {\n readonly target: Extract<Target, { readonly _tag: \"ExactZone\" }>;\n};\nexport type DiscoverCreateInput = Omit<CreateInput, \"target\"> & {\n readonly target: Extract<Target, { readonly _tag: \"DiscoverFromDomain\" }>;\n};\n\nexport interface ApplyInput {\n readonly authorization: DnsPlan.PlanAuthorization;\n readonly plan: DnsPlan.DnsPlan;\n}\n\nexport type CreateError = InvalidInputError | DnsProvider.Error | CryptoError;\nexport type AuthorizeError = AuthorizationError | CryptoError;\nexport type ApplyError =\n | InvalidInputError\n | DnsProvider.Error\n | CryptoError\n | AuthorizationError\n | ConflictError\n | StaleError\n | PartialApplyError;\n\n/** Builds a deterministic DNS plan through an exact or discoverable authoritative-zone target. */\nexport function create(\n input: ExactCreateInput,\n): Effect.Effect<ResolvedCreateResult, CreateError, Crypto.Crypto | DnsProvider.Service>;\nexport function create(\n input: DiscoverCreateInput,\n): Effect.Effect<CreateResult, CreateError, Crypto.Crypto | ZoneDiscovery.Service>;\nexport function create(\n input: CreateInput,\n): Effect.Effect<\n CreateResult,\n CreateError,\n Crypto.Crypto | DnsProvider.Service | ZoneDiscovery.Service\n> {\n const target = input.target;\n if (target._tag === \"ExactZone\") {\n return Effect.gen(function* () {\n const provider = yield* DnsProvider.Service;\n const zone = yield* DomainName.decode(target.zone);\n return CreateResult.Resolved({\n candidate: null,\n plan: yield* planAgainst(provider, zone, input.requirements),\n });\n }).pipe(Effect.withSpan(\"Provisioning.create\"));\n }\n return Effect.gen(function* () {\n const discovery = yield* ZoneDiscovery.Service;\n const domain = yield* DomainName.decode(target.domain);\n const outcome = yield* discovery.discover(domain);\n switch (outcome._tag) {\n case \"NotFound\":\n return CreateResult.NotFound({ domain: outcome.domain });\n case \"SelectionRequired\":\n return CreateResult.SelectionRequired({ candidates: outcome.candidates });\n case \"Resolved\":\n return CreateResult.Resolved({\n candidate: outcome.candidate,\n plan: yield* planAgainst(outcome.provider, outcome.candidate.name, input.requirements),\n });\n }\n }).pipe(Effect.withSpan(\"Provisioning.create\"));\n}\n\nconst planAgainst = Effect.fn(\"Provisioning.planAgainst\")(function* (\n provider: DnsProvider.Interface,\n zone: DomainName.DomainName,\n inputs: ReadonlyArray<DnsRecord.Encoded | DnsRecord.DnsRecord>,\n) {\n const requirements = (yield* Effect.forEach(inputs, DnsRecord.decode, {\n concurrency: \"unbounded\",\n })).sort(compareRecords);\n const existing = [...(yield* provider.listRecords(zone))].sort(compareRecords);\n const { operations } = yield* Effect.reduce(\n requirements,\n (): PlanningState => ({ operations: [], projected: existing }),\n (state, requirement) =>\n reconcileRequirement(requirement, state.projected).pipe(\n Effect.map((operation) => ({\n operations: [...state.operations, operation],\n projected:\n operation._tag === \"create\"\n ? [...state.projected, operation.requirement].sort(compareRecords)\n : state.projected,\n })),\n ),\n );\n const unsigned: S.Schema.Type<typeof UnsignedPlan> = {\n operations,\n providerId: provider.id,\n version: \"domainkit.dns-plan.v1\",\n zone,\n };\n return { ...unsigned, digest: yield* sha256Encoded(UnsignedPlan, unsigned) };\n});\n\ninterface PlanningState {\n readonly operations: ReadonlyArray<DnsPlan.Operation>;\n readonly projected: ReadonlyArray<DnsRecord.Observed>;\n}\n\n/** Authorizes all or a selected subset of create operations in a digest-bound plan. */\nexport const authorize = Effect.fn(\"Provisioning.authorize\")(function* (\n plan: DnsPlan.DnsPlan,\n operationIds?: ReadonlyArray<string>,\n options: { readonly allowPartial?: boolean } = {},\n) {\n yield* validate(plan);\n const createIds = plan.operations\n .filter((operation) => operation._tag === \"create\")\n .map(({ id }) => id);\n const selected = [...new Set(operationIds ?? createIds)].sort();\n const unknown = selected.filter((id) => !createIds.includes(id));\n if (unknown.length > 0) {\n return yield* new AuthorizationError({\n message: `Unknown operation IDs: ${unknown.join(\", \")}`,\n });\n }\n if (!options.allowPartial && selected.length !== createIds.length) {\n return yield* new AuthorizationError({\n message: \"Partial authorization requires allowPartial\",\n });\n }\n return {\n allowPartial: options.allowPartial ?? false,\n operationIds: selected,\n planDigest: plan.digest,\n version: \"domainkit.plan-authorization.v1\" as const,\n };\n});\n\n/** Applies approved creates sequentially after full and per-operation revalidation. */\nexport const apply = Effect.fn(\"Provisioning.apply\")(function* (input: ApplyInput) {\n const { authorization, plan } = input;\n const provider = yield* DnsProvider.Service;\n yield* validate(plan);\n if (authorization.planDigest !== plan.digest) {\n return yield* new AuthorizationError({\n message: \"Authorization belongs to a different plan\",\n });\n }\n if (provider.id !== plan.providerId) {\n return yield* new AuthorizationError({\n message: \"Provider does not match the approved plan\",\n });\n }\n const conflicts = plan.operations.filter((operation) => operation._tag === \"conflict\");\n if (conflicts.length > 0) {\n return yield* new ConflictError({\n operationIds: conflicts.map(({ id }) => id),\n });\n }\n\n const creates = plan.operations.filter(\n (operation): operation is Extract<DnsPlan.Operation, { readonly _tag: \"create\" }> =>\n operation._tag === \"create\",\n );\n const approved = new Set(authorization.operationIds);\n const unknown = authorization.operationIds.filter(\n (id) => !creates.some((operation) => operation.id === id),\n );\n if (unknown.length > 0) {\n return yield* new AuthorizationError({\n message: `Authorization contains unknown operations: ${unknown.join(\", \")}`,\n });\n }\n if (!authorization.allowPartial && creates.some(({ id }) => !approved.has(id))) {\n return yield* new AuthorizationError({\n message: \"Authorization does not cover every create operation\",\n });\n }\n\n const currentPlan = yield* planAgainst(\n provider,\n plan.zone,\n plan.operations.map(({ requirement }) => requirement),\n );\n if (currentPlan.digest !== plan.digest) {\n return yield* new StaleError({\n approvedPlanDigest: plan.digest,\n currentPlanDigest: currentPlan.digest,\n });\n }\n\n const operations: Array<{\n operationId: string;\n providerRecordId: string | null;\n }> = [];\n for (const operation of creates) {\n if (!approved.has(operation.id)) continue;\n yield* Effect.gen(function* () {\n yield* assertStillCreatable(plan, operation);\n const result = yield* provider.createRecord(plan.zone, operation.requirement);\n operations.push({\n operationId: operation.id,\n providerRecordId: result.providerRecordId,\n });\n }).pipe(\n Effect.catch((failure): Effect.Effect<never, CreateError | StaleError | PartialApplyError> =>\n operations.length === 0\n ? Effect.fail(failure)\n : makeReceipt(input, operations, \"partial\").pipe(\n Effect.flatMap((receipt) =>\n Effect.fail(\n new PartialApplyError({\n causeTag: failure._tag,\n failedOperationId: operation.id,\n message: failureMessage(failure),\n receipt,\n }),\n ),\n ),\n ),\n ),\n Effect.catchCause((cause) => {\n if (!Cause.hasInterruptsOnly(cause) || operations.length === 0) {\n return Effect.failCause(cause);\n }\n return makeReceipt(input, operations, \"partial\").pipe(\n Effect.flatMap((receipt) =>\n Effect.fail(\n new PartialApplyError({\n causeTag: \"Interrupted\",\n failedOperationId: operation.id,\n message: \"DNS apply was interrupted after confirmed writes\",\n receipt,\n }),\n ),\n ),\n );\n }),\n );\n }\n return yield* makeReceipt(input, operations, \"complete\");\n});\n\nexport function renderManualInstructions(plan: DnsPlan.DnsPlan): ReadonlyArray<string> {\n return plan.operations.map((operation) => {\n const record = operation.requirement;\n const data = Object.entries(DnsRecord.data(record))\n .map(([key, value]) => `${key}=${value}`)\n .join(\" \");\n return `${operation._tag.toUpperCase()} ${record._tag} ${record.name} ${data}`.trim();\n });\n}\n\nfunction makeReceipt(\n input: ApplyInput,\n operations: ReadonlyArray<{\n readonly operationId: string;\n readonly providerRecordId: string | null;\n }>,\n status: \"complete\" | \"partial\",\n): Effect.Effect<DnsPlan.ApplyReceipt> {\n return Clock.currentTimeMillis.pipe(\n Effect.map((now) => ({\n appliedAt: new Date(now),\n operations,\n planDigest: input.plan.digest,\n providerId: input.plan.providerId,\n status,\n version: \"domainkit.apply-receipt.v1\" as const,\n zone: input.plan.zone,\n })),\n );\n}\n\nfunction assertStillCreatable(\n plan: DnsPlan.DnsPlan,\n operation: Extract<DnsPlan.Operation, { readonly _tag: \"create\" }>,\n): Effect.Effect<void, CreateError | StaleError, DnsProvider.Service | Crypto.Crypto> {\n return DnsProvider.Service.pipe(\n Effect.flatMap((provider) => planAgainst(provider, plan.zone, [operation.requirement])),\n Effect.flatMap((currentPlan) => {\n const currentOperation = currentPlan.operations[0];\n return currentOperation?._tag === \"create\" && currentOperation.id === operation.id\n ? Effect.void\n : Effect.fail(\n new StaleError({\n approvedPlanDigest: plan.digest,\n currentPlanDigest: currentPlan.digest,\n }),\n );\n }),\n );\n}\n\nfunction reconcileRequirement(\n requirement: DnsRecord.DnsRecord,\n allExisting: ReadonlyArray<DnsRecord.Observed>,\n): Effect.Effect<DnsPlan.Operation, CryptoError, Crypto.Crypto> {\n return Effect.gen(function* () {\n const sameName = allExisting.filter((record) => record.name === requirement.name);\n const sameSet = sameName.filter(\n (record): record is DnsRecord.DnsRecord =>\n record._tag !== \"Opaque\" && record._tag === requirement._tag,\n );\n const exact = sameSet.find((record) => DnsRecord.equals(record, requirement));\n const id = yield* sha256Encoded(RequirementDigest, { requirement });\n if (exact !== undefined) {\n return DnsPlan.Operation.noop({\n id,\n requirement,\n ttlDrift: exact.ttl !== requirement.ttl,\n });\n }\n const cnameConflict =\n sameName.length > 0 &&\n (requirement._tag === \"CNAME\" || sameName.some((record) => record._tag === \"CNAME\"));\n if (cnameConflict) {\n return DnsPlan.Operation.conflict({\n existing: sameName,\n id,\n reason: \"CNAME records cannot coexist with other records at the same name\",\n requirement,\n });\n }\n if (\n sameSet.length > 0 &&\n (requirement.policy === \"exclusive\" || sameSet.some(({ policy }) => policy === \"exclusive\"))\n ) {\n return DnsPlan.Operation.conflict({\n existing: sameSet,\n id,\n reason: \"The exclusive record set already contains incompatible data\",\n requirement,\n });\n }\n return DnsPlan.Operation.create({ id, requirement });\n });\n}\n\nexport function validate(\n plan: DnsPlan.DnsPlan,\n): Effect.Effect<void, AuthorizeError, Crypto.Crypto> {\n const unsigned: S.Schema.Type<typeof UnsignedPlan> = {\n operations: plan.operations,\n providerId: plan.providerId,\n version: plan.version,\n zone: plan.zone,\n };\n return sha256Encoded(UnsignedPlan, unsigned).pipe(\n Effect.flatMap((digest) =>\n digest === plan.digest\n ? Effect.void\n : Effect.fail(\n new AuthorizationError({\n message: \"Plan digest does not match its contents\",\n }),\n ),\n ),\n );\n}\n\nfunction failureMessage(failure: CreateError | StaleError): string {\n return failure._tag === \"StalePlanError\"\n ? \"DNS state changed while applying the approved plan\"\n : failure.message;\n}\n\nfunction compareRecords(left: DnsRecord.Observed, right: DnsRecord.Observed): number {\n const encode = S.encodeSync(DnsRecord.Observed);\n const toJson = S.decodeUnknownSync(S.Json);\n const leftJson = stringify(toJson(encode(left)));\n const rightJson = stringify(toJson(encode(right)));\n return leftJson < rightJson ? -1 : leftJson > rightJson ? 1 : 0;\n}\n","import { Clock, Crypto, Effect, Schema as S } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport * as DnsRecord from \"../domain/dns-record.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport * as DnsProvider from \"../provider/provider.ts\";\nimport { CryptoError, sha256Encoded } from \"./canonical-json.ts\";\nimport * as Provisioning from \"./plan.ts\";\nimport * as DnsPlan from \"./types.ts\";\n\nexport const Operation = S.Struct({\n id: S.String,\n providerRecordId: S.String,\n record: DnsRecord.Schema,\n});\nexport interface Operation extends S.Schema.Type<typeof Operation> {}\n\nconst UnsignedPlan = S.Struct({\n createdAt: S.DateFromString,\n expiresAt: S.DateFromString,\n operations: S.Array(Operation),\n providerId: S.String,\n sourcePlanDigest: S.String,\n version: S.Literal(\"domainkit.deletion-plan.v1\"),\n zone: DomainName.Schema,\n});\n\nexport const Plan = S.Struct({ ...UnsignedPlan.fields, digest: S.String });\nexport interface Plan extends S.Schema.Type<typeof Plan> {}\n\nexport const Authorization = S.Struct({\n operationIds: S.Array(S.String),\n planDigest: S.String,\n version: S.Literal(\"domainkit.deletion-authorization.v1\"),\n});\nexport interface Authorization extends S.Schema.Type<typeof Authorization> {}\n\nexport const Receipt = S.Struct({\n deletedAt: S.DateFromString,\n operations: S.Array(S.Struct({ operationId: S.String, providerRecordId: S.String })),\n planDigest: S.String,\n providerId: S.String,\n status: S.Literals([\"complete\", \"partial\"]),\n version: S.Literal(\"domainkit.deletion-receipt.v1\"),\n zone: DomainName.Schema,\n});\nexport interface Receipt extends S.Schema.Type<typeof Receipt> {}\n\nexport class Error extends S.TaggedError<Error>()(\"UnsafeDeletionError\", {\n message: S.String,\n operationId: S.optionalKey(S.String),\n}) {}\n\nexport class PartialError extends S.TaggedError<PartialError>()(\"PartialDeletionError\", {\n failedOperationId: S.String,\n message: S.String,\n receipt: Receipt,\n}) {}\n\nexport interface CreateInput {\n readonly plan: DnsPlan.DnsPlan;\n readonly receipt: DnsPlan.ApplyReceipt;\n readonly ttlMs?: number;\n}\n\n/** Build a fresh deletion plan only from records proven by a prior create receipt. */\nexport const create = Effect.fn(\"Deletion.create\")(function* (input: CreateInput) {\n const provider = yield* DnsProvider.Service;\n yield* Provisioning.validate(input.plan);\n if (\n input.receipt.planDigest !== input.plan.digest ||\n input.receipt.providerId !== input.plan.providerId ||\n input.receipt.zone !== input.plan.zone\n ) {\n return yield* new Error({ message: \"Create receipt does not belong to the source plan\" });\n }\n if (provider.id !== input.plan.providerId) {\n return yield* new Error({ message: \"Provider does not match the source receipt\" });\n }\n const operations = yield* Effect.forEach(input.receipt.operations, (applied) =>\n Effect.gen(function* () {\n const source = input.plan.operations.find(\n (operation) => operation._tag === \"create\" && operation.id === applied.operationId,\n );\n if (source === undefined || source._tag !== \"create\") {\n return yield* new Error({\n message: \"Receipt operation is not a created source record\",\n operationId: applied.operationId,\n });\n }\n if (applied.providerRecordId === null) {\n return yield* new Error({\n message: \"Provider record ID is required for safe deletion\",\n operationId: applied.operationId,\n });\n }\n yield* assertExact(\n provider,\n input.plan.zone,\n applied.providerRecordId,\n source.requirement,\n source.id,\n );\n return {\n id: source.id,\n providerRecordId: applied.providerRecordId,\n record: source.requirement,\n };\n }),\n );\n const now = yield* Clock.currentTimeMillis;\n const unsigned: S.Schema.Type<typeof UnsignedPlan> = {\n createdAt: new Date(now),\n expiresAt: new Date(now + (input.ttlMs ?? 15 * 60_000)),\n operations,\n providerId: input.plan.providerId,\n sourcePlanDigest: input.plan.digest,\n version: \"domainkit.deletion-plan.v1\",\n zone: input.plan.zone,\n };\n return { ...unsigned, digest: yield* sha256Encoded(UnsignedPlan, unsigned) };\n});\n\n/** Produce a separate digest-bound consent artifact for destructive operations. */\nexport const authorize = Effect.fn(\"Deletion.authorize\")(function* (\n plan: Plan,\n operationIds?: ReadonlyArray<string>,\n) {\n yield* validate(plan);\n const selected = [...new Set(operationIds ?? plan.operations.map(({ id }) => id))].sort();\n const unknown = selected.filter(\n (id) => !plan.operations.some((operation) => operation.id === id),\n );\n if (unknown.length > 0) {\n return yield* new Error({ message: `Unknown deletion operation IDs: ${unknown.join(\", \")}` });\n }\n return {\n operationIds: selected,\n planDigest: plan.digest,\n version: \"domainkit.deletion-authorization.v1\" as const,\n };\n});\n\n/** Re-read every approved record before the first delete, then delete by provider record ID. */\nexport const apply = Effect.fn(\"Deletion.apply\")(function* (input: {\n readonly authorization: Authorization;\n readonly plan: Plan;\n readonly priorReceipt?: Receipt;\n}) {\n const provider = yield* DnsProvider.Service;\n yield* validate(input.plan);\n if (input.authorization.planDigest !== input.plan.digest) {\n return yield* new Error({ message: \"Deletion authorization belongs to a different plan\" });\n }\n if (provider.id !== input.plan.providerId) {\n return yield* new Error({ message: \"Provider does not match the deletion plan\" });\n }\n const now = yield* Clock.currentTimeMillis;\n if (input.plan.expiresAt <= new Date(now)) {\n return yield* new Error({ message: \"Deletion plan has expired\" });\n }\n const selected = input.plan.operations.filter(({ id }) =>\n input.authorization.operationIds.includes(id),\n );\n if (selected.length !== input.authorization.operationIds.length) {\n return yield* new Error({ message: \"Deletion authorization contains unknown operations\" });\n }\n const previouslyDeleted = yield* validatePriorReceipt(input.plan, input.priorReceipt);\n const completedIds = new Set(previouslyDeleted.map(({ operationId }) => operationId));\n if (\n previouslyDeleted.some(\n ({ operationId }) => !input.authorization.operationIds.includes(operationId),\n )\n ) {\n return yield* new Error({ message: \"Prior receipt contains an unauthorized operation\" });\n }\n const remaining = selected.filter(({ id }) => !completedIds.has(id));\n yield* Effect.forEach(remaining, (operation) =>\n assertExact(\n provider,\n input.plan.zone,\n operation.providerRecordId,\n operation.record,\n operation.id,\n ),\n );\n\n const deleted: Array<{ operationId: string; providerRecordId: string }> = [...previouslyDeleted];\n for (const operation of remaining) {\n const failure = yield* Effect.gen(function* () {\n yield* assertExact(\n provider,\n input.plan.zone,\n operation.providerRecordId,\n operation.record,\n operation.id,\n );\n yield* provider.deleteRecord(input.plan.zone, operation.providerRecordId);\n deleted.push({ operationId: operation.id, providerRecordId: operation.providerRecordId });\n }).pipe(Effect.match({ onFailure: (cause) => cause, onSuccess: () => null }));\n if (failure !== null) {\n if (deleted.length === 0) return yield* failure;\n return yield* new PartialError({\n failedOperationId: operation.id,\n message: failure.message,\n receipt: yield* makeReceipt(input.plan, deleted, \"partial\"),\n });\n }\n }\n return yield* makeReceipt(input.plan, deleted, \"complete\");\n});\n\nexport function validate(plan: Plan): Effect.Effect<void, Error | CryptoError, Crypto.Crypto> {\n const unsigned: S.Schema.Type<typeof UnsignedPlan> = {\n createdAt: plan.createdAt,\n expiresAt: plan.expiresAt,\n operations: plan.operations,\n providerId: plan.providerId,\n sourcePlanDigest: plan.sourcePlanDigest,\n version: plan.version,\n zone: plan.zone,\n };\n return sha256Encoded(UnsignedPlan, unsigned).pipe(\n Effect.flatMap((digest) =>\n digest === plan.digest\n ? Effect.void\n : Effect.fail(new Error({ message: \"Deletion plan digest does not match its contents\" })),\n ),\n );\n}\n\nfunction validatePriorReceipt(\n plan: Plan,\n receipt: Receipt | undefined,\n): Effect.Effect<ReadonlyArray<{ operationId: string; providerRecordId: string }>, Error> {\n if (receipt === undefined) return Effect.succeed([]);\n if (\n receipt.planDigest !== plan.digest ||\n receipt.providerId !== plan.providerId ||\n receipt.zone !== plan.zone ||\n receipt.status !== \"partial\"\n ) {\n return Effect.fail(\n new Error({ message: \"Prior receipt does not belong to this deletion plan\" }),\n );\n }\n for (const completed of receipt.operations) {\n const operation = plan.operations.find(({ id }) => id === completed.operationId);\n if (operation === undefined || operation.providerRecordId !== completed.providerRecordId) {\n return Effect.fail(\n new Error({ message: \"Prior receipt operation does not match the deletion plan\" }),\n );\n }\n }\n return Effect.succeed([...receipt.operations]);\n}\n\nfunction assertExact(\n provider: DnsProvider.Interface,\n zone: DomainName.DomainName,\n providerRecordId: string,\n expected: DnsRecord.DnsRecord,\n operationId: string,\n): Effect.Effect<void, Error | DnsProvider.Error> {\n return provider.getRecord(zone, providerRecordId).pipe(\n Effect.flatMap((observed) =>\n observed !== null && observed._tag !== \"Opaque\" && DnsRecord.equals(observed, expected)\n ? Effect.void\n : Effect.fail(\n new Error({\n message:\n observed === null\n ? \"Created record no longer exists\"\n : \"Created record content no longer matches its receipt\",\n operationId,\n }),\n ),\n ),\n );\n}\n\nfunction makeReceipt(\n plan: Plan,\n operations: ReadonlyArray<{ readonly operationId: string; readonly providerRecordId: string }>,\n status: \"complete\" | \"partial\",\n): Effect.Effect<Receipt> {\n return Clock.currentTimeMillis.pipe(\n Effect.map((now) => ({\n deletedAt: new Date(now),\n operations,\n planDigest: plan.digest,\n providerId: plan.providerId,\n status,\n version: \"domainkit.deletion-receipt.v1\" as const,\n zone: plan.zone,\n })),\n );\n}\n\nexport type CreateError =\n | Error\n | InvalidInputError\n | Provisioning.AuthorizationError\n | DnsProvider.Error\n | CryptoError;\nexport type ApplyError = Error | PartialError | DnsProvider.Error | CryptoError;\nexport type Requirements = DnsProvider.Service | Crypto.Crypto;\n","import { Context, Effect, Layer, Schema } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport * as DnsRecord from \"../domain/dns-record.ts\";\n\nexport interface Query {\n readonly name: DomainName.DomainName;\n readonly signal?: AbortSignal;\n readonly type: DnsRecord.Type;\n}\n\nexport const Answer = Schema.Struct({\n data: Schema.String,\n name: DomainName.Schema,\n ttl: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n type: DnsRecord.Type,\n});\nexport interface Answer extends Schema.Schema.Type<typeof Answer> {}\n\nconst ResolutionSchema = Schema.TaggedUnion({\n answer: { answers: Schema.Array(Answer) },\n nodata: {},\n});\n/** DNS answer schema and callable constructors for trusted resolver values. */\nexport const Resolution = {\n Schema: ResolutionSchema,\n answer: (input: Parameters<typeof ResolutionSchema.cases.answer.make>[0]) =>\n ResolutionSchema.cases.answer.make(input),\n nodata: () => ResolutionSchema.cases.nodata.make({}),\n};\nexport type Resolution = typeof ResolutionSchema.Type;\n\nexport class Error extends Schema.TaggedError<Error>()(\"ResolverError\", {\n cause: Schema.optionalKey(Schema.Unknown),\n message: Schema.String,\n reason: Schema.Literals([\"response\", \"timeout\", \"transport\"]),\n}) {}\n\nexport interface Interface {\n readonly resolve: (query: Query) => Effect.Effect<Resolution, Error>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@domainkit/DnsResolver\") {}\n\nconst AsyncResolutionSchema = Schema.TaggedUnion({\n answer: { answers: Schema.Array(Answer) },\n nodata: {},\n timeout: {},\n failure: { message: Schema.String },\n});\n/** Promise bridge result schema and callable constructors, including typed failures. */\nexport const AsyncResolution = {\n Schema: AsyncResolutionSchema,\n answer: (input: Parameters<typeof AsyncResolutionSchema.cases.answer.make>[0]) =>\n AsyncResolutionSchema.cases.answer.make(input),\n failure: (input: Parameters<typeof AsyncResolutionSchema.cases.failure.make>[0]) =>\n AsyncResolutionSchema.cases.failure.make(input),\n nodata: () => AsyncResolutionSchema.cases.nodata.make({}),\n timeout: () => AsyncResolutionSchema.cases.timeout.make({}),\n};\nexport type AsyncResolution = typeof AsyncResolutionSchema.Type;\n\nexport interface AsyncInterface {\n readonly resolve: (query: Query) => Promise<AsyncResolution>;\n}\n\nexport const layerFromAsync = (resolver: AsyncInterface): Layer.Layer<Service> =>\n Layer.succeed(Service, {\n resolve: Effect.fn(\"DnsResolver.resolve\")((query) =>\n Effect.tryPromise({\n try: () => resolver.resolve(query),\n catch: (cause) =>\n new Error({\n cause,\n message: cause instanceof globalThis.Error ? cause.message : String(cause),\n reason: \"transport\",\n }),\n }).pipe(\n Effect.flatMap((resolution) => {\n switch (resolution._tag) {\n case \"answer\":\n case \"nodata\":\n return Effect.succeed(resolution);\n case \"timeout\":\n return Effect.fail(new Error({ message: \"DNS query timed out\", reason: \"timeout\" }));\n case \"failure\":\n return Effect.fail(new Error({ message: resolution.message, reason: \"transport\" }));\n }\n }),\n ),\n ),\n });\n\nexport const toAsync = (resolver: Interface): AsyncInterface => ({\n resolve: (query) =>\n Effect.runPromise(\n resolver.resolve(query).pipe(\n Effect.match({\n onFailure: (failure): AsyncResolution =>\n failure.reason === \"timeout\"\n ? AsyncResolution.timeout()\n : AsyncResolution.failure({ message: failure.message }),\n onSuccess: (resolution) => resolution,\n }),\n ),\n ),\n});\n"],"mappings":"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"}
|