domainkit 0.6.0 → 0.8.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 (32) hide show
  1. package/README.md +20 -18
  2. package/dist/{canonical-json-9x7gHIoS.mjs → canonical-json-CQYKsZw7.mjs} +10 -4
  3. package/dist/canonical-json-CQYKsZw7.mjs.map +1 -0
  4. package/dist/{connect-Db830jad.d.mts → connect-D-X8T9W8.d.mts} +305 -95
  5. package/dist/{connect-ks3cpqBD.mjs → connect-oI8hcMxc.mjs} +4 -4
  6. package/dist/connect-oI8hcMxc.mjs.map +1 -0
  7. package/dist/{connection-DuYDgWir.d.mts → connection-Dp6ZdSo8.d.mts} +2 -2
  8. package/dist/{connection-api-B__0M3PA.d.mts → connection-api-lqG1nBtD.d.mts} +2 -2
  9. package/dist/index.d.mts +703 -34
  10. package/dist/index.mjs +137 -30
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{managed-dns-connections-CaXts84E.mjs → managed-dns-connections-C3A_GBaz.mjs} +2 -2
  13. package/dist/{managed-dns-connections-CaXts84E.mjs.map → managed-dns-connections-C3A_GBaz.mjs.map} +1 -1
  14. package/dist/promise.d.mts +72 -13
  15. package/dist/promise.mjs +13 -8
  16. package/dist/promise.mjs.map +1 -1
  17. package/dist/{resolver-DxJPsq6l.mjs → resolver-BeGz1ukw.mjs} +132 -50
  18. package/dist/resolver-BeGz1ukw.mjs.map +1 -0
  19. package/dist/{resolver-DUAIlm2I.d.mts → resolver-xoSwyXDJ.d.mts} +889 -15
  20. package/dist/server.d.mts +3 -3
  21. package/dist/server.mjs +3 -3
  22. package/dist/testing.d.mts +2 -2
  23. package/dist/testing.mjs +5 -7
  24. package/dist/testing.mjs.map +1 -1
  25. package/dist/{verify-DAtUAEeg.mjs → verify-DvGPb5C9.mjs} +51 -45
  26. package/dist/verify-DvGPb5C9.mjs.map +1 -0
  27. package/dist/{verify-yAy-r9no.d.mts → verify-FpunAcM7.d.mts} +83 -6
  28. package/package.json +4 -2
  29. package/dist/canonical-json-9x7gHIoS.mjs.map +0 -1
  30. package/dist/connect-ks3cpqBD.mjs.map +0 -1
  31. package/dist/resolver-DxJPsq6l.mjs.map +0 -1
  32. package/dist/verify-DAtUAEeg.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { H as Capability, J as Manifest, M as ProviderConnection, N as ProviderTarget, Nt as Error$1, Q as OAuthSubjectResolver, W as ProviderAuthorization, X as OAuthClientConfiguration, Z as OAuthMethod, ct as Service$1, d as Method, et as TokenValidation, g as Envelope, h as Codec, it as AsyncInterface$1, j as DomainAttachment, kt as DomainName, l as InteractiveFlow, mt as DnsRecord, nt as Value, ot as Error, q as IntegrationMethod, s as Error$2, st as Interface$4 } from "./connect-Db830jad.mjs";
2
- import { H as Source, a as Interface$5, c as Service$2, i as Error$3, n as AsyncInterface$2, o as Query, t as Answer } from "./resolver-DUAIlm2I.mjs";
1
+ import { H as Capability, J as Manifest, M as ProviderConnection, N as ProviderTarget, Nt as Error$1, Q as OAuthSubjectResolver, W as ProviderAuthorization, X as OAuthClientConfiguration, Z as OAuthMethod, ct as Service$1, d as Method, et as TokenValidation, g as Envelope, h as Codec, it as AsyncInterface$1, j as DomainAttachment, kt as DomainName, l as InteractiveFlow, mt as DnsRecord, nt as Value, ot as Error, q as IntegrationMethod, s as Error$2, st as Interface$4 } from "./connect-D-X8T9W8.mjs";
2
+ import { H as Source, a as Interface$5, c as Service$2, i as Error$3, n as AsyncInterface$2, o as Query, t as Answer } from "./resolver-xoSwyXDJ.mjs";
3
3
  import { Context, Data, Effect, Layer, Schema } from "effect";
4
4
  import * as oauth from "oauth4webapi";
5
5
  declare namespace diagnostic_d_exports {
@@ -47,7 +47,7 @@ declare const Evidence$1: Schema.Struct<{
47
47
  readonly zone: Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>;
48
48
  }>;
49
49
  interface Evidence$1 extends Schema.Schema.Type<typeof Evidence$1> {}
50
- declare const Selection: Schema.TaggedUnion<{
50
+ declare const SelectionSchema: Schema.TaggedUnion<{
51
51
  readonly manual: Schema.TaggedStruct<"manual", {
52
52
  readonly evidence: Schema.$Array<Schema.Struct<{
53
53
  readonly accountId: Schema.String;
@@ -79,7 +79,74 @@ declare const Selection: Schema.TaggedUnion<{
79
79
  readonly reason: Schema.Literals<readonly ["explicit", "unique-nameserver-match"]>;
80
80
  }>;
81
81
  }>;
82
- type Selection = typeof Selection.Type;
82
+ /** Provider selection schema and constructors for trusted discovery results. */
83
+ declare const Selection: {
84
+ Schema: Schema.TaggedUnion<{
85
+ readonly manual: Schema.TaggedStruct<"manual", {
86
+ readonly evidence: Schema.$Array<Schema.Struct<{
87
+ readonly accountId: Schema.String;
88
+ readonly connectionId: Schema.String;
89
+ readonly decisiveNameserverMatch: Schema.Boolean;
90
+ readonly matchedNameservers: Schema.$Array<Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>>;
91
+ readonly providerId: Schema.String;
92
+ readonly zone: Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>;
93
+ }>>;
94
+ readonly reason: Schema.Literals<readonly ["ambiguous", "unsupported"]>;
95
+ }>;
96
+ readonly selected: Schema.TaggedStruct<"selected", {
97
+ readonly candidate: Schema.Struct<{
98
+ readonly accountId: Schema.String;
99
+ readonly connectionId: Schema.String;
100
+ readonly decisiveNameserverMatch: Schema.Boolean;
101
+ readonly matchedNameservers: Schema.$Array<Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>>;
102
+ readonly providerId: Schema.String;
103
+ readonly zone: Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>;
104
+ }>;
105
+ readonly evidence: Schema.$Array<Schema.Struct<{
106
+ readonly accountId: Schema.String;
107
+ readonly connectionId: Schema.String;
108
+ readonly decisiveNameserverMatch: Schema.Boolean;
109
+ readonly matchedNameservers: Schema.$Array<Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>>;
110
+ readonly providerId: Schema.String;
111
+ readonly zone: Schema.decodeTo<Schema.brand<Schema.String, "DomainName">, Schema.String, never, never>;
112
+ }>>;
113
+ readonly reason: Schema.Literals<readonly ["explicit", "unique-nameserver-match"]>;
114
+ }>;
115
+ }>;
116
+ manual: (input: Parameters<typeof SelectionSchema.cases.manual.make>[0]) => {
117
+ readonly _tag: "manual";
118
+ readonly evidence: readonly {
119
+ readonly accountId: string;
120
+ readonly connectionId: string;
121
+ readonly decisiveNameserverMatch: boolean;
122
+ readonly matchedNameservers: readonly (string & import("effect/Brand").Brand<"DomainName">)[];
123
+ readonly providerId: string;
124
+ readonly zone: string & import("effect/Brand").Brand<"DomainName">;
125
+ }[];
126
+ readonly reason: "ambiguous" | "unsupported";
127
+ };
128
+ selected: (input: Parameters<typeof SelectionSchema.cases.selected.make>[0]) => {
129
+ readonly _tag: "selected";
130
+ readonly candidate: {
131
+ readonly accountId: string;
132
+ readonly connectionId: string;
133
+ readonly decisiveNameserverMatch: boolean;
134
+ readonly matchedNameservers: readonly (string & import("effect/Brand").Brand<"DomainName">)[];
135
+ readonly providerId: string;
136
+ readonly zone: string & import("effect/Brand").Brand<"DomainName">;
137
+ };
138
+ readonly evidence: readonly {
139
+ readonly accountId: string;
140
+ readonly connectionId: string;
141
+ readonly decisiveNameserverMatch: boolean;
142
+ readonly matchedNameservers: readonly (string & import("effect/Brand").Brand<"DomainName">)[];
143
+ readonly providerId: string;
144
+ readonly zone: string & import("effect/Brand").Brand<"DomainName">;
145
+ }[];
146
+ readonly reason: "explicit" | "unique-nameserver-match";
147
+ };
148
+ };
149
+ type Selection = typeof SelectionSchema.Type;
83
150
  declare function select(input: {
84
151
  readonly authoritativeNameservers: ReadonlyArray<string>;
85
152
  readonly connectedZones: ReadonlyArray<ConnectedZone>;
@@ -411,6 +478,17 @@ type AccountContext = {
411
478
  readonly _tag: "team";
412
479
  readonly teamId: string;
413
480
  };
481
+ /** Constructs the account scope used by Vercel API requests. */
482
+ declare const AccountContext: {
483
+ personal: () => Extract<AccountContext, {
484
+ readonly _tag: "personal";
485
+ }>;
486
+ team: ({ teamId }: {
487
+ readonly teamId: string;
488
+ }) => Extract<AccountContext, {
489
+ readonly _tag: "team";
490
+ }>;
491
+ };
414
492
  /** Configuration for an Effect-native Vercel authoritative-DNS client. */
415
493
  interface Options$3 {
416
494
  readonly baseUrl?: string;
@@ -504,7 +582,6 @@ declare const exchangeCode: (options: ExchangeCodeOptions) => Effect.Effect<{
504
582
  accessToken: Value;
505
583
  context: {
506
584
  readonly _tag: "personal";
507
- readonly teamId?: never;
508
585
  } | {
509
586
  readonly _tag: "team";
510
587
  readonly teamId: string;
@@ -1255,4 +1332,4 @@ declare function observe(input: ProviderConfig): Effect.Effect<Result, Error$1,
1255
1332
  declare function observe(input: Config): Effect.Effect<Result, Error$1, Service$1>;
1256
1333
  //#endregion
1257
1334
  export { RestoreInput as $, Options$3 as A, manifest$1 as B, manifest as C, Fetch$1 as D, AccountContext as E, OAuthMethodOptions as F, Interface$2 as G, tokenMethod$1 as H, RefreshCredentialOptions as I, Zone$1 as J, ListZonesInput$1 as K, SubjectResolverOptions as L, index_d_exports$1 as M, CredentialTarget as N, Interface$1 as O, OAuthFlowOptions as P, Resolution as Q, TokenConnectionOptions$1 as R, integrationMethod as S, Account as T, Account$1 as U, oauthMethod as V, Fetch$2 as W, Interface$3 as X, Credential as Y, ListTargetsInput as Z, ExchangeCodeOptions as _, verify_d_exports as a, IntegrationMethodOptions as b, Policy as c, google_doh_d_exports as d, session_d_exports as et, Options$1 as f, index_d_exports as g, doh_d_exports as h, Result as i, Zone as j, ListZonesInput as k, resolver_pool_d_exports as l, Options$2 as m, PublicDns as n, selection_d_exports as nt, DefaultOptions as o, cloudflare_doh_d_exports as p, Options$4 as q, PublicDnsObservation as r, diagnostic_d_exports as rt, Observation as s, ProviderObservation as t, zones_d_exports as tt, Options as u, IntegrationCredential as v, tokenMethod as w, TokenConnectionOptions as x, IntegrationFlowOptions as y, TokenValidatorOptions as z };
1258
- //# sourceMappingURL=verify-yAy-r9no.d.mts.map
1335
+ //# sourceMappingURL=verify-FpunAcM7.d.mts.map
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "domainkit",
3
- "version": "0.6.0",
4
- "description": "Provider-independent DNS provisioning plans and authorization for TypeScript",
3
+ "version": "0.8.0",
4
+ "description": "Build reviewable DNS plans for custom domains in TypeScript",
5
5
  "keywords": [
6
+ "custom-domains",
6
7
  "dns",
7
8
  "domain",
8
9
  "domain-connect",
10
+ "domainkit",
9
11
  "effect",
10
12
  "typescript"
11
13
  ],
@@ -1 +0,0 @@
1
- {"version":3,"file":"canonical-json-9x7gHIoS.mjs","names":["Error","S","Schema","decode","InvalidInputError","S","DomainName.Schema","decode","InvalidInputError","validate","encode","DomainName.parse","InvalidInputError","decode","encode","S","Schema","ProviderContext.Envelope","InvalidInputError","ProviderAuthorization.Schema","Connection.StoredConnection","Connection.DomainAttachment","Error"],"sources":["../src/invalid-input.ts","../src/domain/domain-name.ts","../src/auth/connection.ts","../src/auth/provider-context.ts","../src/auth/authorization.ts","../src/auth/lifecycle-repository.ts","../src/plan/canonical-json.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nexport class Error extends Schema.TaggedError<Error>()(\"InvalidInputError\", {\n message: Schema.String,\n}) {}\n","import { Effect, Schema as S, SchemaIssue, SchemaTransformation } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\nconst labelPattern = /^[a-z0-9_](?:[a-z0-9_-]{0,61}[a-z0-9_])?$/;\n\nconst Type = S.String.check(\n S.makeFilter<string>(\n (value) =>\n value.length <= 253 &&\n value.includes(\".\") &&\n value.split(\".\").every((label) => labelPattern.test(label))\n ? undefined\n : \"Expected a fully qualified DNS name\",\n { identifier: \"DomainName\" },\n ),\n).pipe(S.brand(\"DomainName\"));\n\n/** A lower-case, fully qualified DNS name without a trailing dot. */\nexport type DomainName = typeof Type.Type;\n\n/** Decodes user and wire strings into canonical domain names. */\nexport const Schema = S.String.pipe(\n S.decodeTo(\n Type,\n SchemaTransformation.transformOrFail({\n decode: (input, options) =>\n Effect.try({\n try: () => normalize(input),\n catch: (cause) =>\n new SchemaIssue.InvalidValue(\n { message: cause instanceof Error ? cause.message : String(cause) },\n input,\n options,\n ),\n }),\n encode: (domain) => Effect.succeed(domain),\n }),\n ),\n);\n\nexport const decode = Effect.fn(\"DomainName.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): DomainName {\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\nfunction normalize(input: string): string {\n const labels = input\n .trim()\n .replace(/\\.+$/, \"\")\n .split(\".\")\n .map((label) => {\n if (label.includes(\"_\") || [...label].every((character) => character.charCodeAt(0) <= 127)) {\n return label.toLowerCase();\n }\n const hostname = new URL(`http://${label}.example`).hostname;\n const normalized = hostname.split(\".\")[0];\n if (normalized === undefined) throw new Error(\"Domain label could not be normalized\");\n return normalized.toLowerCase();\n });\n return labels.join(\".\");\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport type { OAuthMethod } from \"./manifest.ts\";\nimport type * as ProviderAuthorization from \"./authorization.ts\";\nimport type { Value as Secret } from \"./secret.ts\";\n\n/** A provider account and authoritative zone selected for one domain attachment. */\nexport const ProviderTargetEvidence = S.Struct({\n /** The account display name observed during discovery, when the provider exposes one. */\n accountName: S.optionalKey(S.String),\n /** Nameserver and provider-state evidence observed during discovery. */\n nameservers: S.Array(DomainName.Schema),\n status: S.String,\n /** Provider-specific authoritative-zone type, such as Cloudflare's `full` or Vercel's `external`. */\n zoneType: S.String,\n});\nexport interface ProviderTargetEvidence extends S.Schema.Type<typeof ProviderTargetEvidence> {}\n\nexport const ProviderTarget = S.Struct({\n accountId: S.String,\n accountKind: S.NullOr(S.Literals([\"account\", \"personal\", \"team\"])),\n evidence: S.optionalKey(ProviderTargetEvidence),\n zoneId: S.String,\n zoneName: DomainName.Schema,\n});\nexport interface ProviderTarget extends S.Schema.Type<typeof ProviderTarget> {}\n\n/** The lifecycle state visible to a host for an organization connection. */\nexport const ConnectionStatus = S.Literals([\"active\", \"expired\", \"revocation-pending\"]);\nexport type ConnectionStatus = typeof ConnectionStatus.Type;\n\n/** An organization-scoped provider connection. */\nexport const ProviderConnection = S.Struct({\n createdAt: S.DateFromString,\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n ownerId: S.String,\n providerId: S.String,\n status: ConnectionStatus,\n});\nexport interface ProviderConnection extends S.Schema.Type<typeof ProviderConnection> {}\n\n/** An exact provider target attached to one organization domain. */\nexport const DomainAttachment = S.Struct({\n connectionId: S.String,\n createdAt: S.DateFromString,\n domain: DomainName.Schema,\n id: S.String,\n target: ProviderTarget,\n});\nexport interface DomainAttachment extends S.Schema.Type<typeof DomainAttachment> {}\n\n/** Internal connection row; the authorization id is intentionally not part of the public shape. */\nexport const StoredConnection = S.Struct({\n authorizationId: S.String,\n createdAt: S.DateFromString,\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n ownerId: S.String,\n providerId: S.String,\n});\nexport interface StoredConnection extends S.Schema.Type<typeof StoredConnection> {}\n\n/** Internal credential material retained by the host's persistence implementation. */\nexport interface StoredCredential {\n readonly accessToken: Secret;\n readonly expiresAt: Date | null;\n readonly refreshToken: Secret | null;\n readonly tokenType: string;\n}\n\n/** The provider context carried through an interactive connection continuation. */\nexport interface OAuthContinuation {\n readonly clientId: string;\n readonly codeVerifier: Secret;\n readonly expiresAt: Date;\n readonly authorizationId?: string;\n readonly method: OAuthMethod;\n readonly ownerId: string;\n readonly redirectUri: string;\n readonly stateHash: string;\n readonly authorizedById: string;\n}\n\nexport class AuthorizationError extends S.TaggedError<AuthorizationError>()(\"AuthorizationError\", {\n category: S.Literal(\"authorization\"),\n message: S.String,\n operation: S.String,\n retry: S.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\nexport const authorizationError = (message: string, operation: string): AuthorizationError =>\n new AuthorizationError({\n category: \"authorization\",\n message,\n operation,\n retry: \"after-user-action\",\n });\n\n/** Decode a public connection snapshot returned by a host. */\nexport const decode = Effect.fn(\"ProviderConnection.decode\")((input: unknown) =>\n S.decodeUnknownEffect(ProviderConnection)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const validate = Effect.fn(\"ProviderConnection.validate\")((input: unknown) =>\n S.decodeUnknownEffect(S.toType(ProviderConnection))(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = S.encodeSync(ProviderConnection);\n\n/** Derive a public connection projection from its private authorization state. */\nexport function project(\n connection: StoredConnection,\n authorization: ProviderAuthorization.ProviderAuthorization,\n credential: StoredCredential,\n now = new Date(),\n): ProviderConnection {\n const status: ConnectionStatus =\n authorization.revocation._tag === \"Pending\"\n ? \"revocation-pending\"\n : credential.refreshToken === null &&\n credential.expiresAt !== null &&\n (Number.isNaN(credential.expiresAt.valueOf()) || credential.expiresAt <= now)\n ? \"expired\"\n : \"active\";\n return {\n createdAt: connection.createdAt,\n id: connection.id,\n method: connection.method,\n ownerId: connection.ownerId,\n providerId: connection.providerId,\n status,\n };\n}\n\n/** Assert that an exact attachment is usable for one DNS operation. */\nexport function assertAttachment(input: {\n readonly attachment: DomainAttachment;\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly capability: ProviderAuthorization.Capability;\n readonly connection: StoredConnection | ProviderConnection;\n readonly credential?: StoredCredential;\n readonly domain: string;\n readonly now?: Date;\n readonly providerId: string;\n}): DomainName.DomainName {\n const credentialStatus =\n \"status\" in input.connection\n ? input.connection.status\n : input.credential === undefined\n ? null\n : project(input.connection, input.authorization, input.credential, input.now).status;\n if (\n input.connection.providerId !== input.providerId ||\n input.authorization.providerId !== input.providerId ||\n input.authorization.revocation._tag !== \"Active\" ||\n input.attachment.connectionId !== input.connection.id ||\n credentialStatus !== \"active\"\n ) {\n throw authorizationError(\n \"Domain attachment is not active for this provider\",\n \"Connection.assertAttachment\",\n );\n }\n if (!input.authorization.requiredCapabilities.includes(input.capability)) {\n throw authorizationError(\n `Provider authorization lacks the ${input.capability} capability`,\n \"Connection.assertAttachment\",\n );\n }\n if (\n !input.authorization.capabilityEvidence.some((item) => item.capability === input.capability)\n ) {\n throw authorizationError(\n `Provider authorization has no evidence for the ${input.capability} capability`,\n \"Connection.assertAttachment\",\n );\n }\n let domain: DomainName.DomainName;\n try {\n domain = DomainName.parse(input.domain);\n } catch (cause) {\n if (cause instanceof InvalidInputError) throw cause;\n throw new InvalidInputError({\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n if (input.attachment.domain !== domain && !domain.endsWith(`.${input.attachment.domain}`)) {\n throw authorizationError(\n \"Domain attachment does not match the requested domain\",\n \"Connection.assertAttachment\",\n );\n }\n return domain;\n}\n","import { Effect, Schema } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\n/** A provider-owned, versioned, non-secret context value persisted by the host. */\nexport const Envelope = Schema.Struct({\n value: Schema.Json,\n version: Schema.String,\n});\nexport interface Envelope extends Schema.Schema.Type<typeof Envelope> {}\n\nexport interface Codec<A> {\n readonly decode: (envelope: Envelope) => Effect.Effect<A, InvalidInputError>;\n readonly encode: (value: A) => Effect.Effect<Envelope, InvalidInputError>;\n readonly version: string;\n}\n\n/** Build an adapter-owned context codec from a schema and stable version identifier. */\nexport function codec<A, I>(version: string, schema: Schema.Codec<A, I>): Codec<A> {\n return {\n decode: Effect.fn(\"ProviderContext.decode\")((envelope) =>\n envelope.version !== version\n ? Effect.fail(\n new InvalidInputError({\n message: `Unsupported provider context version: ${envelope.version}`,\n }),\n )\n : Schema.decodeUnknownEffect(schema)(envelope.value).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n ),\n encode: Effect.fn(\"ProviderContext.encode\")((value) =>\n Schema.encodeEffect(schema)(value).pipe(\n Effect.flatMap((encoded) => Schema.decodeUnknownEffect(Schema.Json)(encoded)),\n Effect.map((encoded) => ({ value: encoded, version })),\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n ),\n version,\n };\n}\n\nexport const decode = Effect.fn(\"ProviderContext.Envelope.decode\")((input: unknown) =>\n Schema.decodeUnknownEffect(Envelope)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = Schema.encodeSync(Envelope);\n","import { Data, Effect, Schema as S } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport * as ProviderContext from \"./provider-context.ts\";\n\nexport const Capability = S.Literals([\"dns:read\", \"dns:write\"]);\nexport type Capability = typeof Capability.Type;\n\nexport type Evidence = Data.TaggedEnum<{\n Declared: {};\n Exercised: { readonly observedAt: Date };\n Introspected: { readonly observedAt: Date };\n}>;\nexport const Evidence = Data.taggedEnum<Evidence>();\n\nexport const EvidenceSchema = S.TaggedUnion({\n Declared: {},\n Exercised: { observedAt: S.DateFromString },\n Introspected: { observedAt: S.DateFromString },\n});\n\nexport const CapabilityEvidence = S.Struct({\n capability: Capability,\n evidence: EvidenceSchema,\n});\nexport interface CapabilityEvidence extends S.Schema.Type<typeof CapabilityEvidence> {}\n\nexport const Revocation = S.TaggedUnion({\n Active: {},\n Pending: { requestedAt: S.DateFromString },\n});\nexport type Revocation = typeof Revocation.Type;\n\n/** A provider credential authorization shared by one or more organization connections. */\nexport const Schema = S.Struct({\n authorizedById: S.String,\n capabilityEvidence: S.Array(CapabilityEvidence),\n createdAt: S.DateFromString,\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n providerContext: ProviderContext.Envelope,\n providerId: S.String,\n requiredCapabilities: S.Array(Capability),\n revocation: Revocation,\n scopes: S.Array(S.String),\n});\nexport interface ProviderAuthorization extends S.Schema.Type<typeof Schema> {}\n\nexport const decode = Effect.fn(\"ProviderAuthorization.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const validate = Effect.fn(\"ProviderAuthorization.validate\")((input: unknown) =>\n S.decodeUnknownEffect(S.toType(Schema))(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = S.encodeSync(Schema);\n\nexport function evidenceFor(\n authorization: ProviderAuthorization,\n capability: Capability,\n): Evidence | undefined {\n return authorization.capabilityEvidence.find((item) => item.capability === capability)?.evidence;\n}\n","import { Context, Effect, Schema } from \"effect\";\n\nimport * as ProviderAuthorization from \"./authorization.ts\";\nimport * as Connection from \"./connection.ts\";\n\n/** Private aggregate owned by the managed-DNS persistence capability. */\nexport interface Aggregate {\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connections: ReadonlyArray<Connection.StoredConnection>;\n readonly attachments: ReadonlyArray<Connection.DomainAttachment>;\n readonly credential: Connection.StoredCredential;\n}\n\n/** Serializable durable state. Credential material is deliberately sealed separately. */\nexport const AggregateSchema = Schema.Struct({\n authorization: ProviderAuthorization.Schema,\n connections: Schema.Array(Connection.StoredConnection),\n attachments: Schema.Array(Connection.DomainAttachment),\n});\n\nexport interface ConnectInput {\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connection: Connection.StoredConnection;\n readonly credential: Connection.StoredCredential;\n /** The authorization id observed before building a reuse update, if any. */\n readonly expectedAuthorizationId?: string;\n /** The owner connection id observed before building a reuse update, if any. */\n readonly expectedConnectionId?: string;\n}\n\nexport interface AttachmentResult {\n readonly attachment: Connection.DomainAttachment;\n readonly connection: Connection.ProviderConnection;\n}\n\nexport interface DetachResult {\n readonly attachment: Connection.DomainAttachment;\n readonly connection: Connection.ProviderConnection;\n readonly remainingAttachments: number;\n}\n\nexport interface DisconnectResult {\n readonly connection: Connection.ProviderConnection;\n readonly remainingConnections: number;\n readonly revokedAuthorization: boolean;\n}\n\nexport class Error extends Schema.TaggedError<Error>()(\"ManagedDnsLifecycleError\", {\n category: Schema.Literal(\"storage\"),\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\n/**\n * Persistence capability for the managed-DNS model.\n *\n * Implementations own the atomic aggregate containing one provider credential authorization,\n * organization connections, and exact domain attachments. Provider authorization is deliberately\n * an implementation detail of the capability; public callers operate on the projections returned\n * by the connection and attachment methods.\n */\nexport interface Interface {\n readonly attach: (input: {\n readonly attachment: Connection.DomainAttachment;\n readonly connectionId: string;\n readonly ownerId: string;\n }) => Effect.Effect<AttachmentResult, Error>;\n readonly connect: (input: ConnectInput) => Effect.Effect<Aggregate, Error>;\n readonly detach: (input: {\n readonly attachmentId: string;\n readonly ownerId: string;\n }) => Effect.Effect<DetachResult, Error>;\n readonly disconnect: <E>(input: {\n readonly connectionId: string;\n readonly ownerId: string;\n readonly revoke: (\n authorization: ProviderAuthorization.ProviderAuthorization,\n ) => Effect.Effect<void, E>;\n }) => Effect.Effect<DisconnectResult, Error | E>;\n readonly findConnection: (\n ownerId: string,\n authorizationId: string,\n ) => Effect.Effect<Connection.StoredConnection | null, Error>;\n readonly get: (authorizationId: string) => Effect.Effect<Aggregate | null, Error>;\n readonly getAttachment: (\n attachmentId: string,\n ) => Effect.Effect<Connection.DomainAttachment | null, Error>;\n readonly getByConnectionId: (connectionId: string) => Effect.Effect<Aggregate | null, Error>;\n readonly listAttachments: (\n connectionId: string,\n ownerId: string,\n ) => Effect.Effect<ReadonlyArray<Connection.DomainAttachment>, Error>;\n readonly promoteEvidence: (\n authorizationId: string,\n evidence: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>,\n ) => Effect.Effect<Aggregate, Error>;\n readonly recover: <E>(input: {\n readonly authorizationId: string;\n readonly revoke: (\n authorization: ProviderAuthorization.ProviderAuthorization,\n ) => Effect.Effect<void, E>;\n }) => Effect.Effect<DisconnectResult, Error | E>;\n readonly rotate: (\n authorizationId: string,\n credential: Connection.StoredCredential,\n ) => Effect.Effect<Aggregate, Error>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\n \"@domainkit/ManagedDnsConnections\",\n) {}\n","import { Crypto, Effect, Layer, PlatformError, Schema } from \"effect\";\n\nexport class CryptoError extends Schema.TaggedError<CryptoError>()(\"CryptoError\", {\n message: Schema.String,\n}) {}\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | ReadonlyArray<Json>\n | { readonly [key: string]: Json };\n\n/** Deterministic JSON serialization for already schema-encoded protocol values. */\nexport function stringify(value: Json): string {\n if (value === null || typeof value !== \"object\") {\n const encoded = JSON.stringify(value);\n if (encoded === undefined) throw new TypeError(\"Value is not representable as JSON\");\n return encoded;\n }\n if (isJsonArray(value)) return `[${value.map(stringify).join(\",\")}]`;\n return `{${Object.entries(value)\n .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([key, entry]) => `${JSON.stringify(key)}:${stringify(entry)}`)\n .join(\",\")}}`;\n}\n\nfunction isJsonArray(value: Json): value is ReadonlyArray<Json> {\n return Array.isArray(value);\n}\n\nexport const sha256Text = Effect.fn(\"Digest.sha256Text\")(function* (value: string) {\n const cryptoService = yield* Crypto.Crypto;\n const digest = yield* cryptoService\n .digest(\"SHA-256\", new TextEncoder().encode(value))\n .pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })));\n return [...digest].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n});\n\nexport const sha256Json = Effect.fn(\"Digest.sha256Json\")((value: Json) =>\n Effect.try({\n try: () => stringify(value),\n catch: (cause) =>\n new CryptoError({ message: cause instanceof Error ? cause.message : String(cause) }),\n }).pipe(Effect.flatMap(sha256Text)),\n);\n\nfunction sha256EncodedProgram<S extends Schema.Constraint>(\n schema: S,\n value: S[\"Type\"],\n): Effect.Effect<string, CryptoError, Crypto.Crypto | S[\"EncodingServices\"]> {\n return Schema.encodeEffect(schema)(value).pipe(\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n Effect.flatMap(Schema.decodeUnknownEffect(Schema.Json)),\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n Effect.flatMap(sha256Json),\n );\n}\n\nexport const sha256Encoded = Effect.fn(\"Digest.sha256Encoded\")(sha256EncodedProgram);\n\n/** Portable Web Crypto implementation for hosts that want a ready-made Layer. */\nexport const webCryptoLayer: Layer.Layer<Crypto.Crypto> = Layer.succeed(\n Crypto.Crypto,\n Crypto.make({\n randomBytes: (size) => crypto.getRandomValues(new Uint8Array(size)),\n digest: (algorithm, data) =>\n Effect.tryPromise({\n try: async () => {\n const bytes = new Uint8Array(data.byteLength);\n bytes.set(data);\n return new Uint8Array(await crypto.subtle.digest(algorithm, bytes.buffer));\n },\n catch: (cause) =>\n PlatformError.systemError({\n _tag: \"Unknown\",\n module: \"WebCrypto\",\n method: \"digest\",\n cause,\n }),\n }),\n }),\n);\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"connect-ks3cpqBD.mjs","names":["Repository.Service","Connection.project"],"sources":["../src/auth/connect.ts"],"sourcesContent":["import { Clock, Crypto, Data, Effect, Schema } from \"effect\";\n\nimport { CryptoError } from \"../plan/canonical-json.ts\";\nimport type { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport type * as DnsProvider from \"../provider/provider.ts\";\nimport * as ProviderAuthorization from \"./authorization.ts\";\nimport * as Connection from \"./connection.ts\";\nimport * as Repository from \"./lifecycle-repository.ts\";\nimport type * as ProviderContext from \"./provider-context.ts\";\nimport type * as Secret from \"./secret.ts\";\n\nexport interface Authentication {\n readonly capabilityEvidence: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>;\n readonly credential: Connection.StoredCredential;\n /** Provider-specific subject identity used only during authentication; targets are selected later. */\n readonly providerAccountId: string;\n readonly providerContext: ProviderContext.Envelope;\n readonly scopes: ReadonlyArray<string>;\n}\n\nexport type AuthenticationFailure = Error | InvalidInputError | DnsProvider.Error;\n\nexport interface InteractiveStart {\n readonly authorizationUrl: URL;\n readonly payload: Secret.Value;\n}\n\nexport interface Continuation extends BaseInput {\n readonly expiresAt: Date;\n readonly id: string;\n readonly method: \"integration\" | \"oauth2\";\n readonly payload: Secret.Value;\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n}\n\nexport interface ContinuationStore {\n readonly consume: (id: string, now: Date) => Effect.Effect<Continuation | null, Error>;\n readonly put: (continuation: Continuation) => Effect.Effect<void, Error>;\n}\n\nexport interface InteractiveFlow {\n readonly complete: (\n payload: Secret.Value,\n callbackUrl: URL,\n ) => Effect.Effect<Authentication, AuthenticationFailure>;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n readonly start: (\n continuationId: string,\n ) => Effect.Effect<InteractiveStart, AuthenticationFailure, Crypto.Crypto>;\n}\n\nexport type Method = Data.TaggedEnum<{\n Interactive: {\n readonly continuations: ContinuationStore;\n readonly flow: InteractiveFlow;\n readonly ttlMs?: number;\n };\n Token: {\n readonly authenticate: (\n token: Secret.Value,\n ) => Effect.Effect<Authentication, AuthenticationFailure>;\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n readonly token: Secret.Value;\n };\n}>;\nexport const Method = Data.taggedEnum<Method>();\n\nexport type StartResult = Data.TaggedEnum<{\n Connected: { readonly connection: Connection.ProviderConnection };\n Redirect: { readonly authorizationUrl: URL; readonly continuationId: string };\n}>;\nexport const StartResult = Data.taggedEnum<StartResult>();\n\nexport class Error extends Schema.TaggedError<Error>()(\"ConnectionError\", {\n category: Schema.Literals([\"authorization\", \"provider\", \"validation\"]),\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\n/** Inputs shared by token and interactive connection flows. */\nexport interface BaseInput {\n readonly authorizedById: string;\n /** Existing authorization may be supplied only after the host completed fresh provider proof. */\n readonly authorizationId?: string;\n readonly ownerId: string;\n}\n\nexport interface CompleteInput {\n readonly callbackUrl: URL;\n readonly continuationId: string;\n readonly continuations: ContinuationStore;\n readonly flow: InteractiveFlow;\n}\n\nexport interface ConnectInput extends BaseInput {\n readonly authentication: Authentication;\n readonly method: \"integration\" | \"oauth2\" | \"token\";\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n}\n\nconst missingCapability = (\n authentication: Authentication,\n requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>,\n): ProviderAuthorization.Capability | undefined =>\n requiredCapabilities.find(\n (capability) =>\n !authentication.capabilityEvidence.some((item) => item.capability === capability),\n );\n\nconst freshId = Effect.fn(\"Connection.freshId\")(function* () {\n const crypto = yield* Crypto.Crypto;\n return yield* crypto.randomUUIDv4.pipe(\n Effect.mapError(\n (cause) =>\n new Error({\n category: \"validation\",\n message: cause.message,\n operation: \"Connection.connect\",\n retry: \"safe\",\n }),\n ),\n );\n});\n\n/** Persist one authenticated provider connection, optionally reusing a proven authorization. */\nexport const connect = Effect.fn(\"Connection.connect\")(function* (input: ConnectInput) {\n const repository = yield* Repository.Service;\n const now = new Date(yield* Clock.currentTimeMillis);\n const missing = missingCapability(input.authentication, input.requiredCapabilities);\n if (missing !== undefined) {\n return yield* new Error({\n category: \"authorization\",\n message: `Provider authorization lacks evidence for ${missing}`,\n operation: \"Connection.connect\",\n retry: \"after-user-action\",\n });\n }\n\n const existing =\n input.authorizationId === undefined ? null : yield* repository.get(input.authorizationId);\n if (input.authorizationId !== undefined && existing === null) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Provider authorization does not exist\",\n operation: \"Connection.connect\",\n retry: \"after-user-action\",\n });\n }\n if (existing?.authorization.revocation._tag === \"Pending\") {\n return yield* new Error({\n category: \"authorization\",\n message: \"Provider authorization is awaiting revocation recovery\",\n operation: \"Connection.connect\",\n retry: \"after-user-action\",\n });\n }\n if (\n existing !== null &&\n (existing.authorization.providerId !== input.providerId ||\n existing.authorization.method !== input.method)\n ) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Provider proof does not match the existing authorization\",\n operation: \"Connection.connect\",\n retry: \"never\",\n });\n }\n\n const authorizationId = existing?.authorization.id ?? (yield* freshId());\n const authorization: ProviderAuthorization.ProviderAuthorization =\n existing === null\n ? {\n authorizedById: input.authorizedById,\n capabilityEvidence: [...input.authentication.capabilityEvidence],\n createdAt: now,\n id: authorizationId,\n method: input.method,\n providerContext: input.authentication.providerContext,\n providerId: input.providerId,\n requiredCapabilities: [...input.requiredCapabilities],\n revocation: { _tag: \"Active\" },\n scopes: [...input.authentication.scopes],\n }\n : {\n ...existing.authorization,\n capabilityEvidence: mergeEvidence(\n existing.authorization.capabilityEvidence,\n input.authentication.capabilityEvidence,\n ),\n method: input.method,\n providerContext: input.authentication.providerContext,\n requiredCapabilities: [...input.requiredCapabilities],\n revocation: { _tag: \"Active\" },\n scopes: [...input.authentication.scopes],\n };\n const existingConnection = yield* repository.findConnection(input.ownerId, authorizationId);\n const connection: Connection.StoredConnection = {\n authorizationId,\n createdAt: existingConnection?.createdAt ?? now,\n id: existingConnection?.id ?? (yield* freshId()),\n method: input.method,\n ownerId: input.ownerId,\n providerId: input.providerId,\n };\n return yield* repository.connect({\n authorization,\n connection,\n credential: input.authentication.credential,\n ...(existing === null ? {} : { expectedAuthorizationId: existing.authorization.id }),\n ...(existingConnection === null ? {} : { expectedConnectionId: existingConnection.id }),\n });\n});\n\nexport const start = Effect.fn(\"Connection.start\")(function* (\n input: BaseInput & { readonly method: Method },\n) {\n if (input.method._tag === \"Interactive\") {\n const crypto = yield* Crypto.Crypto;\n const now = yield* Clock.currentTimeMillis;\n const continuationId = yield* crypto.randomUUIDv4.pipe(\n Effect.mapError(\n (cause) =>\n new Error({\n category: \"validation\",\n message: cause.message,\n operation: \"Connection.start\",\n retry: \"safe\",\n }),\n ),\n );\n const started = yield* input.method.flow.start(continuationId);\n yield* input.method.continuations.put({\n authorizedById: input.authorizedById,\n ...(input.authorizationId === undefined ? {} : { authorizationId: input.authorizationId }),\n expiresAt: new Date(now + (input.method.ttlMs ?? 10 * 60_000)),\n id: continuationId,\n method: input.method.flow.method,\n ownerId: input.ownerId,\n payload: started.payload,\n providerId: input.method.flow.providerId,\n requiredCapabilities: [...input.method.flow.requiredCapabilities],\n });\n return StartResult.Redirect({\n authorizationUrl: started.authorizationUrl,\n continuationId,\n });\n }\n const authentication = yield* input.method.authenticate(input.method.token);\n const aggregate = yield* connect({\n authentication,\n authorizedById: input.authorizedById,\n ...(input.authorizationId === undefined ? {} : { authorizationId: input.authorizationId }),\n method: \"token\",\n ownerId: input.ownerId,\n providerId: input.method.providerId,\n requiredCapabilities: input.method.requiredCapabilities,\n });\n const storedConnection = aggregate.connections.find(({ ownerId }) => ownerId === input.ownerId);\n if (storedConnection === undefined) {\n return yield* new Error({\n category: \"validation\",\n message: \"Connected provider authorization returned no organization connection\",\n operation: \"Connection.start\",\n retry: \"safe\",\n });\n }\n return StartResult.Connected({\n connection: Connection.project(storedConnection, aggregate.authorization, aggregate.credential),\n });\n});\n\nexport const complete = Effect.fn(\"Connection.complete\")(function* (input: CompleteInput) {\n const continuation = yield* input.continuations.consume(\n input.continuationId,\n new Date(yield* Clock.currentTimeMillis),\n );\n if (continuation === null) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Connection continuation is expired, unknown, or already consumed\",\n operation: \"Connection.complete\",\n retry: \"after-user-action\",\n });\n }\n if (\n continuation.providerId !== input.flow.providerId ||\n continuation.method !== input.flow.method\n ) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Connection continuation does not match the provider flow\",\n operation: \"Connection.complete\",\n retry: \"never\",\n });\n }\n const authentication = yield* input.flow.complete(continuation.payload, input.callbackUrl);\n const aggregate = yield* connect({\n authentication,\n authorizedById: continuation.authorizedById,\n ...(continuation.authorizationId === undefined\n ? {}\n : { authorizationId: continuation.authorizationId }),\n method: continuation.method,\n ownerId: continuation.ownerId,\n providerId: continuation.providerId,\n requiredCapabilities: continuation.requiredCapabilities,\n });\n const storedConnection = aggregate.connections.find(\n ({ ownerId }) => ownerId === continuation.ownerId,\n );\n if (storedConnection === undefined) {\n return yield* new Error({\n category: \"validation\",\n message: \"Connected provider authorization returned no organization connection\",\n operation: \"Connection.complete\",\n retry: \"safe\",\n });\n }\n return Connection.project(storedConnection, aggregate.authorization, aggregate.credential);\n});\n\nfunction mergeEvidence(\n current: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>,\n incoming: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>,\n): ReadonlyArray<ProviderAuthorization.CapabilityEvidence> {\n const byCapability = new Map(current.map((item) => [item.capability, item]));\n for (const item of incoming) byCapability.set(item.capability, item);\n return [...byCapability.values()];\n}\n\nexport type Requirements = Repository.Service | Crypto.Crypto;\nexport type Failure = AuthenticationFailure | Repository.Error | CryptoError;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolver-DxJPsq6l.mjs","names":["DomainName.parse","InvalidInputError","Domain.Schema","Service","Zones.candidates","S","DomainName.Schema","Schema","decode","InvalidInputError","Error","Service","layerFromAsync","toAsync","Operation","S","DnsRecord.Schema","DnsRecord.Observed","Schema","DomainName.Schema","Authorization","Receipt","InvalidInputError","UnsignedPlan","S","DnsPlan.Operation","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.Struct({\n _tag: S.Literal(\"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\nexport const Operation = 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});\nexport type Operation = typeof Operation.Type;\n\nexport const Schema = S.Struct({\n digest: S.String,\n operations: S.Array(Operation),\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),\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(DnsPlan.Operation.guards.create);\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 {\n _tag: \"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 {\n _tag: \"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 {\n _tag: \"conflict\",\n existing: sameSet,\n id,\n reason: \"The exclusive record set already contains incompatible data\",\n requirement,\n };\n }\n return { _tag: \"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\nexport const Resolution = Schema.TaggedUnion({\n answer: { answers: Schema.Array(Answer) },\n nodata: {},\n});\nexport type Resolution = typeof Resolution.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\nexport type AsyncResolution =\n | Resolution\n | { readonly _tag: \"timeout\" }\n | { readonly _tag: \"failure\"; readonly message: string };\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 ? { _tag: \"timeout\" }\n : { _tag: \"failure\", message: failure.message },\n onSuccess: (resolution) => resolution,\n }),\n ),\n ),\n});\n"],"mappings":"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"}