domainkit 0.1.0-beta.0 → 0.1.0-beta.1

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 (46) hide show
  1. package/dist/{auth-Df9BuC25.mjs → auth-Vi-hhXbV.mjs} +24 -9
  2. package/dist/auth-Vi-hhXbV.mjs.map +1 -0
  3. package/dist/{client-DvXfJx_E.mjs → client-BnD7QLRF.mjs} +54 -21
  4. package/dist/client-BnD7QLRF.mjs.map +1 -0
  5. package/dist/{cloudflare-C_ixZsJo.mjs → cloudflare-C6ryPlCZ.mjs} +4 -2
  6. package/dist/{cloudflare-C_ixZsJo.mjs.map → cloudflare-C6ryPlCZ.mjs.map} +1 -1
  7. package/dist/{cloudflare-DClWuAm8.d.mts → cloudflare-tdjNS8vE.d.mts} +3 -3
  8. package/dist/cloudflare.d.mts +2 -2
  9. package/dist/cloudflare.mjs +1 -1
  10. package/dist/{dns-record-Dzo4flM5.mjs → dns-record-C_KwGPLf.mjs} +11 -1
  11. package/dist/dns-record-C_KwGPLf.mjs.map +1 -0
  12. package/dist/effect-cloudflare.d.mts +1 -1
  13. package/dist/effect-cloudflare.mjs +1 -1
  14. package/dist/effect-vercel.d.mts +1 -1
  15. package/dist/effect-vercel.mjs +1 -1
  16. package/dist/effect.d.mts +33 -23
  17. package/dist/effect.mjs +7 -7
  18. package/dist/effect.mjs.map +1 -1
  19. package/dist/{index-DQAjUrZu.d.mts → index-CEzk2gbZ.d.mts} +2 -2
  20. package/dist/{index-D1KtyjuI.d.mts → index-CS9Rl5LQ.d.mts} +2 -2
  21. package/dist/index.d.mts +72 -27
  22. package/dist/index.mjs +88 -25
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/{manifest-DjH3BVB9.d.mts → manifest-CP85ePFn.d.mts} +5 -1
  25. package/dist/{receipt-C7PjnibZ.mjs → receipt-CGSnfZQ6.mjs} +2 -2
  26. package/dist/{receipt-C7PjnibZ.mjs.map → receipt-CGSnfZQ6.mjs.map} +1 -1
  27. package/dist/{resolver-BjZwN2JE.d.mts → resolver-BHPsADzE.d.mts} +115 -55
  28. package/dist/{resolver-D5nVrR10.mjs → resolver-tEXpKxmH.mjs} +69 -22
  29. package/dist/resolver-tEXpKxmH.mjs.map +1 -0
  30. package/dist/testing.d.mts +24 -18
  31. package/dist/testing.mjs +72 -24
  32. package/dist/testing.mjs.map +1 -1
  33. package/dist/{vercel-Vc_K_87s.d.mts → vercel-D-E2aqb1.d.mts} +3 -3
  34. package/dist/{vercel-BWz_9Y1v.mjs → vercel-DD89DCqH.mjs} +4 -2
  35. package/dist/{vercel-BWz_9Y1v.mjs.map → vercel-DD89DCqH.mjs.map} +1 -1
  36. package/dist/vercel.d.mts +2 -2
  37. package/dist/vercel.mjs +1 -1
  38. package/dist/{verify-DPB1OfZ5.d.mts → verify-B80xCBh2.d.mts} +457 -29
  39. package/dist/{verify-CeMW6XtK.mjs → verify-Dvc-9Kgp.mjs} +426 -134
  40. package/dist/verify-Dvc-9Kgp.mjs.map +1 -0
  41. package/package.json +4 -2
  42. package/dist/auth-Df9BuC25.mjs.map +0 -1
  43. package/dist/client-DvXfJx_E.mjs.map +0 -1
  44. package/dist/dns-record-Dzo4flM5.mjs.map +0 -1
  45. package/dist/resolver-D5nVrR10.mjs.map +0 -1
  46. package/dist/verify-CeMW6XtK.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-Dvc-9Kgp.mjs","names":["S","DomainName.Schema","Schema","decode","InvalidInputError","validate","encode","AuthorizationError","DomainName.parse","Error","S","ConnectionStore.Service","Connection.validate","ProviderAuthorizationStore.Service","CredentialStore.Service","S","Schema","decode","InvalidInputError","validate","encode","OAuthStateStore.Service","Secret","ProviderAuthorizationStore.Service","ConnectionStore.Service","CredentialStore.Service","Connection.AuthorizationError","ProviderAuthorization.validate","Connection.validate","InvalidInputError","DnsProvider.Error","S","Schema","decode","InvalidInputError","ProviderAuthorizationStore.Service","ConnectionStore.Service","CredentialStore.Service","ProviderAuthorization.validate","CryptoFailure","Connection.validate","DomainName.parse","InvalidInputError","DomainName.Schema","DomainName.parse","Zones.candidates","Connection.AuthorizationError","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","DnsRecord.decode","authorize","validate","apply","makeReceipt","data","DnsRecord.data","DnsRecord.equals","DnsRecord.Observed","authorize","Connection.assertGrant","Connection.AuthorizationError","InvalidInputError","Provisioning.authorize","S","DnsRecord.Schema","DomainName.Schema","Error","DnsProvider.Service","Provisioning.validate","DnsRecord.equals","DomainName.parse","InvalidInputError","make","DnsResolver.Error","layer","DnsResolver.Service","toAsync","DnsResolver.toAsync","DomainName.parse","DomainName.decode","DnsData.parse","DnsOverHttps.make","DnsResolver.Service","DnsResolver.toAsync","DnsRecord.Schema","DnsProvider.Service","DnsResolver.Service","DnsRecord.equals","DnsData.parse","data","DnsRecord.data"],"sources":["../package.json","../src/auth/connection.ts","../src/auth/connection-lifecycle.ts","../src/auth/authorization.ts","../src/plan/canonical-json.ts","../src/auth/oauth.ts","../src/auth/manifest.ts","../src/auth/token.ts","../src/discovery/zones.ts","../src/discovery/selection.ts","../src/plan/types.ts","../src/plan/plan.ts","../src/plan/connection-authorization.ts","../src/plan/deletion.ts","../src/verification/dns-data.ts","../src/verification/doh.ts","../src/verification/cloudflare-doh.ts","../src/verification/verify.ts"],"sourcesContent":["","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 { Value as Secret } from \"./secret.ts\";\nimport type { OAuthMethod } from \"./manifest.ts\";\nimport type * as ProviderAuthorization from \"./authorization.ts\";\n\nexport const Grant = S.TaggedUnion({\n account: {},\n domains: { domains: S.Array(DomainName.Schema) },\n});\nexport type Grant = typeof Grant.Type;\n\n/** An owner-scoped grant bound to one provider authorization. */\nexport const Schema = S.Struct({\n authorizationId: S.String,\n createdAt: S.DateFromString,\n grant: Grant,\n id: S.String,\n ownerId: S.String,\n});\nexport interface Connection extends S.Schema.Type<typeof Schema> {}\n\nexport const decode = Effect.fn(\"Connection.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(\"Connection.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 interface OAuthContinuation {\n readonly clientId: string;\n readonly codeVerifier: Secret;\n readonly expiresAt: Date;\n readonly grant: Grant;\n readonly method: OAuthMethod;\n readonly ownerId: string;\n readonly redirectUri: string;\n readonly stateHash: string;\n readonly subjectId: string;\n}\n\nexport interface StoredCredential {\n readonly accessToken: Secret;\n readonly refreshToken: Secret | null;\n readonly tokenType: string;\n}\n\nexport class AuthorizationError extends S.TaggedError<AuthorizationError>()(\"AuthorizationError\", {\n message: S.String,\n}) {}\n\nexport function assertGrant(\n connection: Connection,\n authorization: ProviderAuthorization.ProviderAuthorization,\n request: {\n readonly capability: ProviderAuthorization.Capability;\n readonly domain: string;\n readonly now?: Date;\n readonly providerId: string;\n },\n): DomainName.DomainName {\n if (\n connection.authorizationId !== authorization.id ||\n authorization.providerId !== request.providerId\n ) {\n throw new AuthorizationError({ message: \"Connection does not grant this provider account\" });\n }\n if (authorization.expiresAt !== null) {\n if (Number.isNaN(authorization.expiresAt.getTime())) {\n throw new AuthorizationError({ message: \"Connection expiration is invalid\" });\n }\n if (authorization.expiresAt <= (request.now ?? new Date())) {\n throw new AuthorizationError({ message: \"Connection has expired\" });\n }\n }\n if (!authorization.capabilities.includes(request.capability)) {\n throw new AuthorizationError({\n message: `Connection lacks the ${request.capability} capability`,\n });\n }\n let domain: DomainName.DomainName;\n try {\n domain = DomainName.parse(request.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 (connection.grant._tag === \"domains\" && !connection.grant.domains.includes(domain)) {\n throw new AuthorizationError({ message: \"Connection does not grant this domain\" });\n }\n return domain;\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport * as ConnectionStore from \"../stores/connection.ts\";\nimport * as CredentialStore from \"../stores/credential.ts\";\nimport * as ProviderAuthorizationStore from \"../stores/authorization.ts\";\nimport type * as Storage from \"../stores/error.ts\";\nimport * as Connection from \"./connection.ts\";\nimport type * as ProviderAuthorization from \"./authorization.ts\";\n\nexport class Error extends S.TaggedError<Error>()(\"ConnectionLifecycleError\", {\n message: S.String,\n}) {}\n\nexport interface DetachResult {\n readonly connection: Connection.Connection;\n readonly remainingBindings: number;\n readonly revokedAuthorization: boolean;\n}\n\n/** Replace the grant on an owner binding after the host has obtained explicit consent. */\nexport const updateGrant = Effect.fn(\"ConnectionLifecycle.updateGrant\")(function* (input: {\n readonly connection: Connection.Connection;\n readonly grant: Connection.Grant;\n}) {\n const connectionStore = yield* ConnectionStore.Service;\n const connection = yield* Connection.validate({ ...input.connection, grant: input.grant });\n yield* connectionStore.put(connection);\n return connection;\n});\n\n/**\n * Detach one owner binding. The final binding invokes provider revocation before deleting local\n * credential and authorization state. The callback keeps provider-specific revocation outside the\n * portable authorization model.\n */\nexport function detach<E, R>(input: {\n readonly connectionId: string;\n readonly revokeAuthorization: (\n authorization: ProviderAuthorization.ProviderAuthorization,\n ) => Effect.Effect<void, E, R>;\n}): Effect.Effect<DetachResult, Error | Storage.Error | E, R | Requirements> {\n return Effect.gen(function* () {\n const authorizationStore = yield* ProviderAuthorizationStore.Service;\n const connectionStore = yield* ConnectionStore.Service;\n const credentialStore = yield* CredentialStore.Service;\n const connection = yield* connectionStore.get(input.connectionId);\n if (connection === null) {\n return yield* new Error({ message: \"Connection binding does not exist\" });\n }\n const bindings = yield* connectionStore.listByAuthorizationId(connection.authorizationId);\n const remainingBindings = bindings.filter(({ id }) => id !== connection.id);\n if (remainingBindings.length > 0) {\n yield* connectionStore.delete(connection.id);\n return {\n connection,\n remainingBindings: remainingBindings.length,\n revokedAuthorization: false,\n };\n }\n\n const authorization = yield* authorizationStore.get(connection.authorizationId);\n if (authorization === null) {\n // A prior attempt may have revoked and removed the authorization before its final binding\n // delete failed. Both local deletes are idempotent, so finish that interrupted cleanup.\n yield* credentialStore.delete(connection.authorizationId);\n yield* connectionStore.delete(connection.id);\n return { connection, remainingBindings: 0, revokedAuthorization: true };\n }\n yield* input.revokeAuthorization(authorization);\n yield* credentialStore.delete(authorization.id);\n yield* authorizationStore.delete(authorization.id);\n yield* connectionStore.delete(connection.id);\n return { connection, remainingBindings: 0, revokedAuthorization: true };\n });\n}\n\nexport type Requirements =\n | ConnectionStore.Service\n | CredentialStore.Service\n | ProviderAuthorizationStore.Service;\n","import { Effect, Schema as S } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\nexport const Capability = S.Literals([\"dns:read\", \"dns:write\"]);\nexport type Capability = typeof Capability.Type;\n\n/** A provider credential authorization shared by one or more owner connections. */\nexport const Schema = S.Struct({\n accountId: S.String,\n capabilities: S.Array(Capability),\n createdAt: S.DateFromString,\n expiresAt: S.NullOr(S.DateFromString),\n id: S.String,\n kind: S.Literals([\"oauth2\", \"token\"]),\n providerId: S.String,\n scopes: S.Array(S.String),\n subjectId: 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","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","import { Clock, Crypto, Effect } from \"effect\";\nimport * as oauth from \"oauth4webapi\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport { CryptoError, sha256Text } from \"../plan/canonical-json.ts\";\nimport * as DnsProvider from \"../provider/provider.ts\";\nimport * as ConnectionStore from \"../stores/connection.ts\";\nimport * as CredentialStore from \"../stores/credential.ts\";\nimport * as ProviderAuthorizationStore from \"../stores/authorization.ts\";\nimport type * as Storage from \"../stores/error.ts\";\nimport * as OAuthStateStore from \"../stores/oauth-state.ts\";\nimport * as Connection from \"./connection.ts\";\nimport * as ProviderAuthorization from \"./authorization.ts\";\nimport type * as ProviderAuth from \"./manifest.ts\";\nimport { Value as Secret } from \"./secret.ts\";\n\nexport type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport interface BeginInput {\n readonly client: ProviderAuth.OAuthClientConfiguration;\n readonly grant: Connection.Grant;\n readonly method: ProviderAuth.OAuthMethod;\n readonly ownerId: string;\n readonly redirectUri: string;\n readonly subjectId: string;\n readonly ttlMs?: number;\n}\n\nexport interface OAuthSubjectResolver {\n (\n tokens: oauth.TokenEndpointResponse,\n accessToken: Secret,\n ): Effect.Effect<\n { readonly accountId: string; readonly expiresAt: Date | null },\n InvalidInputError | DnsProvider.Error\n >;\n}\n\nexport type OAuthError =\n | Connection.AuthorizationError\n | CryptoError\n | InvalidInputError\n | DnsProvider.Error\n | Storage.Error;\n\nfunction beginProgram(\n input: BeginInput,\n): Effect.Effect<\n { readonly authorizationUrl: URL },\n CryptoError | Storage.Error,\n OAuthStateStore.Service | Crypto.Crypto\n> {\n return Effect.gen(function* () {\n const stateStore = yield* OAuthStateStore.Service;\n const cryptoService = yield* Crypto.Crypto;\n const now = yield* Clock.currentTimeMillis;\n const state = base64Url(yield* cryptoBytes(cryptoService, 32));\n const codeVerifier = base64Url(yield* cryptoBytes(cryptoService, 32));\n const challenge = base64Url(\n yield* cryptoService\n .digest(\"SHA-256\", new TextEncoder().encode(codeVerifier))\n .pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message }))),\n );\n const stateHash = yield* sha256Text(state);\n const authorizationUrl = new URL(input.method.authorizationServer.authorization_endpoint);\n authorizationUrl.search = new URLSearchParams({\n client_id: input.client.clientId,\n code_challenge: challenge,\n code_challenge_method: \"S256\",\n redirect_uri: input.redirectUri,\n response_type: \"code\",\n scope: input.method.scopes.join(\" \"),\n state,\n }).toString();\n\n yield* stateStore.put({\n clientId: input.client.clientId,\n codeVerifier: Secret.from(codeVerifier),\n expiresAt: new Date(now + (input.ttlMs ?? 10 * 60_000)),\n grant: input.grant,\n method: input.method,\n ownerId: input.ownerId,\n redirectUri: input.redirectUri,\n stateHash,\n subjectId: input.subjectId,\n });\n return { authorizationUrl };\n });\n}\n\nfunction completeProgram(input: {\n readonly callbackUrl: URL;\n readonly client: ProviderAuth.OAuthClientConfiguration;\n readonly fetch?: Fetch;\n readonly providerId: string;\n readonly resolveSubject: OAuthSubjectResolver;\n}): Effect.Effect<\n {\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connection: Connection.Connection;\n },\n OAuthError,\n | OAuthStateStore.Service\n | ProviderAuthorizationStore.Service\n | ConnectionStore.Service\n | CredentialStore.Service\n | Crypto.Crypto\n> {\n return Effect.gen(function* () {\n const stateStore = yield* OAuthStateStore.Service;\n const authorizationStore = yield* ProviderAuthorizationStore.Service;\n const connectionStore = yield* ConnectionStore.Service;\n const credentialStore = yield* CredentialStore.Service;\n const cryptoService = yield* Crypto.Crypto;\n const state = input.callbackUrl.searchParams.get(\"state\");\n if (state === null) {\n return yield* new Connection.AuthorizationError({\n message: \"OAuth callback is missing state\",\n });\n }\n const now = yield* Clock.currentTimeMillis;\n const continuation = yield* stateStore.consume(yield* sha256Text(state), new Date(now));\n if (continuation === null) {\n return yield* new Connection.AuthorizationError({\n message: \"OAuth continuation is expired, unknown, or already used\",\n });\n }\n if (continuation.clientId !== input.client.clientId) {\n return yield* new Connection.AuthorizationError({\n message: \"OAuth client does not match the continuation\",\n });\n }\n\n const as = continuation.method.authorizationServer as oauth.AuthorizationServer;\n const client: oauth.Client = { client_id: continuation.clientId };\n const authentication = yield* effectClientAuthentication(continuation.method, input.client);\n const tokens = yield* providerRequest(input.providerId, async (signal) => {\n const callbackParameters = oauth.validateAuthResponse(as, client, input.callbackUrl, state);\n const response = await oauth.authorizationCodeGrantRequest(\n as,\n client,\n authentication,\n callbackParameters,\n continuation.redirectUri,\n continuation.codeVerifier.expose(),\n requestOptions(input.fetch, signal),\n );\n return oauth.processAuthorizationCodeResponse(as, client, response);\n });\n const accessToken = Secret.from(tokens.access_token);\n const subject = yield* input.resolveSubject(tokens, accessToken);\n const existingAuthorization = yield* authorizationStore.findByProviderAccount(\n input.providerId,\n subject.accountId,\n );\n const authorizationId =\n existingAuthorization?.id ??\n (yield* cryptoService.randomUUIDv4.pipe(\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n ));\n const authorization = yield* ProviderAuthorization.validate({\n accountId: subject.accountId,\n capabilities: [...continuation.method.capabilities],\n createdAt: existingAuthorization?.createdAt ?? new Date(now),\n expiresAt: subject.expiresAt,\n id: authorizationId,\n kind: \"oauth2\",\n providerId: input.providerId,\n scopes: (tokens.scope ?? continuation.method.scopes.join(\" \")).split(\" \").filter(Boolean),\n subjectId: continuation.subjectId,\n });\n const existingConnection = yield* connectionStore.find(continuation.ownerId, authorization.id);\n const connection = yield* Connection.validate({\n authorizationId: authorization.id,\n createdAt: existingConnection?.createdAt ?? new Date(now),\n grant: continuation.grant,\n id:\n existingConnection?.id ??\n (yield* cryptoService.randomUUIDv4.pipe(\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n )),\n ownerId: continuation.ownerId,\n });\n yield* credentialStore.put(authorization.id, {\n accessToken,\n refreshToken: tokens.refresh_token === undefined ? null : Secret.from(tokens.refresh_token),\n tokenType: tokens.token_type,\n });\n yield* authorizationStore.put(authorization);\n yield* connectionStore.put(connection);\n return { authorization, connection };\n });\n}\n\nfunction refreshProgram(input: {\n readonly client: ProviderAuth.OAuthClientConfiguration;\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly fetch?: Fetch;\n readonly method: ProviderAuth.OAuthMethod;\n}): Effect.Effect<void, OAuthError, CredentialStore.Service> {\n return Effect.gen(function* () {\n const credentialStore = yield* CredentialStore.Service;\n const credential = yield* requireCredential(input.authorization.id, credentialStore);\n const refreshToken = credential.refreshToken;\n if (refreshToken === null) {\n return yield* new Connection.AuthorizationError({\n message: \"Connection has no refresh token\",\n });\n }\n const as = input.method.authorizationServer as oauth.AuthorizationServer;\n const client: oauth.Client = { client_id: input.client.clientId };\n const authentication = yield* effectClientAuthentication(input.method, input.client);\n const tokens = yield* providerRequest(input.authorization.providerId, async (signal) => {\n const response = await oauth.refreshTokenGrantRequest(\n as,\n client,\n authentication,\n refreshToken.expose(),\n requestOptions(input.fetch, signal),\n );\n return oauth.processRefreshTokenResponse(as, client, response);\n });\n yield* credentialStore.put(input.authorization.id, {\n accessToken: Secret.from(tokens.access_token),\n refreshToken:\n tokens.refresh_token === undefined\n ? credential.refreshToken\n : Secret.from(tokens.refresh_token),\n tokenType: tokens.token_type,\n });\n });\n}\n\nfunction revokeProgram(input: {\n readonly client: ProviderAuth.OAuthClientConfiguration;\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly fetch?: Fetch;\n readonly method: ProviderAuth.OAuthMethod;\n}): Effect.Effect<void, OAuthError, CredentialStore.Service> {\n return Effect.gen(function* () {\n if (input.method.authorizationServer.revocation_endpoint === undefined) {\n return yield* new Connection.AuthorizationError({\n message: \"Provider does not advertise token revocation\",\n });\n }\n const credentialStore = yield* CredentialStore.Service;\n const credential = yield* requireCredential(input.authorization.id, credentialStore);\n const as = input.method.authorizationServer as oauth.AuthorizationServer;\n const authentication = yield* effectClientAuthentication(input.method, input.client);\n yield* providerRequest(input.authorization.providerId, async (signal) => {\n const response = await oauth.revocationRequest(\n as,\n { client_id: input.client.clientId },\n authentication,\n credential.accessToken.expose(),\n requestOptions(input.fetch, signal),\n );\n await oauth.processRevocationResponse(response);\n });\n yield* credentialStore.delete(input.authorization.id);\n });\n}\n\nfunction effectClientAuthentication(\n method: ProviderAuth.OAuthMethod,\n client: ProviderAuth.OAuthClientConfiguration,\n): Effect.Effect<oauth.ClientAuth, InvalidInputError> {\n return Effect.try({\n try: () => clientAuthentication(method, client),\n catch: (cause) =>\n cause instanceof InvalidInputError\n ? cause\n : new InvalidInputError({ message: \"OAuth client authentication is invalid\" }),\n });\n}\n\nfunction clientAuthentication(\n method: ProviderAuth.OAuthMethod,\n client: ProviderAuth.OAuthClientConfiguration,\n): oauth.ClientAuth {\n switch (method.clientAuth) {\n case \"none\":\n return oauth.None();\n case \"client_secret_basic\":\n if (client.clientSecret === undefined) {\n throw new InvalidInputError({ message: \"Client secret is required\" });\n }\n return oauth.ClientSecretBasic(client.clientSecret.expose());\n case \"client_secret_post\":\n if (client.clientSecret === undefined) {\n throw new InvalidInputError({ message: \"Client secret is required\" });\n }\n return oauth.ClientSecretPost(client.clientSecret.expose());\n }\n}\n\nfunction requestOptions(\n fetchImplementation: Fetch | undefined,\n signal: AbortSignal,\n): oauth.TokenEndpointRequestOptions {\n return fetchImplementation === undefined\n ? { signal }\n : {\n signal,\n [oauth.customFetch]: (url, options) =>\n fetchImplementation(url, { ...options, body: options.body }),\n };\n}\n\nfunction requireCredential(\n connectionId: string,\n store: CredentialStore.Interface,\n): Effect.Effect<Connection.StoredCredential, Connection.AuthorizationError | Storage.Error> {\n return store.get(connectionId).pipe(\n Effect.flatMap((credential) =>\n credential === null\n ? Effect.fail(\n new Connection.AuthorizationError({\n message: \"Connection credentials are unavailable\",\n }),\n )\n : Effect.succeed(credential),\n ),\n );\n}\n\nfunction providerRequest<A>(providerId: string, request: (signal: AbortSignal) => Promise<A>) {\n return Effect.tryPromise({\n try: request,\n catch: (cause) =>\n cause instanceof Connection.AuthorizationError || cause instanceof InvalidInputError\n ? cause\n : new DnsProvider.Error({\n cause,\n message: safeOAuthMessage(cause),\n operation: \"oauthRequest\",\n providerId,\n }),\n });\n}\n\nfunction cryptoBytes(\n cryptoService: Crypto.Crypto,\n size: number,\n): Effect.Effect<Uint8Array, CryptoError> {\n return cryptoService\n .randomBytes(size)\n .pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })));\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replaceAll(\"+\", \"-\").replaceAll(\"/\", \"_\").replaceAll(\"=\", \"\");\n}\n\nfunction safeOAuthMessage(cause: unknown): string {\n return cause instanceof Error ? cause.name : \"OAuth provider request failed\";\n}\n\nexport const begin = Effect.fn(\"OAuth.begin\")(beginProgram);\nexport const complete = Effect.fn(\"OAuth.complete\")(completeProgram);\nexport const refresh = Effect.fn(\"OAuth.refresh\")(refreshProgram);\nexport const revoke = Effect.fn(\"OAuth.revoke\")(revokeProgram);\n","import { Effect, Schema as S } from \"effect\";\nimport type * as oauth from \"oauth4webapi\";\n\nimport type * as DnsProvider from \"../provider/provider.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport type { Value as Secret } from \"./secret.ts\";\n\nexport const Method = S.TaggedUnion({\n integration: {\n capabilities: S.Array(S.Literals([\"dns:read\", \"dns:write\"])),\n installUrl: S.String,\n tokenEndpoint: S.String,\n },\n oauth2: {\n authorizationServer: S.Struct({\n authorization_endpoint: S.String,\n issuer: S.String,\n revocation_endpoint: S.optionalKey(S.String),\n token_endpoint: S.String,\n }),\n capabilities: S.Array(S.Literals([\"dns:read\", \"dns:write\"])),\n clientAuth: S.Literals([\"none\", \"client_secret_basic\", \"client_secret_post\"]),\n scopes: S.Array(S.String),\n },\n token: {\n capabilities: S.Array(S.Literals([\"dns:read\", \"dns:write\"])),\n instructionsUrl: S.String,\n },\n});\n\nexport const Schema = S.Struct({\n methods: S.Array(Method),\n providerId: S.String,\n});\nexport interface Manifest extends S.Schema.Type<typeof Schema> {}\nexport type OAuthMethod = Extract<Manifest[\"methods\"][number], { readonly _tag: \"oauth2\" }>;\n/** A provider-owned installation flow that returns a credential from a one-time code. */\nexport type IntegrationMethod = Extract<\n Manifest[\"methods\"][number],\n { readonly _tag: \"integration\" }\n>;\n\nexport const decode = Effect.fn(\"ProviderAuth.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport interface OAuthClientConfiguration {\n readonly clientId: string;\n readonly clientSecret?: Secret;\n}\n\nexport interface TokenValidation {\n readonly accountId: string;\n readonly capabilities: ReadonlyArray<\"dns:read\" | \"dns:write\">;\n readonly expiresAt: Date | null;\n readonly scopes: ReadonlyArray<string>;\n}\n\nexport interface OAuthSubjectResolver {\n (\n tokens: oauth.TokenEndpointResponse,\n accessToken: Secret,\n ): Effect.Effect<\n { readonly accountId: string; readonly expiresAt: Date | null },\n DnsProvider.Error\n >;\n}\n\nexport interface AsyncOAuthSubjectResolver {\n (\n tokens: oauth.TokenEndpointResponse,\n accessToken: Secret,\n ): Promise<{ readonly accountId: string; readonly expiresAt: Date | null }>;\n}\n","import { Clock, Crypto, Effect } from \"effect\";\n\nimport { CryptoError, CryptoError as CryptoFailure } from \"../plan/canonical-json.ts\";\nimport type { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport type * as DnsProvider from \"../provider/provider.ts\";\nimport * as ConnectionStore from \"../stores/connection.ts\";\nimport * as CredentialStore from \"../stores/credential.ts\";\nimport * as ProviderAuthorizationStore from \"../stores/authorization.ts\";\nimport type * as Storage from \"../stores/error.ts\";\nimport * as Connection from \"./connection.ts\";\nimport * as ProviderAuthorization from \"./authorization.ts\";\nimport type * as ProviderAuth from \"./manifest.ts\";\nimport { Value as Secret } from \"./secret.ts\";\n\nexport interface Input {\n readonly grant: Connection.Grant;\n readonly ownerId: string;\n readonly providerId: string;\n readonly subjectId: string;\n readonly token: Secret;\n readonly validate: (\n token: Secret,\n ) => Effect.Effect<ProviderAuth.TokenValidation, DnsProvider.Error | InvalidInputError>;\n}\n\nexport const connect = Effect.fn(\"TokenConnection.connect\")(function* (input: Input) {\n const authorizationStore = yield* ProviderAuthorizationStore.Service;\n const connectionStore = yield* ConnectionStore.Service;\n const credentialStore = yield* CredentialStore.Service;\n const cryptoService = yield* Crypto.Crypto;\n const validation = yield* input.validate(input.token);\n const createdAt = new Date(yield* Clock.currentTimeMillis);\n const existingAuthorization = yield* authorizationStore.findByProviderAccount(\n input.providerId,\n validation.accountId,\n );\n const authorization = yield* ProviderAuthorization.validate({\n accountId: validation.accountId,\n capabilities: [...validation.capabilities],\n createdAt: existingAuthorization?.createdAt ?? createdAt,\n expiresAt: validation.expiresAt,\n id:\n existingAuthorization?.id ??\n (yield* cryptoService.randomUUIDv4.pipe(\n Effect.mapError((cause) => new CryptoFailure({ message: cause.message })),\n )),\n kind: \"token\",\n providerId: input.providerId,\n scopes: [...validation.scopes],\n subjectId: input.subjectId,\n });\n const existingConnection = yield* connectionStore.find(input.ownerId, authorization.id);\n const connection = yield* Connection.validate({\n authorizationId: authorization.id,\n createdAt: existingConnection?.createdAt ?? createdAt,\n grant: input.grant,\n id:\n existingConnection?.id ??\n (yield* cryptoService.randomUUIDv4.pipe(\n Effect.mapError((cause) => new CryptoFailure({ message: cause.message })),\n )),\n ownerId: input.ownerId,\n });\n yield* credentialStore.put(authorization.id, {\n accessToken: input.token,\n refreshToken: null,\n tokenType: \"bearer\",\n });\n yield* authorizationStore.put(authorization);\n yield* connectionStore.put(connection);\n return { authorization, connection };\n});\n\nexport type Error = DnsProvider.Error | InvalidInputError | CryptoError | Storage.Error;\n\nexport type Requirements =\n | ProviderAuthorizationStore.Service\n | ConnectionStore.Service\n | CredentialStore.Service\n | Crypto.Crypto;\n","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 { Schema } from \"effect\";\n\nimport * as ProviderAuthorization from \"../auth/authorization.ts\";\nimport * as Connection from \"../auth/connection.ts\";\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport * as Zones from \"./zones.ts\";\n\nexport interface ConnectedZone {\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connection: Connection.Connection;\n readonly nameservers: ReadonlyArray<string>;\n readonly providerId: string;\n readonly zone: string;\n}\n\nexport const Evidence = Schema.Struct({\n accountId: Schema.String,\n connectionId: Schema.String,\n decisiveNameserverMatch: Schema.Boolean,\n matchedNameservers: Schema.Array(DomainName.Schema),\n providerId: Schema.String,\n zone: DomainName.Schema,\n});\nexport interface Evidence extends Schema.Schema.Type<typeof Evidence> {}\n\nexport const Selection = Schema.TaggedUnion({\n selected: {\n candidate: Evidence,\n evidence: Schema.Array(Evidence),\n reason: Schema.Literals([\"explicit\", \"unique-nameserver-match\"]),\n },\n manual: {\n evidence: Schema.Array(Evidence),\n reason: Schema.Literals([\"ambiguous\", \"unsupported\"]),\n },\n});\nexport type Selection = typeof Selection.Type;\n\nexport function select(input: {\n readonly authoritativeNameservers: ReadonlyArray<string>;\n readonly connectedZones: ReadonlyArray<ConnectedZone>;\n readonly domain: string;\n readonly explicit?: {\n readonly accountId: string;\n readonly providerId: string;\n readonly zone: string;\n };\n readonly now?: Date;\n}): Selection {\n const domain = DomainName.parse(input.domain);\n const zoneCandidates = new Set(Zones.candidates(domain));\n const authoritative = nameserverSet(input.authoritativeNameservers);\n const eligible = input.connectedZones.filter((connected) => {\n if (!zoneCandidates.has(DomainName.parse(connected.zone))) return false;\n try {\n Connection.assertGrant(connected.connection, connected.authorization, {\n capability: \"dns:read\",\n domain,\n ...(input.now === undefined ? {} : { now: input.now }),\n providerId: connected.providerId,\n });\n return true;\n } catch {\n return false;\n }\n });\n const evidence = eligible.map((connected) => evidenceFor(connected, authoritative));\n\n if (input.explicit !== undefined) {\n const explicitZone = DomainName.parse(input.explicit.zone);\n const index = eligible.findIndex(\n (connected) =>\n connected.providerId === input.explicit?.providerId &&\n connected.authorization.accountId === input.explicit.accountId &&\n DomainName.parse(connected.zone) === explicitZone,\n );\n if (index < 0) {\n throw new Connection.AuthorizationError({\n message: \"Explicit provider zone is not connected or granted\",\n });\n }\n const candidate = evidence[index];\n if (candidate === undefined) throw new Error(\"Eligible provider evidence is missing\");\n return { _tag: \"selected\", candidate, evidence, reason: \"explicit\" };\n }\n\n const decisive = evidence.filter(({ decisiveNameserverMatch }) => decisiveNameserverMatch);\n const candidate = decisive[0];\n return decisive.length === 1 && candidate !== undefined\n ? { _tag: \"selected\", candidate, evidence, reason: \"unique-nameserver-match\" }\n : {\n _tag: \"manual\",\n evidence,\n reason: decisive.length > 1 ? \"ambiguous\" : \"unsupported\",\n };\n}\n\nfunction evidenceFor(\n connected: ConnectedZone,\n authoritative: ReadonlyArray<DomainName.DomainName>,\n): Evidence {\n const configured = new Set(nameserverSet(connected.nameservers));\n const matchedNameservers = authoritative.filter((nameserver) => configured.has(nameserver));\n return {\n accountId: connected.authorization.accountId,\n connectionId: connected.connection.id,\n decisiveNameserverMatch:\n authoritative.length > 0 && matchedNameservers.length === authoritative.length,\n matchedNameservers,\n providerId: connected.providerId,\n zone: DomainName.parse(connected.zone),\n };\n}\n\nfunction nameserverSet(nameservers: ReadonlyArray<string>): ReadonlyArray<DomainName.DomainName> {\n return [...new Set(nameservers.map(DomainName.parse))].sort();\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, 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, 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 interface CreateInput {\n readonly requirements: ReadonlyArray<DnsRecord.Encoded | DnsRecord.DnsRecord>;\n readonly zone: string;\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 the provider in the Effect environment. */\nexport const create = Effect.fn(\"Provisioning.create\")(function* (input: CreateInput) {\n const provider = yield* DnsProvider.Service;\n const zone = yield* DomainName.decode(input.zone);\n const requirements = (yield* Effect.forEach(input.requirements, 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* create({\n requirements: plan.operations.map(({ requirement }) => requirement),\n zone: plan.zone,\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 create({\n requirements: [operation.requirement],\n zone: plan.zone,\n }).pipe(\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 { Crypto, Effect } from \"effect\";\n\nimport * as Connection from \"../auth/connection.ts\";\nimport * as ProviderAuthorization from \"../auth/authorization.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport { CryptoError } from \"./canonical-json.ts\";\nimport * as Provisioning from \"./plan.ts\";\nimport type * as DnsPlan from \"./types.ts\";\n\nexport const authorize = Effect.fn(\"ConnectionAuthorization.authorize\")(function* (input: {\n readonly allowPartial?: boolean;\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connection: Connection.Connection;\n readonly domain: string;\n readonly operationIds?: ReadonlyArray<string>;\n readonly plan: DnsPlan.DnsPlan;\n}) {\n const domain = yield* Effect.try({\n try: () =>\n Connection.assertGrant(input.connection, input.authorization, {\n capability: \"dns:write\",\n domain: input.domain,\n providerId: input.plan.providerId,\n }),\n catch: (cause) =>\n cause instanceof Connection.AuthorizationError || cause instanceof InvalidInputError\n ? cause\n : new Connection.AuthorizationError({ message: \"Connection grant is invalid\" }),\n });\n const authorization = yield* Provisioning.authorize(\n input.plan,\n input.operationIds,\n input.allowPartial === undefined ? {} : { allowPartial: input.allowPartial },\n );\n const selected = new Set(authorization.operationIds);\n const outsideGrant = input.plan.operations.filter(\n (operation) =>\n operation._tag === \"create\" &&\n selected.has(operation.id) &&\n operation.requirement.name !== domain &&\n !operation.requirement.name.endsWith(`.${domain}`),\n );\n if (outsideGrant.length > 0) {\n return yield* new Connection.AuthorizationError({\n message: `Plan operations are outside the granted domain ${domain}`,\n });\n }\n return authorization;\n});\n\nexport type Error = Connection.AuthorizationError | InvalidInputError | CryptoError;\nexport type Requirements = Crypto.Crypto;\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 { Effect, Schema, SchemaIssue, SchemaTransformation } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport type * as DnsRecord from \"../domain/dns-record.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\nconst CanonicalAddress = Schema.String.pipe(\n Schema.decodeTo(\n Schema.String,\n SchemaTransformation.transform({\n decode: (value) => value.trim().toLowerCase(),\n encode: (value) => value,\n }),\n ),\n);\n\nconst CanonicalDomain = Schema.String.pipe(\n Schema.decodeTo(\n Schema.String,\n SchemaTransformation.transformOrFail({\n decode: (value, options) =>\n Effect.try({\n try: () => DomainName.parse(value).toString(),\n catch: (cause) =>\n new SchemaIssue.InvalidValue(\n { message: cause instanceof Error ? cause.message : String(cause) },\n value,\n options,\n ),\n }),\n encode: (value) => Effect.succeed(value),\n }),\n ),\n);\n\nconst CanonicalMx = tokenizedDomain(2, 1);\nconst CanonicalSrv = tokenizedDomain(4, 3);\n\nconst CanonicalTxt = Schema.String.pipe(\n Schema.decodeTo(\n Schema.String,\n SchemaTransformation.transform({\n decode: (value) => {\n const trimmed = value.trim();\n const chunks = [...trimmed.matchAll(/\"((?:\\\\.|[^\"])*)\"/g)];\n return chunks.length === 0\n ? trimmed\n : chunks\n .map((match) => (match[1] ?? \"\").replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, \"\\\\\"))\n .join(\"\");\n },\n encode: (value) => value,\n }),\n ),\n);\n\nconst CanonicalCaa = Schema.String.pipe(\n Schema.decodeTo(\n Schema.String,\n SchemaTransformation.transform({\n decode: (value) => value.trim().replace(/\\s+\"([\\s\\S]*)\"$/, \" $1\"),\n encode: (value) => value,\n }),\n ),\n);\n\nexport function parse(type: DnsRecord.Type, input: unknown): string {\n const schema = (() => {\n switch (type) {\n case \"A\":\n case \"AAAA\":\n return CanonicalAddress;\n case \"CNAME\":\n case \"NS\":\n return CanonicalDomain;\n case \"MX\":\n return CanonicalMx;\n case \"SRV\":\n return CanonicalSrv;\n case \"TXT\":\n return CanonicalTxt;\n case \"CAA\":\n return CanonicalCaa;\n }\n })();\n try {\n return Schema.decodeUnknownSync(schema)(input);\n } catch (cause) {\n throw new InvalidInputError({\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n}\n\nfunction tokenizedDomain(length: number, domainIndex: number) {\n return Schema.String.pipe(\n Schema.decodeTo(\n Schema.String,\n SchemaTransformation.transformOrFail({\n decode: (value, options) =>\n Effect.try({\n try: () => {\n const parts = value.trim().split(/\\s+/);\n if (parts.length !== length)\n throw new Error(\"DNS record data has an invalid field count\");\n const domain = parts[domainIndex];\n if (domain === undefined) throw new Error(\"DNS record target is missing\");\n parts[domainIndex] = DomainName.parse(domain);\n return parts.join(\" \");\n },\n catch: (cause) =>\n new SchemaIssue.InvalidValue(\n { message: cause instanceof Error ? cause.message : String(cause) },\n value,\n options,\n ),\n }),\n encode: (value) => Effect.succeed(value),\n }),\n ),\n );\n}\n","import * as DnsPacket from \"@leichtgewicht/dns-packet\";\nimport { Effect, Layer } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport * as DnsRecord from \"../domain/dns-record.ts\";\nimport * as DnsData from \"./dns-data.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\n\nexport type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\nexport interface Options {\n readonly endpoint: string;\n readonly fetch?: Fetch;\n readonly timeoutMs?: number;\n}\n\nexport function make(options: Options): DnsResolver.Interface {\n const fetch = options.fetch ?? globalThis.fetch;\n const timeoutMs = options.timeoutMs ?? 5_000;\n return {\n resolve: Effect.fn(\"DnsOverHttps.resolve\")((query) =>\n Effect.tryPromise({\n try: (effectSignal) =>\n request({ effectSignal, fetch, query, timeoutMs, endpoint: options.endpoint }),\n catch: (cause) =>\n cause instanceof DnsResolver.Error\n ? cause\n : new DnsResolver.Error({\n cause,\n message: cause instanceof Error ? cause.message : \"DNS resolution failed\",\n reason: \"transport\",\n }),\n }).pipe(Effect.flatMap((message) => decodeResolution(query, message))),\n ),\n };\n}\n\nexport const layer = (options: Options): Layer.Layer<DnsResolver.Service> =>\n Layer.succeed(DnsResolver.Service, make(options));\n\nexport const toAsync = (options: Options): DnsResolver.AsyncInterface =>\n DnsResolver.toAsync(make(options));\n\nfunction decodeResolution(\n query: DnsResolver.Query,\n message: Uint8Array,\n): Effect.Effect<DnsResolver.Resolution, DnsResolver.Error> {\n return Effect.try({\n try: () => DnsPacket.decode(message),\n catch: (cause) =>\n new DnsResolver.Error({\n cause,\n message: \"DoH returned an invalid DNS message\",\n reason: \"response\",\n }),\n }).pipe(\n Effect.flatMap((packet) => validatePacket(query, packet)),\n Effect.flatMap(decodePacket),\n );\n}\n\nfunction decodePacket(\n packet: DnsPacket.Packet,\n): Effect.Effect<DnsResolver.Resolution, DnsResolver.Error> {\n if (packet.rcode === \"NXDOMAIN\") {\n return Effect.succeed({ _tag: \"nodata\" });\n }\n if (packet.rcode !== \"NOERROR\") {\n return Effect.fail(\n new DnsResolver.Error({\n message: `DNS resolver returned ${packet.rcode ?? \"an unknown response code\"}`,\n reason: \"response\",\n }),\n );\n }\n if (packet.answers === undefined || packet.answers.length === 0) {\n return Effect.succeed({ _tag: \"nodata\" });\n }\n return Effect.forEach(packet.answers, decodeAnswer, { concurrency: \"unbounded\" }).pipe(\n Effect.map((answers): DnsResolver.Resolution => {\n const supportedAnswers = answers.filter((answer) => answer !== null);\n return supportedAnswers.length === 0\n ? { _tag: \"nodata\" }\n : { _tag: \"answer\", answers: supportedAnswers };\n }),\n );\n}\n\nfunction validatePacket(\n query: DnsResolver.Query,\n packet: DnsPacket.Packet,\n): Effect.Effect<DnsPacket.Packet, DnsResolver.Error> {\n return Effect.try({\n try: () => {\n if (packet.type !== \"response\") throw new Error(\"DoH returned a DNS query\");\n if (packet.id !== 0) throw new Error(\"DoH response used an unexpected message ID\");\n if (packet.flag_tc) throw new Error(\"DoH returned a truncated DNS response\");\n const questions = packet.questions ?? [];\n if (questions.length !== 1) throw new Error(\"DoH returned an unexpected question count\");\n const question = questions[0];\n if (question === undefined) throw new Error(\"DoH response omitted the DNS question\");\n if (\n question.class !== \"IN\" ||\n question.type !== query.type ||\n DomainName.parse(question.name) !== query.name\n ) {\n throw new Error(\"DoH response did not match the DNS question\");\n }\n return packet;\n },\n catch: (cause) =>\n new DnsResolver.Error({\n cause,\n message: cause instanceof Error ? cause.message : \"DoH returned an invalid DNS response\",\n reason: \"response\",\n }),\n });\n}\n\nfunction decodeAnswer(\n answer: DnsPacket.Answer,\n): Effect.Effect<DnsResolver.Answer | null, DnsResolver.Error> {\n return Effect.gen(function* () {\n if (answer.class !== \"IN\") return null;\n const decoded = yield* Effect.try({\n try: () => answerData(answer),\n catch: (cause) =>\n new DnsResolver.Error({\n cause,\n message: \"DoH returned invalid DNS record data\",\n reason: \"response\",\n }),\n });\n if (decoded === undefined) return null;\n const name = yield* DomainName.decode(answer.name);\n const data = yield* Effect.try({\n try: () => DnsData.parse(decoded.type, decoded.data),\n catch: (cause) =>\n new DnsResolver.Error({\n cause,\n message: \"DoH returned invalid DNS record data\",\n reason: \"response\",\n }),\n });\n if (answer.ttl === undefined) {\n return yield* new DnsResolver.Error({\n message: \"DoH response omitted the DNS record TTL\",\n reason: \"response\",\n });\n }\n return { data, name, ttl: answer.ttl, type: decoded.type };\n }).pipe(\n Effect.mapError((cause) =>\n cause instanceof DnsResolver.Error\n ? cause\n : new DnsResolver.Error({ cause, message: cause.message, reason: \"response\" }),\n ),\n );\n}\n\nfunction answerData(\n answer: DnsPacket.Answer,\n): { readonly data: string; readonly type: DnsRecord.Type } | undefined {\n switch (answer.type) {\n case \"A\":\n case \"AAAA\":\n case \"CNAME\":\n case \"NS\":\n return { data: answer.data, type: answer.type };\n case \"CAA\":\n return {\n data: `${answer.data.flags ?? 0} ${answer.data.tag} ${answer.data.value}`,\n type: answer.type,\n };\n case \"MX\":\n return {\n data: `${requiredNumber(answer.data.preference, \"MX preference\")} ${answer.data.exchange}`,\n type: answer.type,\n };\n case \"SRV\":\n return {\n data: [\n requiredNumber(answer.data.priority, \"SRV priority\"),\n requiredNumber(answer.data.weight, \"SRV weight\"),\n requiredNumber(answer.data.port, \"SRV port\"),\n answer.data.target,\n ].join(\" \"),\n type: answer.type,\n };\n case \"TXT\":\n return { data: decodeTxt(answer.data), type: answer.type };\n default:\n return undefined;\n }\n}\n\nfunction decodeTxt(data: DnsPacket.TxtData): string {\n const chunks = Array.isArray(data) ? data : [data];\n const encoded = chunks.map((chunk) =>\n typeof chunk === \"string\" ? new TextEncoder().encode(chunk) : chunk,\n );\n const length = encoded.reduce((total, chunk) => total + chunk.length, 0);\n const joined = new Uint8Array(length);\n let offset = 0;\n for (const chunk of encoded) {\n joined.set(chunk, offset);\n offset += chunk.length;\n }\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(joined);\n}\n\nfunction requiredNumber(value: number | undefined, field: string): number {\n if (value === undefined) throw new Error(`DoH response omitted ${field}`);\n return value;\n}\n\nasync function request(input: {\n readonly effectSignal: AbortSignal;\n readonly endpoint: string;\n readonly fetch: Fetch;\n readonly query: DnsResolver.Query;\n readonly timeoutMs: number;\n}): Promise<Uint8Array> {\n const controller = new AbortController();\n let timedOut = false;\n const abortFromEffect = () => controller.abort(input.effectSignal.reason);\n const abortFromHost = () => controller.abort(input.query.signal?.reason);\n input.effectSignal.addEventListener(\"abort\", abortFromEffect, { once: true });\n input.query.signal?.addEventListener(\"abort\", abortFromHost, { once: true });\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort(new Error(\"DNS resolution timed out\"));\n }, input.timeoutMs);\n try {\n const query = Uint8Array.from(\n DnsPacket.encode({\n flags: DnsPacket.RECURSION_DESIRED,\n id: 0,\n questions: [{ name: input.query.name, type: input.query.type }],\n type: \"query\",\n }),\n );\n const response = await input.fetch(new URL(input.endpoint), {\n body: query,\n headers: {\n accept: \"application/dns-message\",\n \"content-type\": \"application/dns-message\",\n },\n method: \"POST\",\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new DnsResolver.Error({\n message: `DoH returned HTTP ${response.status}`,\n reason: \"transport\",\n });\n }\n const contentType = response.headers\n .get(\"content-type\")\n ?.split(\";\", 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== \"application/dns-message\") {\n throw new DnsResolver.Error({\n message: `DoH returned unsupported content type ${contentType ?? \"<missing>\"}`,\n reason: \"response\",\n });\n }\n return new Uint8Array(await response.arrayBuffer());\n } catch (cause) {\n if (timedOut) {\n throw new DnsResolver.Error({ message: \"DNS query timed out\", reason: \"timeout\" });\n }\n throw cause;\n } finally {\n clearTimeout(timer);\n input.effectSignal.removeEventListener(\"abort\", abortFromEffect);\n input.query.signal?.removeEventListener(\"abort\", abortFromHost);\n }\n}\n","import { Layer } from \"effect\";\n\nimport * as DnsOverHttps from \"./doh.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\n\nconst endpoint = \"https://cloudflare-dns.com/dns-query\";\n\nexport interface Options extends Omit<DnsOverHttps.Options, \"endpoint\"> {\n readonly endpoint?: string;\n}\n\nexport function make(options: Options = {}): DnsResolver.Interface {\n return DnsOverHttps.make({ ...options, endpoint: options.endpoint ?? endpoint });\n}\n\nexport const layer = (options: Options = {}): Layer.Layer<DnsResolver.Service> =>\n Layer.succeed(DnsResolver.Service, make(options));\n\nexport const toAsync = (options: Options = {}): DnsResolver.AsyncInterface =>\n DnsResolver.toAsync(make(options));\n","import { Effect, Schema } from \"effect\";\n\nimport type * as DomainName from \"../domain/domain-name.ts\";\nimport * as DnsRecord from \"../domain/dns-record.ts\";\nimport * as DnsProvider from \"../provider/provider.ts\";\nimport * as DnsData from \"./dns-data.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\n\nexport const ProviderObservation = Schema.TaggedUnion({\n match: {},\n missing: {},\n mismatch: { records: Schema.Array(DnsRecord.Schema) },\n failure: { message: Schema.String },\n});\nexport type ProviderObservation = typeof ProviderObservation.Type;\n\nexport const PublicDnsObservation = Schema.TaggedUnion({\n propagated: {},\n missing: {},\n mismatch: { answers: Schema.Array(Schema.String) },\n timeout: {},\n failure: { message: Schema.String },\n});\nexport type PublicDnsObservation = typeof PublicDnsObservation.Type;\n\nexport const Result = Schema.Struct({\n provider: ProviderObservation,\n publicDns: PublicDnsObservation,\n status: Schema.Literals([\"verified\", \"pending\", \"mismatch\", \"unavailable\"]),\n});\nexport interface Result extends Schema.Schema.Type<typeof Result> {}\n\nexport const record = Effect.fn(\"Verification.record\")(function* (input: {\n readonly record: DnsRecord.DnsRecord;\n readonly zone: DomainName.DomainName;\n}) {\n const provider = yield* DnsProvider.Service;\n const resolver = yield* DnsResolver.Service;\n const [providerObservation, publicDns] = yield* Effect.all(\n [\n observeProvider(provider, input.zone, input.record).pipe(\n Effect.catch((failure) =>\n Effect.succeed<ProviderObservation>({ _tag: \"failure\", message: failure.message }),\n ),\n ),\n resolver.resolve({ name: input.record.name, type: input.record._tag }).pipe(\n Effect.match({\n onFailure: (failure): PublicDnsObservation =>\n failure.reason === \"timeout\"\n ? { _tag: \"timeout\" }\n : { _tag: \"failure\", message: failure.message },\n onSuccess: (resolution) => observePublicDns(input.record, resolution),\n }),\n ),\n ] as const,\n { concurrency: \"unbounded\" },\n );\n const status: Result[\"status\"] =\n providerObservation._tag === \"match\" && publicDns._tag === \"propagated\"\n ? \"verified\"\n : providerObservation._tag === \"failure\" ||\n publicDns._tag === \"failure\" ||\n publicDns._tag === \"timeout\"\n ? \"unavailable\"\n : providerObservation._tag === \"mismatch\" || publicDns._tag === \"mismatch\"\n ? \"mismatch\"\n : \"pending\";\n return { provider: providerObservation, publicDns, status };\n});\n\nfunction observeProvider(\n provider: DnsProvider.Interface,\n zone: DomainName.DomainName,\n requirement: DnsRecord.DnsRecord,\n): Effect.Effect<ProviderObservation, DnsProvider.Error> {\n return provider.listRecords(zone).pipe(\n Effect.map((records): ProviderObservation => {\n if (\n records.some(\n (existing) => existing._tag !== \"Opaque\" && DnsRecord.equals(existing, requirement),\n )\n ) {\n return { _tag: \"match\" };\n }\n const sameSet = records.filter(\n (existing): existing is DnsRecord.DnsRecord =>\n existing._tag !== \"Opaque\" &&\n existing.name === requirement.name &&\n existing._tag === requirement._tag,\n );\n return sameSet.length === 0 ? { _tag: \"missing\" } : { _tag: \"mismatch\", records: sameSet };\n }),\n );\n}\n\nfunction observePublicDns(\n requirement: DnsRecord.DnsRecord,\n resolution: DnsResolver.Resolution,\n): PublicDnsObservation {\n if (resolution._tag === \"nodata\") return { _tag: \"missing\" };\n const expected = DnsData.parse(requirement._tag, recordValue(requirement));\n return resolution.answers.some(\n (answer) =>\n answer.name === requirement.name &&\n answer.type === requirement._tag &&\n DnsData.parse(answer.type, answer.data) === expected,\n )\n ? { _tag: \"propagated\" }\n : { _tag: \"mismatch\", answers: resolution.answers.map(({ data }) => data) };\n}\n\nfunction recordValue(requirement: DnsRecord.DnsRecord): string {\n const data = DnsRecord.data(requirement);\n switch (requirement._tag) {\n case \"A\":\n case \"AAAA\":\n return String(data.address);\n case \"CNAME\":\n case \"NS\":\n return String(data.target);\n case \"TXT\":\n return String(data.value);\n case \"MX\":\n return `${data.priority} ${data.exchange}`;\n case \"CAA\":\n return `${data.flags} ${data.tag} ${data.value}`;\n case \"SRV\":\n return `${data.priority} ${data.weight} ${data.port} ${data.target}`;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;ACQA,MAAa,QAAQA,OAAE,YAAY;CACjC,SAAS,CAAC;CACV,SAAS,EAAE,SAASA,OAAE,MAAMC,QAAiB,EAAE;AACjD,CAAC;;AAID,MAAaC,WAASF,OAAE,OAAO;CAC7B,iBAAiBA,OAAE;CACnB,WAAWA,OAAE;CACb,OAAO;CACP,IAAIA,OAAE;CACN,SAASA,OAAE;AACb,CAAC;AAGD,MAAaG,WAAS,OAAO,GAAG,mBAAmB,CAAC,EAAE,UACpDH,OAAE,oBAAoBE,QAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACnC,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaC,aAAW,OAAO,GAAG,qBAAqB,CAAC,EAAE,UACxDL,OAAE,oBAAoBA,OAAE,OAAOE,QAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAC7C,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaE,WAASN,OAAE,WAAWE,QAAM;AAoBzC,IAAaK,uBAAb,cAAwCP,OAAE,YAAgC,CAAC,CAAC,sBAAsB,EAChG,SAASA,OAAE,OACb,CAAC,CAAC,CAAC,CAAC;AAEJ,SAAgB,YACd,YACA,eACA,SAMuB;CACvB,IACE,WAAW,oBAAoB,cAAc,MAC7C,cAAc,eAAe,QAAQ,YAErC,MAAM,IAAIO,qBAAmB,EAAE,SAAS,kDAAkD,CAAC;CAE7F,IAAI,cAAc,cAAc,MAAM;EACpC,IAAI,OAAO,MAAM,cAAc,UAAU,QAAQ,CAAC,GAChD,MAAM,IAAIA,qBAAmB,EAAE,SAAS,mCAAmC,CAAC;EAE9E,IAAI,cAAc,cAAc,QAAQ,uBAAO,IAAI,KAAK,IACtD,MAAM,IAAIA,qBAAmB,EAAE,SAAS,yBAAyB,CAAC;CAEtE;CACA,IAAI,CAAC,cAAc,aAAa,SAAS,QAAQ,UAAU,GACzD,MAAM,IAAIA,qBAAmB,EAC3B,SAAS,wBAAwB,QAAQ,WAAW,aACtD,CAAC;CAEH,IAAI;CACJ,IAAI;EACF,SAASC,QAAiB,QAAQ,MAAM;CAC1C,SAAS,OAAO;EACd,IAAI,iBAAiBJ,SAAmB,MAAM;EAC9C,MAAM,IAAIA,QAAkB,EAC1B,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAChE,CAAC;CACH;CACA,IAAI,WAAW,MAAM,SAAS,aAAa,CAAC,WAAW,MAAM,QAAQ,SAAS,MAAM,GAClF,MAAM,IAAIG,qBAAmB,EAAE,SAAS,wCAAwC,CAAC;CAEnF,OAAO;AACT;;;;;;;;AC7FA,IAAaE,UAAb,cAA2BC,OAAE,YAAmB,CAAC,CAAC,4BAA4B,EAC5E,SAASA,OAAE,OACb,CAAC,CAAC,CAAC,CAAC;;AASJ,MAAa,cAAc,OAAO,GAAG,iCAAiC,CAAC,CAAC,WAAW,OAGhF;CACD,MAAM,kBAAkB,OAAOC;CAC/B,MAAM,aAAa,OAAOC,WAAoB;EAAE,GAAG,MAAM;EAAY,OAAO,MAAM;CAAM,CAAC;CACzF,OAAO,gBAAgB,IAAI,UAAU;CACrC,OAAO;AACT,CAAC;;;;;;AAOD,SAAgB,OAAa,OAKgD;CAC3E,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,qBAAqB,OAAOC;EAClC,MAAM,kBAAkB,OAAOF;EAC/B,MAAM,kBAAkB,OAAOG;EAC/B,MAAM,aAAa,OAAO,gBAAgB,IAAI,MAAM,YAAY;EAChE,IAAI,eAAe,MACjB,OAAO,OAAO,IAAIL,QAAM,EAAE,SAAS,oCAAoC,CAAC;EAG1E,MAAM,qBAAoB,OADF,gBAAgB,sBAAsB,WAAW,eAAe,EAAA,CACrD,QAAQ,EAAE,SAAS,OAAO,WAAW,EAAE;EAC1E,IAAI,kBAAkB,SAAS,GAAG;GAChC,OAAO,gBAAgB,OAAO,WAAW,EAAE;GAC3C,OAAO;IACL;IACA,mBAAmB,kBAAkB;IACrC,sBAAsB;GACxB;EACF;EAEA,MAAM,gBAAgB,OAAO,mBAAmB,IAAI,WAAW,eAAe;EAC9E,IAAI,kBAAkB,MAAM;GAG1B,OAAO,gBAAgB,OAAO,WAAW,eAAe;GACxD,OAAO,gBAAgB,OAAO,WAAW,EAAE;GAC3C,OAAO;IAAE;IAAY,mBAAmB;IAAG,sBAAsB;GAAK;EACxE;EACA,OAAO,MAAM,oBAAoB,aAAa;EAC9C,OAAO,gBAAgB,OAAO,cAAc,EAAE;EAC9C,OAAO,mBAAmB,OAAO,cAAc,EAAE;EACjD,OAAO,gBAAgB,OAAO,WAAW,EAAE;EAC3C,OAAO;GAAE;GAAY,mBAAmB;GAAG,sBAAsB;EAAK;CACxE,CAAC;AACH;;;;;;;;;;ACtEA,MAAa,aAAaM,OAAE,SAAS,CAAC,YAAY,WAAW,CAAC;;AAI9D,MAAaC,WAASD,OAAE,OAAO;CAC7B,WAAWA,OAAE;CACb,cAAcA,OAAE,MAAM,UAAU;CAChC,WAAWA,OAAE;CACb,WAAWA,OAAE,OAAOA,OAAE,cAAc;CACpC,IAAIA,OAAE;CACN,MAAMA,OAAE,SAAS,CAAC,UAAU,OAAO,CAAC;CACpC,YAAYA,OAAE;CACd,QAAQA,OAAE,MAAMA,OAAE,MAAM;CACxB,WAAWA,OAAE;AACf,CAAC;AAGD,MAAaE,WAAS,OAAO,GAAG,8BAA8B,CAAC,EAAE,UAC/DF,OAAE,oBAAoBC,QAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACnC,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaC,aAAW,OAAO,GAAG,gCAAgC,CAAC,EAAE,UACnEJ,OAAE,oBAAoBA,OAAE,OAAOC,QAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAC7C,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaE,WAASL,OAAE,WAAWC,QAAM;;;;;;;;;;;AC/BzC,IAAa,cAAb,cAAiC,OAAO,YAAyB,CAAC,CAAC,eAAe,EAChF,SAAS,OAAO,OAClB,CAAC,CAAC,CAAC,CAAC;;AAWJ,SAAgB,UAAU,OAAqB;CAC7C,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,MAAM,UAAU,KAAK,UAAU,KAAK;EACpC,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,UAAU,oCAAoC;EACnF,OAAO;CACT;CACA,IAAI,YAAY,KAAK,GAAG,OAAO,IAAI,MAAM,IAAI,SAAS,CAAC,CAAC,KAAK,GAAG,EAAE;CAClE,OAAO,IAAI,OAAO,QAAQ,KAAK,CAAC,CAC7B,MAAM,CAAC,OAAO,CAAC,WAAY,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI,CAAE,CAAC,CACrE,KAAK,CAAC,KAAK,WAAW,GAAG,KAAK,UAAU,GAAG,EAAE,GAAG,UAAU,KAAK,GAAG,CAAC,CACnE,KAAK,GAAG,EAAE;AACf;AAEA,SAAS,YAAY,OAA2C;CAC9D,OAAO,MAAM,QAAQ,KAAK;AAC5B;AAEA,MAAa,aAAa,OAAO,GAAG,mBAAmB,CAAC,CAAC,WAAW,OAAe;CAKjF,OAAO,CAAC,GAAG,QAHW,OADO,OAAO,OAAA,CAEjC,OAAO,WAAW,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAClD,KAAK,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAAC,CAC9D,CAAC,CAAC,KAAK,SAAS,KAAK,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;AAC9E,CAAC;AAED,MAAa,aAAa,OAAO,GAAG,mBAAmB,CAAC,EAAE,UACxD,OAAO,IAAI;CACT,WAAW,UAAU,KAAK;CAC1B,QAAQ,UACN,IAAI,YAAY,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC;AACvF,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,UAAU,CAAC,CACpC;AAEA,SAAS,qBACP,QACA,OAC2E;CAC3E,OAAO,OAAO,aAAa,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACxC,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,GACtE,OAAO,QAAQ,OAAO,oBAAoB,OAAO,IAAI,CAAC,GACtD,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,GACtE,OAAO,QAAQ,UAAU,CAC3B;AACF;AAEA,MAAa,gBAAgB,OAAO,GAAG,sBAAsB,CAAC,CAAC,oBAAoB;;AAGnF,MAAa,iBAA6C,MAAM,QAC9D,OAAO,QACP,OAAO,KAAK;CACV,cAAc,SAAS,OAAO,gBAAgB,IAAI,WAAW,IAAI,CAAC;CAClE,SAAS,WAAW,SAClB,OAAO,WAAW;EAChB,KAAK,YAAY;GACf,MAAM,QAAQ,IAAI,WAAW,KAAK,UAAU;GAC5C,MAAM,IAAI,IAAI;GACd,OAAO,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,MAAM,MAAM,CAAC;EAC3E;EACA,QAAQ,UACN,cAAc,YAAY;GACxB,MAAM;GACN,QAAQ;GACR,QAAQ;GACR;EACF,CAAC;CACL,CAAC;AACL,CAAC,CACH;;;;;;;;;ACtCA,SAAS,aACP,OAKA;CACA,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,aAAa,OAAOK;EAC1B,MAAM,gBAAgB,OAAO,OAAO;EACpC,MAAM,MAAM,OAAO,MAAM;EACzB,MAAM,QAAQ,UAAU,OAAO,YAAY,eAAe,EAAE,CAAC;EAC7D,MAAM,eAAe,UAAU,OAAO,YAAY,eAAe,EAAE,CAAC;EACpE,MAAM,YAAY,UAChB,OAAO,cACJ,OAAO,WAAW,IAAI,YAAY,CAAC,CAAC,OAAO,YAAY,CAAC,CAAC,CACzD,KAAK,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAAC,CACjF;EACA,MAAM,YAAY,OAAO,WAAW,KAAK;EACzC,MAAM,mBAAmB,IAAI,IAAI,MAAM,OAAO,oBAAoB,sBAAsB;EACxF,iBAAiB,SAAS,IAAI,gBAAgB;GAC5C,WAAW,MAAM,OAAO;GACxB,gBAAgB;GAChB,uBAAuB;GACvB,cAAc,MAAM;GACpB,eAAe;GACf,OAAO,MAAM,OAAO,OAAO,KAAK,GAAG;GACnC;EACF,CAAC,CAAC,CAAC,SAAS;EAEZ,OAAO,WAAW,IAAI;GACpB,UAAU,MAAM,OAAO;GACvB,cAAcC,MAAO,KAAK,YAAY;GACtC,WAAW,IAAI,KAAK,OAAO,MAAM,SAAS,IAAY;GACtD,OAAO,MAAM;GACb,QAAQ,MAAM;GACd,SAAS,MAAM;GACf,aAAa,MAAM;GACnB;GACA,WAAW,MAAM;EACnB,CAAC;EACD,OAAO,EAAE,iBAAiB;CAC5B,CAAC;AACH;AAEA,SAAS,gBAAgB,OAiBvB;CACA,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,aAAa,OAAOD;EAC1B,MAAM,qBAAqB,OAAOE;EAClC,MAAM,kBAAkB,OAAOC;EAC/B,MAAM,kBAAkB,OAAOC;EAC/B,MAAM,gBAAgB,OAAO,OAAO;EACpC,MAAM,QAAQ,MAAM,YAAY,aAAa,IAAI,OAAO;EACxD,IAAI,UAAU,MACZ,OAAO,OAAO,IAAIC,qBAA8B,EAC9C,SAAS,kCACX,CAAC;EAEH,MAAM,MAAM,OAAO,MAAM;EACzB,MAAM,eAAe,OAAO,WAAW,QAAQ,OAAO,WAAW,KAAK,GAAG,IAAI,KAAK,GAAG,CAAC;EACtF,IAAI,iBAAiB,MACnB,OAAO,OAAO,IAAIA,qBAA8B,EAC9C,SAAS,0DACX,CAAC;EAEH,IAAI,aAAa,aAAa,MAAM,OAAO,UACzC,OAAO,OAAO,IAAIA,qBAA8B,EAC9C,SAAS,+CACX,CAAC;EAGH,MAAM,KAAK,aAAa,OAAO;EAC/B,MAAM,SAAuB,EAAE,WAAW,aAAa,SAAS;EAChE,MAAM,iBAAiB,OAAO,2BAA2B,aAAa,QAAQ,MAAM,MAAM;EAC1F,MAAM,SAAS,OAAO,gBAAgB,MAAM,YAAY,OAAO,WAAW;GACxE,MAAM,qBAAqB,MAAM,qBAAqB,IAAI,QAAQ,MAAM,aAAa,KAAK;GAC1F,MAAM,WAAW,MAAM,MAAM,8BAC3B,IACA,QACA,gBACA,oBACA,aAAa,aACb,aAAa,aAAa,OAAO,GACjC,eAAe,MAAM,OAAO,MAAM,CACpC;GACA,OAAO,MAAM,iCAAiC,IAAI,QAAQ,QAAQ;EACpE,CAAC;EACD,MAAM,cAAcJ,MAAO,KAAK,OAAO,YAAY;EACnD,MAAM,UAAU,OAAO,MAAM,eAAe,QAAQ,WAAW;EAC/D,MAAM,wBAAwB,OAAO,mBAAmB,sBACtD,MAAM,YACN,QAAQ,SACV;EACA,MAAM,kBACJ,uBAAuB,OACtB,OAAO,cAAc,aAAa,KACjC,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CACxE;EACF,MAAM,gBAAgB,OAAOK,WAA+B;GAC1D,WAAW,QAAQ;GACnB,cAAc,CAAC,GAAG,aAAa,OAAO,YAAY;GAClD,WAAW,uBAAuB,aAAa,IAAI,KAAK,GAAG;GAC3D,WAAW,QAAQ;GACnB,IAAI;GACJ,MAAM;GACN,YAAY,MAAM;GAClB,SAAS,OAAO,SAAS,aAAa,OAAO,OAAO,KAAK,GAAG,EAAA,CAAG,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO;GACxF,WAAW,aAAa;EAC1B,CAAC;EACD,MAAM,qBAAqB,OAAO,gBAAgB,KAAK,aAAa,SAAS,cAAc,EAAE;EAC7F,MAAM,aAAa,OAAOC,WAAoB;GAC5C,iBAAiB,cAAc;GAC/B,WAAW,oBAAoB,aAAa,IAAI,KAAK,GAAG;GACxD,OAAO,aAAa;GACpB,IACE,oBAAoB,OACnB,OAAO,cAAc,aAAa,KACjC,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CACxE;GACF,SAAS,aAAa;EACxB,CAAC;EACD,OAAO,gBAAgB,IAAI,cAAc,IAAI;GAC3C;GACA,cAAc,OAAO,kBAAkB,KAAA,IAAY,OAAON,MAAO,KAAK,OAAO,aAAa;GAC1F,WAAW,OAAO;EACpB,CAAC;EACD,OAAO,mBAAmB,IAAI,aAAa;EAC3C,OAAO,gBAAgB,IAAI,UAAU;EACrC,OAAO;GAAE;GAAe;EAAW;CACrC,CAAC;AACH;AAEA,SAAS,eAAe,OAKqC;CAC3D,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,kBAAkB,OAAOG;EAC/B,MAAM,aAAa,OAAO,kBAAkB,MAAM,cAAc,IAAI,eAAe;EACnF,MAAM,eAAe,WAAW;EAChC,IAAI,iBAAiB,MACnB,OAAO,OAAO,IAAIC,qBAA8B,EAC9C,SAAS,kCACX,CAAC;EAEH,MAAM,KAAK,MAAM,OAAO;EACxB,MAAM,SAAuB,EAAE,WAAW,MAAM,OAAO,SAAS;EAChE,MAAM,iBAAiB,OAAO,2BAA2B,MAAM,QAAQ,MAAM,MAAM;EACnF,MAAM,SAAS,OAAO,gBAAgB,MAAM,cAAc,YAAY,OAAO,WAAW;GACtF,MAAM,WAAW,MAAM,MAAM,yBAC3B,IACA,QACA,gBACA,aAAa,OAAO,GACpB,eAAe,MAAM,OAAO,MAAM,CACpC;GACA,OAAO,MAAM,4BAA4B,IAAI,QAAQ,QAAQ;EAC/D,CAAC;EACD,OAAO,gBAAgB,IAAI,MAAM,cAAc,IAAI;GACjD,aAAaJ,MAAO,KAAK,OAAO,YAAY;GAC5C,cACE,OAAO,kBAAkB,KAAA,IACrB,WAAW,eACXA,MAAO,KAAK,OAAO,aAAa;GACtC,WAAW,OAAO;EACpB,CAAC;CACH,CAAC;AACH;AAEA,SAAS,cAAc,OAKsC;CAC3D,OAAO,OAAO,IAAI,aAAa;EAC7B,IAAI,MAAM,OAAO,oBAAoB,wBAAwB,KAAA,GAC3D,OAAO,OAAO,IAAII,qBAA8B,EAC9C,SAAS,+CACX,CAAC;EAEH,MAAM,kBAAkB,OAAOD;EAC/B,MAAM,aAAa,OAAO,kBAAkB,MAAM,cAAc,IAAI,eAAe;EACnF,MAAM,KAAK,MAAM,OAAO;EACxB,MAAM,iBAAiB,OAAO,2BAA2B,MAAM,QAAQ,MAAM,MAAM;EACnF,OAAO,gBAAgB,MAAM,cAAc,YAAY,OAAO,WAAW;GACvE,MAAM,WAAW,MAAM,MAAM,kBAC3B,IACA,EAAE,WAAW,MAAM,OAAO,SAAS,GACnC,gBACA,WAAW,YAAY,OAAO,GAC9B,eAAe,MAAM,OAAO,MAAM,CACpC;GACA,MAAM,MAAM,0BAA0B,QAAQ;EAChD,CAAC;EACD,OAAO,gBAAgB,OAAO,MAAM,cAAc,EAAE;CACtD,CAAC;AACH;AAEA,SAAS,2BACP,QACA,QACoD;CACpD,OAAO,OAAO,IAAI;EAChB,WAAW,qBAAqB,QAAQ,MAAM;EAC9C,QAAQ,UACN,iBAAiBI,UACb,QACA,IAAIA,QAAkB,EAAE,SAAS,yCAAyC,CAAC;CACnF,CAAC;AACH;AAEA,SAAS,qBACP,QACA,QACkB;CAClB,QAAQ,OAAO,YAAf;EACE,KAAK,QACH,OAAO,MAAM,KAAK;EACpB,KAAK;GACH,IAAI,OAAO,iBAAiB,KAAA,GAC1B,MAAM,IAAIA,QAAkB,EAAE,SAAS,4BAA4B,CAAC;GAEtE,OAAO,MAAM,kBAAkB,OAAO,aAAa,OAAO,CAAC;EAC7D,KAAK;GACH,IAAI,OAAO,iBAAiB,KAAA,GAC1B,MAAM,IAAIA,QAAkB,EAAE,SAAS,4BAA4B,CAAC;GAEtE,OAAO,MAAM,iBAAiB,OAAO,aAAa,OAAO,CAAC;CAC9D;AACF;AAEA,SAAS,eACP,qBACA,QACmC;CACnC,OAAO,wBAAwB,KAAA,IAC3B,EAAE,OAAO,IACT;EACE;GACC,MAAM,eAAe,KAAK,YACzB,oBAAoB,KAAK;GAAE,GAAG;GAAS,MAAM,QAAQ;EAAK,CAAC;CAC/D;AACN;AAEA,SAAS,kBACP,cACA,OAC2F;CAC3F,OAAO,MAAM,IAAI,YAAY,CAAC,CAAC,KAC7B,OAAO,SAAS,eACd,eAAe,OACX,OAAO,KACL,IAAIH,qBAA8B,EAChC,SAAS,yCACX,CAAC,CACH,IACA,OAAO,QAAQ,UAAU,CAC/B,CACF;AACF;AAEA,SAAS,gBAAmB,YAAoB,SAA8C;CAC5F,OAAO,OAAO,WAAW;EACvB,KAAK;EACL,QAAQ,UACN,iBAAiBA,wBAAiC,iBAAiBG,UAC/D,QACA,IAAIC,QAAkB;GACpB;GACA,SAAS,iBAAiB,KAAK;GAC/B,WAAW;GACX;EACF,CAAC;CACT,CAAC;AACH;AAEA,SAAS,YACP,eACA,MACwC;CACxC,OAAO,cACJ,YAAY,IAAI,CAAC,CACjB,KAAK,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAAC;AACjF;AAEA,SAAS,UAAU,OAA2B;CAC5C,IAAI,SAAS;CACb,KAAK,MAAM,QAAQ,OAAO,UAAU,OAAO,aAAa,IAAI;CAC5D,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,WAAW,KAAK,EAAE;AAClF;AAEA,SAAS,iBAAiB,OAAwB;CAChD,OAAO,iBAAiB,QAAQ,MAAM,OAAO;AAC/C;AAEA,MAAa,QAAQ,OAAO,GAAG,aAAa,CAAC,CAAC,YAAY;AAC1D,MAAa,WAAW,OAAO,GAAG,gBAAgB,CAAC,CAAC,eAAe;AACnE,MAAa,UAAU,OAAO,GAAG,eAAe,CAAC,CAAC,cAAc;AAChE,MAAa,SAAS,OAAO,GAAG,cAAc,CAAC,CAAC,aAAa;;;;;;;;ACpW7D,MAAa,SAASC,OAAE,YAAY;CAClC,aAAa;EACX,cAAcA,OAAE,MAAMA,OAAE,SAAS,CAAC,YAAY,WAAW,CAAC,CAAC;EAC3D,YAAYA,OAAE;EACd,eAAeA,OAAE;CACnB;CACA,QAAQ;EACN,qBAAqBA,OAAE,OAAO;GAC5B,wBAAwBA,OAAE;GAC1B,QAAQA,OAAE;GACV,qBAAqBA,OAAE,YAAYA,OAAE,MAAM;GAC3C,gBAAgBA,OAAE;EACpB,CAAC;EACD,cAAcA,OAAE,MAAMA,OAAE,SAAS,CAAC,YAAY,WAAW,CAAC,CAAC;EAC3D,YAAYA,OAAE,SAAS;GAAC;GAAQ;GAAuB;EAAoB,CAAC;EAC5E,QAAQA,OAAE,MAAMA,OAAE,MAAM;CAC1B;CACA,OAAO;EACL,cAAcA,OAAE,MAAMA,OAAE,SAAS,CAAC,YAAY,WAAW,CAAC,CAAC;EAC3D,iBAAiBA,OAAE;CACrB;AACF,CAAC;AAED,MAAaC,WAASD,OAAE,OAAO;CAC7B,SAASA,OAAE,MAAM,MAAM;CACvB,YAAYA,OAAE;AAChB,CAAC;AASD,MAAaE,WAAS,OAAO,GAAG,qBAAqB,CAAC,EAAE,UACtDF,OAAE,oBAAoBC,QAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACnC,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;;;;ACrBA,MAAa,UAAU,OAAO,GAAG,yBAAyB,CAAC,CAAC,WAAW,OAAc;CACnF,MAAM,qBAAqB,OAAOC;CAClC,MAAM,kBAAkB,OAAOC;CAC/B,MAAM,kBAAkB,OAAOC;CAC/B,MAAM,gBAAgB,OAAO,OAAO;CACpC,MAAM,aAAa,OAAO,MAAM,SAAS,MAAM,KAAK;CACpD,MAAM,YAAY,IAAI,KAAK,OAAO,MAAM,iBAAiB;CACzD,MAAM,wBAAwB,OAAO,mBAAmB,sBACtD,MAAM,YACN,WAAW,SACb;CACA,MAAM,gBAAgB,OAAOC,WAA+B;EAC1D,WAAW,WAAW;EACtB,cAAc,CAAC,GAAG,WAAW,YAAY;EACzC,WAAW,uBAAuB,aAAa;EAC/C,WAAW,WAAW;EACtB,IACE,uBAAuB,OACtB,OAAO,cAAc,aAAa,KACjC,OAAO,UAAU,UAAU,IAAIC,YAAc,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC1E;EACF,MAAM;EACN,YAAY,MAAM;EAClB,QAAQ,CAAC,GAAG,WAAW,MAAM;EAC7B,WAAW,MAAM;CACnB,CAAC;CACD,MAAM,qBAAqB,OAAO,gBAAgB,KAAK,MAAM,SAAS,cAAc,EAAE;CACtF,MAAM,aAAa,OAAOC,WAAoB;EAC5C,iBAAiB,cAAc;EAC/B,WAAW,oBAAoB,aAAa;EAC5C,OAAO,MAAM;EACb,IACE,oBAAoB,OACnB,OAAO,cAAc,aAAa,KACjC,OAAO,UAAU,UAAU,IAAID,YAAc,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC1E;EACF,SAAS,MAAM;CACjB,CAAC;CACD,OAAO,gBAAgB,IAAI,cAAc,IAAI;EAC3C,aAAa,MAAM;EACnB,cAAc;EACd,WAAW;CACb,CAAC;CACD,OAAO,mBAAmB,IAAI,aAAa;CAC3C,OAAO,gBAAgB,IAAI,UAAU;CACrC,OAAO;EAAE;EAAe;CAAW;AACrC,CAAC;;;;AClED,SAAgB,WAAW,OAAqD;CAC9E,MAAM,SAASE,QAAiB,KAAK;CACrC,MAAM,cAAc,UAAU,QAAQ,EAAE,qBAAqB,KAAK,CAAC;CACnE,IAAI,gBAAgB,MAClB,MAAM,IAAIC,QAAkB,EAAE,SAAS,8CAA8C,CAAC;CAExF,MAAM,SAAS,OAAO,MAAM,GAAG;CAC/B,MAAM,oBAAoB,YAAY,MAAM,GAAG,CAAC,CAAC;CACjD,MAAM,SAAuC,CAAC;CAC9C,KAAK,IAAI,QAAQ,GAAG,SAAS,OAAO,SAAS,mBAAmB,SAAS,GACvE,OAAO,KAAKD,QAAiB,OAAO,MAAM,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;CAE7D,OAAO;AACT;;;;;;;;ACHA,MAAa,WAAW,OAAO,OAAO;CACpC,WAAW,OAAO;CAClB,cAAc,OAAO;CACrB,yBAAyB,OAAO;CAChC,oBAAoB,OAAO,MAAME,QAAiB;CAClD,YAAY,OAAO;CACnB,MAAMA;AACR,CAAC;AAGD,MAAa,YAAY,OAAO,YAAY;CAC1C,UAAU;EACR,WAAW;EACX,UAAU,OAAO,MAAM,QAAQ;EAC/B,QAAQ,OAAO,SAAS,CAAC,YAAY,yBAAyB,CAAC;CACjE;CACA,QAAQ;EACN,UAAU,OAAO,MAAM,QAAQ;EAC/B,QAAQ,OAAO,SAAS,CAAC,aAAa,aAAa,CAAC;CACtD;AACF,CAAC;AAGD,SAAgB,OAAO,OAUT;CACZ,MAAM,SAASC,QAAiB,MAAM,MAAM;CAC5C,MAAM,iBAAiB,IAAI,IAAIC,WAAiB,MAAM,CAAC;CACvD,MAAM,gBAAgB,cAAc,MAAM,wBAAwB;CAClE,MAAM,WAAW,MAAM,eAAe,QAAQ,cAAc;EAC1D,IAAI,CAAC,eAAe,IAAID,QAAiB,UAAU,IAAI,CAAC,GAAG,OAAO;EAClE,IAAI;GACF,YAAuB,UAAU,YAAY,UAAU,eAAe;IACpE,YAAY;IACZ;IACA,GAAI,MAAM,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK,MAAM,IAAI;IACpD,YAAY,UAAU;GACxB,CAAC;GACD,OAAO;EACT,QAAQ;GACN,OAAO;EACT;CACF,CAAC;CACD,MAAM,WAAW,SAAS,KAAK,cAAc,YAAY,WAAW,aAAa,CAAC;CAElF,IAAI,MAAM,aAAa,KAAA,GAAW;EAChC,MAAM,eAAeA,QAAiB,MAAM,SAAS,IAAI;EACzD,MAAM,QAAQ,SAAS,WACpB,cACC,UAAU,eAAe,MAAM,UAAU,cACzC,UAAU,cAAc,cAAc,MAAM,SAAS,aACrDA,QAAiB,UAAU,IAAI,MAAM,YACzC;EACA,IAAI,QAAQ,GACV,MAAM,IAAIE,qBAA8B,EACtC,SAAS,qDACX,CAAC;EAEH,MAAM,YAAY,SAAS;EAC3B,IAAI,cAAc,KAAA,GAAW,MAAM,IAAI,MAAM,uCAAuC;EACpF,OAAO;GAAE,MAAM;GAAY;GAAW;GAAU,QAAQ;EAAW;CACrE;CAEA,MAAM,WAAW,SAAS,QAAQ,EAAE,8BAA8B,uBAAuB;CACzF,MAAM,YAAY,SAAS;CAC3B,OAAO,SAAS,WAAW,KAAK,cAAc,KAAA,IAC1C;EAAE,MAAM;EAAY;EAAW;EAAU,QAAQ;CAA0B,IAC3E;EACE,MAAM;EACN;EACA,QAAQ,SAAS,SAAS,IAAI,cAAc;CAC9C;AACN;AAEA,SAAS,YACP,WACA,eACU;CACV,MAAM,aAAa,IAAI,IAAI,cAAc,UAAU,WAAW,CAAC;CAC/D,MAAM,qBAAqB,cAAc,QAAQ,eAAe,WAAW,IAAI,UAAU,CAAC;CAC1F,OAAO;EACL,WAAW,UAAU,cAAc;EACnC,cAAc,UAAU,WAAW;EACnC,yBACE,cAAc,SAAS,KAAK,mBAAmB,WAAW,cAAc;EAC1E;EACA,YAAY,UAAU;EACtB,MAAMF,QAAiB,UAAU,IAAI;CACvC;AACF;AAEA,SAAS,cAAc,aAA0E;CAC/F,OAAO,CAAC,GAAG,IAAI,IAAI,YAAY,IAAIA,OAAgB,CAAC,CAAC,CAAC,CAAC,KAAK;AAC9D;;;;;;;;;;;;;AC9GA,MAAaG,cAAYC,OAAE,YAAY;CACrC,QAAQ;EACN,IAAIA,OAAE;EACN,aAAaC;CACf;CACA,MAAM;EACJ,IAAID,OAAE;EACN,aAAaC;EACb,UAAUD,OAAE;CACd;CACA,UAAU;EACR,UAAUA,OAAE,MAAME,QAAkB;EACpC,IAAIF,OAAE;EACN,QAAQA,OAAE;EACV,aAAaC;CACf;AACF,CAAC;AAGD,MAAaE,WAASH,OAAE,OAAO;CAC7B,QAAQA,OAAE;CACV,YAAYA,OAAE,MAAMD,WAAS;CAC7B,YAAYC,OAAE;CACd,SAASA,OAAE,QAAQ,uBAAuB;CAC1C,MAAMI;AACR,CAAC;AAGD,MAAaC,kBAAgBL,OAAE,OAAO;CACpC,cAAcA,OAAE;CAChB,cAAcA,OAAE,MAAMA,OAAE,MAAM;CAC9B,YAAYA,OAAE;CACd,SAASA,OAAE,QAAQ,iCAAiC;AACtD,CAAC;AAGD,MAAaM,YAAUN,OAAE,OAAO;CAC9B,WAAWA,OAAE;CACb,YAAYA,OAAE,MACZA,OAAE,OAAO;EACP,aAAaA,OAAE;EACf,kBAAkBA,OAAE,OAAOA,OAAE,MAAM;CACrC,CAAC,CACH;CACA,YAAYA,OAAE;CACd,YAAYA,OAAE;CACd,QAAQA,OAAE,SAAS,CAAC,YAAY,SAAS,CAAC;CAC1C,SAASA,OAAE,QAAQ,4BAA4B;CAC/C,MAAMI;AACR,CAAC;AAGD,MAAa,SAAS,OAAO,GAAG,gBAAgB,CAAC,EAAE,UACjDJ,OAAE,oBAAoBG,QAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACnC,OAAO,UAAU,UAAU,IAAII,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAa,SAASP,OAAE,WAAWG,QAAM;AACzC,MAAa,gBAAgB,OAAO,GAAG,uBAAuB,CAAC,EAAE,UAC/DH,OAAE,oBAAoBM,SAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KACpC,OAAO,UAAU,UAAU,IAAIC,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AACA,MAAa,gBAAgBP,OAAE,WAAWM,SAAO;;;;;;;;;;;;;;AC7DjD,MAAME,iBAAeC,OAAE,OAAO;CAC5B,YAAYA,OAAE,MAAMC,WAAiB;CACrC,YAAYD,OAAE;CACd,SAASA,OAAE,QAAQ,uBAAuB;CAC1C,MAAME;AACR,CAAC;AAED,MAAM,oBAAoBF,OAAE,OAAO,EAAE,aAAaG,SAAiB,CAAC;AAEpE,IAAa,gBAAb,cAAmCH,OAAE,YAA2B,CAAC,CAAC,qBAAqB,EACrF,cAAcA,OAAE,MAAMA,OAAE,MAAM,EAChC,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAa,qBAAb,cAAwCA,OAAE,YAAgC,CAAC,CAAC,sBAAsB,EAChG,SAASA,OAAE,OACb,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAa,aAAb,cAAgCA,OAAE,YAAwB,CAAC,CAAC,kBAAkB;CAC5E,oBAAoBA,OAAE;CACtB,mBAAmBA,OAAE;AACvB,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAa,oBAAb,cAAuCA,OAAE,YAA+B,CAAC,CAAC,qBAAqB;CAC7F,UAAUA,OAAE,SAAS;EACnB;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,mBAAmBA,OAAE;CACrB,SAASA,OAAE;CACX,SAASI;AACX,CAAC,CAAC,CAAC,CAAC;;AAwBJ,MAAaC,WAAS,OAAO,GAAG,qBAAqB,CAAC,CAAC,WAAW,OAAoB;CACpF,MAAM,WAAW,OAAOC;CACxB,MAAM,OAAO,OAAOC,SAAkB,MAAM,IAAI;CAChD,MAAM,gBAAgB,OAAO,OAAO,QAAQ,MAAM,cAAcC,UAAkB,EAChF,aAAa,YACf,CAAC,EAAA,CAAG,KAAK,cAAc;CACvB,MAAM,WAAW,CAAC,GAAI,OAAO,SAAS,YAAY,IAAI,CAAE,CAAC,CAAC,KAAK,cAAc;CAC7E,MAAM,EAAE,eAAe,OAAO,OAAO,OACnC,qBACsB;EAAE,YAAY,CAAC;EAAG,WAAW;CAAS,KAC3D,OAAO,gBACN,qBAAqB,aAAa,MAAM,SAAS,CAAC,CAAC,KACjD,OAAO,KAAK,eAAe;EACzB,YAAY,CAAC,GAAG,MAAM,YAAY,SAAS;EAC3C,WACE,UAAU,SAAS,WACf,CAAC,GAAG,MAAM,WAAW,UAAU,WAAW,CAAC,CAAC,KAAK,cAAc,IAC/D,MAAM;CACd,EAAE,CACJ,CACJ;CACA,MAAM,WAA+C;EACnD;EACA,YAAY,SAAS;EACrB,SAAS;EACT;CACF;CACA,OAAO;EAAE,GAAG;EAAU,QAAQ,OAAO,cAAcT,gBAAc,QAAQ;CAAE;AAC7E,CAAC;;AAQD,MAAaU,cAAY,OAAO,GAAG,wBAAwB,CAAC,CAAC,WAC3D,MACA,cACA,UAA+C,CAAC,GAChD;CACA,OAAOC,WAAS,IAAI;CACpB,MAAM,YAAY,KAAK,WACpB,QAAQ,cAAc,UAAU,SAAS,QAAQ,CAAC,CAClD,KAAK,EAAE,SAAS,EAAE;CACrB,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,gBAAgB,SAAS,CAAC,CAAC,CAAC,KAAK;CAC9D,MAAM,UAAU,SAAS,QAAQ,OAAO,CAAC,UAAU,SAAS,EAAE,CAAC;CAC/D,IAAI,QAAQ,SAAS,GACnB,OAAO,OAAO,IAAI,mBAAmB,EACnC,SAAS,0BAA0B,QAAQ,KAAK,IAAI,IACtD,CAAC;CAEH,IAAI,CAAC,QAAQ,gBAAgB,SAAS,WAAW,UAAU,QACzD,OAAO,OAAO,IAAI,mBAAmB,EACnC,SAAS,8CACX,CAAC;CAEH,OAAO;EACL,cAAc,QAAQ,gBAAgB;EACtC,cAAc;EACd,YAAY,KAAK;EACjB,SAAS;CACX;AACF,CAAC;;AAGD,MAAaC,UAAQ,OAAO,GAAG,oBAAoB,CAAC,CAAC,WAAW,OAAmB;CACjF,MAAM,EAAE,eAAe,SAAS;CAChC,MAAM,WAAW,OAAOL;CACxB,OAAOI,WAAS,IAAI;CACpB,IAAI,cAAc,eAAe,KAAK,QACpC,OAAO,OAAO,IAAI,mBAAmB,EACnC,SAAS,4CACX,CAAC;CAEH,IAAI,SAAS,OAAO,KAAK,YACvB,OAAO,OAAO,IAAI,mBAAmB,EACnC,SAAS,4CACX,CAAC;CAEH,MAAM,YAAY,KAAK,WAAW,QAAQ,cAAc,UAAU,SAAS,UAAU;CACrF,IAAI,UAAU,SAAS,GACrB,OAAO,OAAO,IAAI,cAAc,EAC9B,cAAc,UAAU,KAAK,EAAE,SAAS,EAAE,EAC5C,CAAC;CAGH,MAAM,UAAU,KAAK,WAAW,OAAA,YAAyB,OAAO,MAAM;CACtE,MAAM,WAAW,IAAI,IAAI,cAAc,YAAY;CACnD,MAAM,UAAU,cAAc,aAAa,QACxC,OAAO,CAAC,QAAQ,MAAM,cAAc,UAAU,OAAO,EAAE,CAC1D;CACA,IAAI,QAAQ,SAAS,GACnB,OAAO,OAAO,IAAI,mBAAmB,EACnC,SAAS,8CAA8C,QAAQ,KAAK,IAAI,IAC1E,CAAC;CAEH,IAAI,CAAC,cAAc,gBAAgB,QAAQ,MAAM,EAAE,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC,GAC3E,OAAO,OAAO,IAAI,mBAAmB,EACnC,SAAS,sDACX,CAAC;CAGH,MAAM,cAAc,OAAOL,SAAO;EAChC,cAAc,KAAK,WAAW,KAAK,EAAE,kBAAkB,WAAW;EAClE,MAAM,KAAK;CACb,CAAC;CACD,IAAI,YAAY,WAAW,KAAK,QAC9B,OAAO,OAAO,IAAI,WAAW;EAC3B,oBAAoB,KAAK;EACzB,mBAAmB,YAAY;CACjC,CAAC;CAGH,MAAM,aAGD,CAAC;CACN,KAAK,MAAM,aAAa,SAAS;EAC/B,IAAI,CAAC,SAAS,IAAI,UAAU,EAAE,GAAG;EACjC,OAAO,OAAO,IAAI,aAAa;GAC7B,OAAO,qBAAqB,MAAM,SAAS;GAC3C,MAAM,SAAS,OAAO,SAAS,aAAa,KAAK,MAAM,UAAU,WAAW;GAC5E,WAAW,KAAK;IACd,aAAa,UAAU;IACvB,kBAAkB,OAAO;GAC3B,CAAC;EACH,CAAC,CAAC,CAAC,KACD,OAAO,OAAO,YACZ,WAAW,WAAW,IAClB,OAAO,KAAK,OAAO,IACnBO,cAAY,OAAO,YAAY,SAAS,CAAC,CAAC,KACxC,OAAO,SAAS,YACd,OAAO,KACL,IAAI,kBAAkB;GACpB,UAAU,QAAQ;GAClB,mBAAmB,UAAU;GAC7B,SAAS,eAAe,OAAO;GAC/B;EACF,CAAC,CACH,CACF,CACF,CACN,GACA,OAAO,YAAY,UAAU;GAC3B,IAAI,CAAC,MAAM,kBAAkB,KAAK,KAAK,WAAW,WAAW,GAC3D,OAAO,OAAO,UAAU,KAAK;GAE/B,OAAOA,cAAY,OAAO,YAAY,SAAS,CAAC,CAAC,KAC/C,OAAO,SAAS,YACd,OAAO,KACL,IAAI,kBAAkB;IACpB,UAAU;IACV,mBAAmB,UAAU;IAC7B,SAAS;IACT;GACF,CAAC,CACH,CACF,CACF;EACF,CAAC,CACH;CACF;CACA,OAAO,OAAOA,cAAY,OAAO,YAAY,UAAU;AACzD,CAAC;AAED,SAAgB,yBAAyB,MAA8C;CACrF,OAAO,KAAK,WAAW,KAAK,cAAc;EACxC,MAAM,SAAS,UAAU;EACzB,MAAMC,SAAO,OAAO,QAAQC,KAAe,MAAM,CAAC,CAAC,CAChD,KAAK,CAAC,KAAK,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,CACxC,KAAK,GAAG;EACX,OAAO,GAAG,UAAU,KAAK,YAAY,EAAE,GAAG,OAAO,KAAK,GAAG,OAAO,KAAK,GAAGD,SAAO,KAAK;CACtF,CAAC;AACH;AAEA,SAASD,cACP,OACA,YAIA,QACqC;CACrC,OAAO,MAAM,kBAAkB,KAC7B,OAAO,KAAK,SAAS;EACnB,WAAW,IAAI,KAAK,GAAG;EACvB;EACA,YAAY,MAAM,KAAK;EACvB,YAAY,MAAM,KAAK;EACvB;EACA,SAAS;EACT,MAAM,MAAM,KAAK;CACnB,EAAE,CACJ;AACF;AAEA,SAAS,qBACP,MACA,WACoF;CACpF,OAAOP,SAAO;EACZ,cAAc,CAAC,UAAU,WAAW;EACpC,MAAM,KAAK;CACb,CAAC,CAAC,CAAC,KACD,OAAO,SAAS,gBAAgB;EAC9B,MAAM,mBAAmB,YAAY,WAAW;EAChD,OAAO,kBAAkB,SAAS,YAAY,iBAAiB,OAAO,UAAU,KAC5E,OAAO,OACP,OAAO,KACL,IAAI,WAAW;GACb,oBAAoB,KAAK;GACzB,mBAAmB,YAAY;EACjC,CAAC,CACH;CACN,CAAC,CACH;AACF;AAEA,SAAS,qBACP,aACA,aAC8D;CAC9D,OAAO,OAAO,IAAI,aAAa;EAC7B,MAAM,WAAW,YAAY,QAAQ,WAAW,OAAO,SAAS,YAAY,IAAI;EAChF,MAAM,UAAU,SAAS,QACtB,WACC,OAAO,SAAS,YAAY,OAAO,SAAS,YAAY,IAC5D;EACA,MAAM,QAAQ,QAAQ,MAAM,WAAWU,OAAiB,QAAQ,WAAW,CAAC;EAC5E,MAAM,KAAK,OAAO,cAAc,mBAAmB,EAAE,YAAY,CAAC;EAClE,IAAI,UAAU,KAAA,GACZ,OAAO;GACL,MAAM;GACN;GACA;GACA,UAAU,MAAM,QAAQ,YAAY;EACtC;EAKF,IAFE,SAAS,SAAS,MACjB,YAAY,SAAS,WAAW,SAAS,MAAM,WAAW,OAAO,SAAS,OAAO,IAElF,OAAO;GACL,MAAM;GACN,UAAU;GACV;GACA,QAAQ;GACR;EACF;EAEF,IACE,QAAQ,SAAS,MAChB,YAAY,WAAW,eAAe,QAAQ,MAAM,EAAE,aAAa,WAAW,WAAW,IAE1F,OAAO;GACL,MAAM;GACN,UAAU;GACV;GACA,QAAQ;GACR;EACF;EAEF,OAAO;GAAE,MAAM;GAAU;GAAI;EAAY;CAC3C,CAAC;AACH;AAEA,SAAgBL,WACd,MACoD;CACpD,MAAM,WAA+C;EACnD,YAAY,KAAK;EACjB,YAAY,KAAK;EACjB,SAAS,KAAK;EACd,MAAM,KAAK;CACb;CACA,OAAO,cAAcX,gBAAc,QAAQ,CAAC,CAAC,KAC3C,OAAO,SAAS,WACd,WAAW,KAAK,SACZ,OAAO,OACP,OAAO,KACL,IAAI,mBAAmB,EACrB,SAAS,0CACX,CAAC,CACH,CACN,CACF;AACF;AAEA,SAAS,eAAe,SAA2C;CACjE,OAAO,QAAQ,SAAS,mBACpB,uDACA,QAAQ;AACd;AAEA,SAAS,eAAe,MAA0B,OAAmC;CACnF,MAAM,SAASC,OAAE,WAAWgB,QAAkB;CAC9C,MAAM,SAAShB,OAAE,kBAAkBA,OAAE,IAAI;CACzC,MAAM,WAAW,UAAU,OAAO,OAAO,IAAI,CAAC,CAAC;CAC/C,MAAM,YAAY,UAAU,OAAO,OAAO,KAAK,CAAC,CAAC;CACjD,OAAO,WAAW,YAAY,KAAK,WAAW,YAAY,IAAI;AAChE;;;;ACtWA,MAAaiB,cAAY,OAAO,GAAG,mCAAmC,CAAC,CAAC,WAAW,OAOhF;CACD,MAAM,SAAS,OAAO,OAAO,IAAI;EAC/B,WACEC,YAAuB,MAAM,YAAY,MAAM,eAAe;GAC5D,YAAY;GACZ,QAAQ,MAAM;GACd,YAAY,MAAM,KAAK;EACzB,CAAC;EACH,QAAQ,UACN,iBAAiBC,wBAAiC,iBAAiBC,UAC/D,QACA,IAAID,qBAA8B,EAAE,SAAS,8BAA8B,CAAC;CACpF,CAAC;CACD,MAAM,gBAAgB,OAAOE,YAC3B,MAAM,MACN,MAAM,cACN,MAAM,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,MAAM,aAAa,CAC7E;CACA,MAAM,WAAW,IAAI,IAAI,cAAc,YAAY;CAQnD,IAPqB,MAAM,KAAK,WAAW,QACxC,cACC,UAAU,SAAS,YACnB,SAAS,IAAI,UAAU,EAAE,KACzB,UAAU,YAAY,SAAS,UAC/B,CAAC,UAAU,YAAY,KAAK,SAAS,IAAI,QAAQ,CAEtC,CAAC,CAAC,SAAS,GACxB,OAAO,OAAO,IAAIF,qBAA8B,EAC9C,SAAS,kDAAkD,SAC7D,CAAC;CAEH,OAAO;AACT,CAAC;;;;;;;;;;;;;;;ACtCD,MAAa,YAAYG,OAAE,OAAO;CAChC,IAAIA,OAAE;CACN,kBAAkBA,OAAE;CACpB,QAAQC;AACV,CAAC;AAGD,MAAM,eAAeD,OAAE,OAAO;CAC5B,WAAWA,OAAE;CACb,WAAWA,OAAE;CACb,YAAYA,OAAE,MAAM,SAAS;CAC7B,YAAYA,OAAE;CACd,kBAAkBA,OAAE;CACpB,SAASA,OAAE,QAAQ,4BAA4B;CAC/C,MAAME;AACR,CAAC;AAED,MAAa,OAAOF,OAAE,OAAO;CAAE,GAAG,aAAa;CAAQ,QAAQA,OAAE;AAAO,CAAC;AAGzE,MAAa,gBAAgBA,OAAE,OAAO;CACpC,cAAcA,OAAE,MAAMA,OAAE,MAAM;CAC9B,YAAYA,OAAE;CACd,SAASA,OAAE,QAAQ,qCAAqC;AAC1D,CAAC;AAGD,MAAa,UAAUA,OAAE,OAAO;CAC9B,WAAWA,OAAE;CACb,YAAYA,OAAE,MAAMA,OAAE,OAAO;EAAE,aAAaA,OAAE;EAAQ,kBAAkBA,OAAE;CAAO,CAAC,CAAC;CACnF,YAAYA,OAAE;CACd,YAAYA,OAAE;CACd,QAAQA,OAAE,SAAS,CAAC,YAAY,SAAS,CAAC;CAC1C,SAASA,OAAE,QAAQ,+BAA+B;CAClD,MAAME;AACR,CAAC;AAGD,IAAaC,UAAb,cAA2BH,OAAE,YAAmB,CAAC,CAAC,uBAAuB;CACvE,SAASA,OAAE;CACX,aAAaA,OAAE,YAAYA,OAAE,MAAM;AACrC,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAa,eAAb,cAAkCA,OAAE,YAA0B,CAAC,CAAC,wBAAwB;CACtF,mBAAmBA,OAAE;CACrB,SAASA,OAAE;CACX,SAAS;AACX,CAAC,CAAC,CAAC,CAAC;;AASJ,MAAa,SAAS,OAAO,GAAG,iBAAiB,CAAC,CAAC,WAAW,OAAoB;CAChF,MAAM,WAAW,OAAOI;CACxB,OAAOC,WAAsB,MAAM,IAAI;CACvC,IACE,MAAM,QAAQ,eAAe,MAAM,KAAK,UACxC,MAAM,QAAQ,eAAe,MAAM,KAAK,cACxC,MAAM,QAAQ,SAAS,MAAM,KAAK,MAElC,OAAO,OAAO,IAAIF,QAAM,EAAE,SAAS,oDAAoD,CAAC;CAE1F,IAAI,SAAS,OAAO,MAAM,KAAK,YAC7B,OAAO,OAAO,IAAIA,QAAM,EAAE,SAAS,6CAA6C,CAAC;CAEnF,MAAM,aAAa,OAAO,OAAO,QAAQ,MAAM,QAAQ,aAAa,YAClE,OAAO,IAAI,aAAa;EACtB,MAAM,SAAS,MAAM,KAAK,WAAW,MAClC,cAAc,UAAU,SAAS,YAAY,UAAU,OAAO,QAAQ,WACzE;EACA,IAAI,WAAW,KAAA,KAAa,OAAO,SAAS,UAC1C,OAAO,OAAO,IAAIA,QAAM;GACtB,SAAS;GACT,aAAa,QAAQ;EACvB,CAAC;EAEH,IAAI,QAAQ,qBAAqB,MAC/B,OAAO,OAAO,IAAIA,QAAM;GACtB,SAAS;GACT,aAAa,QAAQ;EACvB,CAAC;EAEH,OAAO,YACL,UACA,MAAM,KAAK,MACX,QAAQ,kBACR,OAAO,aACP,OAAO,EACT;EACA,OAAO;GACL,IAAI,OAAO;GACX,kBAAkB,QAAQ;GAC1B,QAAQ,OAAO;EACjB;CACF,CAAC,CACH;CACA,MAAM,MAAM,OAAO,MAAM;CACzB,MAAM,WAA+C;EACnD,WAAW,IAAI,KAAK,GAAG;EACvB,WAAW,IAAI,KAAK,OAAO,MAAM,SAAS,IAAY;EACtD;EACA,YAAY,MAAM,KAAK;EACvB,kBAAkB,MAAM,KAAK;EAC7B,SAAS;EACT,MAAM,MAAM,KAAK;CACnB;CACA,OAAO;EAAE,GAAG;EAAU,QAAQ,OAAO,cAAc,cAAc,QAAQ;CAAE;AAC7E,CAAC;;AAGD,MAAa,YAAY,OAAO,GAAG,oBAAoB,CAAC,CAAC,WACvD,MACA,cACA;CACA,OAAO,SAAS,IAAI;CACpB,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,gBAAgB,KAAK,WAAW,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK;CACxF,MAAM,UAAU,SAAS,QACtB,OAAO,CAAC,KAAK,WAAW,MAAM,cAAc,UAAU,OAAO,EAAE,CAClE;CACA,IAAI,QAAQ,SAAS,GACnB,OAAO,OAAO,IAAIA,QAAM,EAAE,SAAS,mCAAmC,QAAQ,KAAK,IAAI,IAAI,CAAC;CAE9F,OAAO;EACL,cAAc;EACd,YAAY,KAAK;EACjB,SAAS;CACX;AACF,CAAC;;AAGD,MAAa,QAAQ,OAAO,GAAG,gBAAgB,CAAC,CAAC,WAAW,OAIzD;CACD,MAAM,WAAW,OAAOC;CACxB,OAAO,SAAS,MAAM,IAAI;CAC1B,IAAI,MAAM,cAAc,eAAe,MAAM,KAAK,QAChD,OAAO,OAAO,IAAID,QAAM,EAAE,SAAS,qDAAqD,CAAC;CAE3F,IAAI,SAAS,OAAO,MAAM,KAAK,YAC7B,OAAO,OAAO,IAAIA,QAAM,EAAE,SAAS,4CAA4C,CAAC;CAElF,MAAM,MAAM,OAAO,MAAM;CACzB,IAAI,MAAM,KAAK,aAAa,IAAI,KAAK,GAAG,GACtC,OAAO,OAAO,IAAIA,QAAM,EAAE,SAAS,4BAA4B,CAAC;CAElE,MAAM,WAAW,MAAM,KAAK,WAAW,QAAQ,EAAE,SAC/C,MAAM,cAAc,aAAa,SAAS,EAAE,CAC9C;CACA,IAAI,SAAS,WAAW,MAAM,cAAc,aAAa,QACvD,OAAO,OAAO,IAAIA,QAAM,EAAE,SAAS,qDAAqD,CAAC;CAE3F,MAAM,oBAAoB,OAAO,qBAAqB,MAAM,MAAM,MAAM,YAAY;CACpF,MAAM,eAAe,IAAI,IAAI,kBAAkB,KAAK,EAAE,kBAAkB,WAAW,CAAC;CACpF,IACE,kBAAkB,MACf,EAAE,kBAAkB,CAAC,MAAM,cAAc,aAAa,SAAS,WAAW,CAC7E,GAEA,OAAO,OAAO,IAAIA,QAAM,EAAE,SAAS,mDAAmD,CAAC;CAEzF,MAAM,YAAY,SAAS,QAAQ,EAAE,SAAS,CAAC,aAAa,IAAI,EAAE,CAAC;CACnE,OAAO,OAAO,QAAQ,YAAY,cAChC,YACE,UACA,MAAM,KAAK,MACX,UAAU,kBACV,UAAU,QACV,UAAU,EACZ,CACF;CAEA,MAAM,UAAoE,CAAC,GAAG,iBAAiB;CAC/F,KAAK,MAAM,aAAa,WAAW;EACjC,MAAM,UAAU,OAAO,OAAO,IAAI,aAAa;GAC7C,OAAO,YACL,UACA,MAAM,KAAK,MACX,UAAU,kBACV,UAAU,QACV,UAAU,EACZ;GACA,OAAO,SAAS,aAAa,MAAM,KAAK,MAAM,UAAU,gBAAgB;GACxE,QAAQ,KAAK;IAAE,aAAa,UAAU;IAAI,kBAAkB,UAAU;GAAiB,CAAC;EAC1F,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM;GAAE,YAAY,UAAU;GAAO,iBAAiB;EAAK,CAAC,CAAC;EAC5E,IAAI,YAAY,MAAM;GACpB,IAAI,QAAQ,WAAW,GAAG,OAAO,OAAO;GACxC,OAAO,OAAO,IAAI,aAAa;IAC7B,mBAAmB,UAAU;IAC7B,SAAS,QAAQ;IACjB,SAAS,OAAO,YAAY,MAAM,MAAM,SAAS,SAAS;GAC5D,CAAC;EACH;CACF;CACA,OAAO,OAAO,YAAY,MAAM,MAAM,SAAS,UAAU;AAC3D,CAAC;AAED,SAAgB,SAAS,MAAqE;CAC5F,MAAM,WAA+C;EACnD,WAAW,KAAK;EAChB,WAAW,KAAK;EAChB,YAAY,KAAK;EACjB,YAAY,KAAK;EACjB,kBAAkB,KAAK;EACvB,SAAS,KAAK;EACd,MAAM,KAAK;CACb;CACA,OAAO,cAAc,cAAc,QAAQ,CAAC,CAAC,KAC3C,OAAO,SAAS,WACd,WAAW,KAAK,SACZ,OAAO,OACP,OAAO,KAAK,IAAIA,QAAM,EAAE,SAAS,mDAAmD,CAAC,CAAC,CAC5F,CACF;AACF;AAEA,SAAS,qBACP,MACA,SACwF;CACxF,IAAI,YAAY,KAAA,GAAW,OAAO,OAAO,QAAQ,CAAC,CAAC;CACnD,IACE,QAAQ,eAAe,KAAK,UAC5B,QAAQ,eAAe,KAAK,cAC5B,QAAQ,SAAS,KAAK,QACtB,QAAQ,WAAW,WAEnB,OAAO,OAAO,KACZ,IAAIA,QAAM,EAAE,SAAS,sDAAsD,CAAC,CAC9E;CAEF,KAAK,MAAM,aAAa,QAAQ,YAAY;EAC1C,MAAM,YAAY,KAAK,WAAW,MAAM,EAAE,SAAS,OAAO,UAAU,WAAW;EAC/E,IAAI,cAAc,KAAA,KAAa,UAAU,qBAAqB,UAAU,kBACtE,OAAO,OAAO,KACZ,IAAIA,QAAM,EAAE,SAAS,2DAA2D,CAAC,CACnF;CAEJ;CACA,OAAO,OAAO,QAAQ,CAAC,GAAG,QAAQ,UAAU,CAAC;AAC/C;AAEA,SAAS,YACP,UACA,MACA,kBACA,UACA,aACgD;CAChD,OAAO,SAAS,UAAU,MAAM,gBAAgB,CAAC,CAAC,KAChD,OAAO,SAAS,aACd,aAAa,QAAQ,SAAS,SAAS,YAAYG,OAAiB,UAAU,QAAQ,IAClF,OAAO,OACP,OAAO,KACL,IAAIH,QAAM;EACR,SACE,aAAa,OACT,oCACA;EACN;CACF,CAAC,CACH,CACN,CACF;AACF;AAEA,SAAS,YACP,MACA,YACA,QACwB;CACxB,OAAO,MAAM,kBAAkB,KAC7B,OAAO,KAAK,SAAS;EACnB,WAAW,IAAI,KAAK,GAAG;EACvB;EACA,YAAY,KAAK;EACjB,YAAY,KAAK;EACjB;EACA,SAAS;EACT,MAAM,KAAK;CACb,EAAE,CACJ;AACF;;;;ACnSA,MAAM,mBAAmB,OAAO,OAAO,KACrC,OAAO,SACL,OAAO,QACP,qBAAqB,UAAU;CAC7B,SAAS,UAAU,MAAM,KAAK,CAAC,CAAC,YAAY;CAC5C,SAAS,UAAU;AACrB,CAAC,CACH,CACF;AAEA,MAAM,kBAAkB,OAAO,OAAO,KACpC,OAAO,SACL,OAAO,QACP,qBAAqB,gBAAgB;CACnC,SAAS,OAAO,YACd,OAAO,IAAI;EACT,WAAWI,QAAiB,KAAK,CAAC,CAAC,SAAS;EAC5C,QAAQ,UACN,IAAI,YAAY,aACd,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAClE,OACA,OACF;CACJ,CAAC;CACH,SAAS,UAAU,OAAO,QAAQ,KAAK;AACzC,CAAC,CACH,CACF;AAEA,MAAM,cAAc,gBAAgB,GAAG,CAAC;AACxC,MAAM,eAAe,gBAAgB,GAAG,CAAC;AAEzC,MAAM,eAAe,OAAO,OAAO,KACjC,OAAO,SACL,OAAO,QACP,qBAAqB,UAAU;CAC7B,SAAS,UAAU;EACjB,MAAM,UAAU,MAAM,KAAK;EAC3B,MAAM,SAAS,CAAC,GAAG,QAAQ,SAAS,oBAAoB,CAAC;EACzD,OAAO,OAAO,WAAW,IACrB,UACA,OACG,KAAK,WAAW,MAAM,MAAM,GAAA,CAAI,QAAQ,QAAQ,IAAG,CAAC,CAAC,QAAQ,SAAS,IAAI,CAAC,CAAC,CAC5E,KAAK,EAAE;CAChB;CACA,SAAS,UAAU;AACrB,CAAC,CACH,CACF;AAEA,MAAM,eAAe,OAAO,OAAO,KACjC,OAAO,SACL,OAAO,QACP,qBAAqB,UAAU;CAC7B,SAAS,UAAU,MAAM,KAAK,CAAC,CAAC,QAAQ,mBAAmB,KAAK;CAChE,SAAS,UAAU;AACrB,CAAC,CACH,CACF;AAEA,SAAgB,MAAM,MAAsB,OAAwB;CAClE,MAAM,gBAAgB;EACpB,QAAQ,MAAR;GACE,KAAK;GACL,KAAK,QACH,OAAO;GACT,KAAK;GACL,KAAK,MACH,OAAO;GACT,KAAK,MACH,OAAO;GACT,KAAK,OACH,OAAO;GACT,KAAK,OACH,OAAO;GACT,KAAK,OACH,OAAO;EACX;CACF,EAAA,CAAG;CACH,IAAI;EACF,OAAO,OAAO,kBAAkB,MAAM,CAAC,CAAC,KAAK;CAC/C,SAAS,OAAO;EACd,MAAM,IAAIC,QAAkB,EAC1B,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAChE,CAAC;CACH;AACF;AAEA,SAAS,gBAAgB,QAAgB,aAAqB;CAC5D,OAAO,OAAO,OAAO,KACnB,OAAO,SACL,OAAO,QACP,qBAAqB,gBAAgB;EACnC,SAAS,OAAO,YACd,OAAO,IAAI;GACT,WAAW;IACT,MAAM,QAAQ,MAAM,KAAK,CAAC,CAAC,MAAM,KAAK;IACtC,IAAI,MAAM,WAAW,QACnB,MAAM,IAAI,MAAM,4CAA4C;IAC9D,MAAM,SAAS,MAAM;IACrB,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,8BAA8B;IACxE,MAAM,eAAeD,QAAiB,MAAM;IAC5C,OAAO,MAAM,KAAK,GAAG;GACvB;GACA,QAAQ,UACN,IAAI,YAAY,aACd,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAClE,OACA,OACF;EACJ,CAAC;EACH,SAAS,UAAU,OAAO,QAAQ,KAAK;CACzC,CAAC,CACH,CACF;AACF;;;;;;;;ACzGA,SAAgBE,OAAK,SAAyC;CAC5D,MAAM,QAAQ,QAAQ,SAAS,WAAW;CAC1C,MAAM,YAAY,QAAQ,aAAa;CACvC,OAAO,EACL,SAAS,OAAO,GAAG,sBAAsB,CAAC,EAAE,UAC1C,OAAO,WAAW;EAChB,MAAM,iBACJ,QAAQ;GAAE;GAAc;GAAO;GAAO;GAAW,UAAU,QAAQ;EAAS,CAAC;EAC/E,QAAQ,UACN,iBAAiBC,UACb,QACA,IAAIA,QAAkB;GACpB;GACA,SAAS,iBAAiB,QAAQ,MAAM,UAAU;GAClD,QAAQ;EACV,CAAC;CACT,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,YAAY,iBAAiB,OAAO,OAAO,CAAC,CAAC,CACvE,EACF;AACF;AAEA,MAAaC,WAAS,YACpB,MAAM,QAAQC,WAAqBH,OAAK,OAAO,CAAC;AAElD,MAAaI,aAAW,YACtBC,UAAoBL,OAAK,OAAO,CAAC;AAEnC,SAAS,iBACP,OACA,SAC0D;CAC1D,OAAO,OAAO,IAAI;EAChB,WAAW,UAAU,OAAO,OAAO;EACnC,QAAQ,UACN,IAAIC,QAAkB;GACpB;GACA,SAAS;GACT,QAAQ;EACV,CAAC;CACL,CAAC,CAAC,CAAC,KACD,OAAO,SAAS,WAAW,eAAe,OAAO,MAAM,CAAC,GACxD,OAAO,QAAQ,YAAY,CAC7B;AACF;AAEA,SAAS,aACP,QAC0D;CAC1D,IAAI,OAAO,UAAU,YACnB,OAAO,OAAO,QAAQ,EAAE,MAAM,SAAS,CAAC;CAE1C,IAAI,OAAO,UAAU,WACnB,OAAO,OAAO,KACZ,IAAIA,QAAkB;EACpB,SAAS,yBAAyB,OAAO,SAAS;EAClD,QAAQ;CACV,CAAC,CACH;CAEF,IAAI,OAAO,YAAY,KAAA,KAAa,OAAO,QAAQ,WAAW,GAC5D,OAAO,OAAO,QAAQ,EAAE,MAAM,SAAS,CAAC;CAE1C,OAAO,OAAO,QAAQ,OAAO,SAAS,cAAc,EAAE,aAAa,YAAY,CAAC,CAAC,CAAC,KAChF,OAAO,KAAK,YAAoC;EAC9C,MAAM,mBAAmB,QAAQ,QAAQ,WAAW,WAAW,IAAI;EACnE,OAAO,iBAAiB,WAAW,IAC/B,EAAE,MAAM,SAAS,IACjB;GAAE,MAAM;GAAU,SAAS;EAAiB;CAClD,CAAC,CACH;AACF;AAEA,SAAS,eACP,OACA,QACoD;CACpD,OAAO,OAAO,IAAI;EAChB,WAAW;GACT,IAAI,OAAO,SAAS,YAAY,MAAM,IAAI,MAAM,0BAA0B;GAC1E,IAAI,OAAO,OAAO,GAAG,MAAM,IAAI,MAAM,4CAA4C;GACjF,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,uCAAuC;GAC3E,MAAM,YAAY,OAAO,aAAa,CAAC;GACvC,IAAI,UAAU,WAAW,GAAG,MAAM,IAAI,MAAM,2CAA2C;GACvF,MAAM,WAAW,UAAU;GAC3B,IAAI,aAAa,KAAA,GAAW,MAAM,IAAI,MAAM,uCAAuC;GACnF,IACE,SAAS,UAAU,QACnB,SAAS,SAAS,MAAM,QACxBK,QAAiB,SAAS,IAAI,MAAM,MAAM,MAE1C,MAAM,IAAI,MAAM,6CAA6C;GAE/D,OAAO;EACT;EACA,QAAQ,UACN,IAAIL,QAAkB;GACpB;GACA,SAAS,iBAAiB,QAAQ,MAAM,UAAU;GAClD,QAAQ;EACV,CAAC;CACL,CAAC;AACH;AAEA,SAAS,aACP,QAC6D;CAC7D,OAAO,OAAO,IAAI,aAAa;EAC7B,IAAI,OAAO,UAAU,MAAM,OAAO;EAClC,MAAM,UAAU,OAAO,OAAO,IAAI;GAChC,WAAW,WAAW,MAAM;GAC5B,QAAQ,UACN,IAAIA,QAAkB;IACpB;IACA,SAAS;IACT,QAAQ;GACV,CAAC;EACL,CAAC;EACD,IAAI,YAAY,KAAA,GAAW,OAAO;EAClC,MAAM,OAAO,OAAOM,SAAkB,OAAO,IAAI;EACjD,MAAM,OAAO,OAAO,OAAO,IAAI;GAC7B,WAAWC,MAAc,QAAQ,MAAM,QAAQ,IAAI;GACnD,QAAQ,UACN,IAAIP,QAAkB;IACpB;IACA,SAAS;IACT,QAAQ;GACV,CAAC;EACL,CAAC;EACD,IAAI,OAAO,QAAQ,KAAA,GACjB,OAAO,OAAO,IAAIA,QAAkB;GAClC,SAAS;GACT,QAAQ;EACV,CAAC;EAEH,OAAO;GAAE;GAAM;GAAM,KAAK,OAAO;GAAK,MAAM,QAAQ;EAAK;CAC3D,CAAC,CAAC,CAAC,KACD,OAAO,UAAU,UACf,iBAAiBA,UACb,QACA,IAAIA,QAAkB;EAAE;EAAO,SAAS,MAAM;EAAS,QAAQ;CAAW,CAAC,CACjF,CACF;AACF;AAEA,SAAS,WACP,QACsE;CACtE,QAAQ,OAAO,MAAf;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,MACH,OAAO;GAAE,MAAM,OAAO;GAAM,MAAM,OAAO;EAAK;EAChD,KAAK,OACH,OAAO;GACL,MAAM,GAAG,OAAO,KAAK,SAAS,EAAE,GAAG,OAAO,KAAK,IAAI,GAAG,OAAO,KAAK;GAClE,MAAM,OAAO;EACf;EACF,KAAK,MACH,OAAO;GACL,MAAM,GAAG,eAAe,OAAO,KAAK,YAAY,eAAe,EAAE,GAAG,OAAO,KAAK;GAChF,MAAM,OAAO;EACf;EACF,KAAK,OACH,OAAO;GACL,MAAM;IACJ,eAAe,OAAO,KAAK,UAAU,cAAc;IACnD,eAAe,OAAO,KAAK,QAAQ,YAAY;IAC/C,eAAe,OAAO,KAAK,MAAM,UAAU;IAC3C,OAAO,KAAK;GACd,CAAC,CAAC,KAAK,GAAG;GACV,MAAM,OAAO;EACf;EACF,KAAK,OACH,OAAO;GAAE,MAAM,UAAU,OAAO,IAAI;GAAG,MAAM,OAAO;EAAK;EAC3D,SACE;CACJ;AACF;AAEA,SAAS,UAAU,MAAiC;CAElD,MAAM,WADS,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI,EAAA,CAC1B,KAAK,UAC1B,OAAO,UAAU,WAAW,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,IAAI,KAChE;CACA,MAAM,SAAS,QAAQ,QAAQ,OAAO,UAAU,QAAQ,MAAM,QAAQ,CAAC;CACvE,MAAM,SAAS,IAAI,WAAW,MAAM;CACpC,IAAI,SAAS;CACb,KAAK,MAAM,SAAS,SAAS;EAC3B,OAAO,IAAI,OAAO,MAAM;EACxB,UAAU,MAAM;CAClB;CACA,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,MAAM;AAChE;AAEA,SAAS,eAAe,OAA2B,OAAuB;CACxE,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,MAAM,wBAAwB,OAAO;CACxE,OAAO;AACT;AAEA,eAAe,QAAQ,OAMC;CACtB,MAAM,aAAa,IAAI,gBAAgB;CACvC,IAAI,WAAW;CACf,MAAM,wBAAwB,WAAW,MAAM,MAAM,aAAa,MAAM;CACxE,MAAM,sBAAsB,WAAW,MAAM,MAAM,MAAM,QAAQ,MAAM;CACvE,MAAM,aAAa,iBAAiB,SAAS,iBAAiB,EAAE,MAAM,KAAK,CAAC;CAC5E,MAAM,MAAM,QAAQ,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;CAC3E,MAAM,QAAQ,iBAAiB;EAC7B,WAAW;EACX,WAAW,sBAAM,IAAI,MAAM,0BAA0B,CAAC;CACxD,GAAG,MAAM,SAAS;CAClB,IAAI;EACF,MAAM,QAAQ,WAAW,KACvB,UAAU,OAAO;GACf,OAAO,UAAU;GACjB,IAAI;GACJ,WAAW,CAAC;IAAE,MAAM,MAAM,MAAM;IAAM,MAAM,MAAM,MAAM;GAAK,CAAC;GAC9D,MAAM;EACR,CAAC,CACH;EACA,MAAM,WAAW,MAAM,MAAM,MAAM,IAAI,IAAI,MAAM,QAAQ,GAAG;GAC1D,MAAM;GACN,SAAS;IACP,QAAQ;IACR,gBAAgB;GAClB;GACA,QAAQ;GACR,QAAQ,WAAW;EACrB,CAAC;EACD,IAAI,CAAC,SAAS,IACZ,MAAM,IAAIA,QAAkB;GAC1B,SAAS,qBAAqB,SAAS;GACvC,QAAQ;EACV,CAAC;EAEH,MAAM,cAAc,SAAS,QAC1B,IAAI,cAAc,CAAC,EAClB,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAChB,KAAK,CAAC,CACP,YAAY;EACf,IAAI,gBAAgB,2BAClB,MAAM,IAAIA,QAAkB;GAC1B,SAAS,yCAAyC,eAAe;GACjE,QAAQ;EACV,CAAC;EAEH,OAAO,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;CACpD,SAAS,OAAO;EACd,IAAI,UACF,MAAM,IAAIA,QAAkB;GAAE,SAAS;GAAuB,QAAQ;EAAU,CAAC;EAEnF,MAAM;CACR,UAAU;EACR,aAAa,KAAK;EAClB,MAAM,aAAa,oBAAoB,SAAS,eAAe;EAC/D,MAAM,MAAM,QAAQ,oBAAoB,SAAS,aAAa;CAChE;AACF;;;;;;;;AClRA,MAAM,WAAW;AAMjB,SAAgB,KAAK,UAAmB,CAAC,GAA0B;CACjE,OAAOQ,OAAkB;EAAE,GAAG;EAAS,UAAU,QAAQ,YAAY;CAAS,CAAC;AACjF;AAEA,MAAa,SAAS,UAAmB,CAAC,MACxC,MAAM,QAAQC,WAAqB,KAAK,OAAO,CAAC;AAElD,MAAa,WAAW,UAAmB,CAAC,MAC1CC,UAAoB,KAAK,OAAO,CAAC;;;;;;;;;ACXnC,MAAa,sBAAsB,OAAO,YAAY;CACpD,OAAO,CAAC;CACR,SAAS,CAAC;CACV,UAAU,EAAE,SAAS,OAAO,MAAMC,QAAgB,EAAE;CACpD,SAAS,EAAE,SAAS,OAAO,OAAO;AACpC,CAAC;AAGD,MAAa,uBAAuB,OAAO,YAAY;CACrD,YAAY,CAAC;CACb,SAAS,CAAC;CACV,UAAU,EAAE,SAAS,OAAO,MAAM,OAAO,MAAM,EAAE;CACjD,SAAS,CAAC;CACV,SAAS,EAAE,SAAS,OAAO,OAAO;AACpC,CAAC;AAGD,MAAa,SAAS,OAAO,OAAO;CAClC,UAAU;CACV,WAAW;CACX,QAAQ,OAAO,SAAS;EAAC;EAAY;EAAW;EAAY;CAAa,CAAC;AAC5E,CAAC;AAGD,MAAa,SAAS,OAAO,GAAG,qBAAqB,CAAC,CAAC,WAAW,OAG/D;CACD,MAAM,WAAW,OAAOC;CACxB,MAAM,WAAW,OAAOC;CACxB,MAAM,CAAC,qBAAqB,aAAa,OAAO,OAAO,IACrD,CACE,gBAAgB,UAAU,MAAM,MAAM,MAAM,MAAM,CAAC,CAAC,KAClD,OAAO,OAAO,YACZ,OAAO,QAA6B;EAAE,MAAM;EAAW,SAAS,QAAQ;CAAQ,CAAC,CACnF,CACF,GACA,SAAS,QAAQ;EAAE,MAAM,MAAM,OAAO;EAAM,MAAM,MAAM,OAAO;CAAK,CAAC,CAAC,CAAC,KACrE,OAAO,MAAM;EACX,YAAY,YACV,QAAQ,WAAW,YACf,EAAE,MAAM,UAAU,IAClB;GAAE,MAAM;GAAW,SAAS,QAAQ;EAAQ;EAClD,YAAY,eAAe,iBAAiB,MAAM,QAAQ,UAAU;CACtE,CAAC,CACH,CACF,GACA,EAAE,aAAa,YAAY,CAC7B;CAWA,OAAO;EAAE,UAAU;EAAqB;EAAW,QATjD,oBAAoB,SAAS,WAAW,UAAU,SAAS,eACvD,aACA,oBAAoB,SAAS,aAC3B,UAAU,SAAS,aACnB,UAAU,SAAS,YACnB,gBACA,oBAAoB,SAAS,cAAc,UAAU,SAAS,aAC5D,aACA;CACgD;AAC5D,CAAC;AAED,SAAS,gBACP,UACA,MACA,aACuD;CACvD,OAAO,SAAS,YAAY,IAAI,CAAC,CAAC,KAChC,OAAO,KAAK,YAAiC;EAC3C,IACE,QAAQ,MACL,aAAa,SAAS,SAAS,YAAYC,OAAiB,UAAU,WAAW,CACpF,GAEA,OAAO,EAAE,MAAM,QAAQ;EAEzB,MAAM,UAAU,QAAQ,QACrB,aACC,SAAS,SAAS,YAClB,SAAS,SAAS,YAAY,QAC9B,SAAS,SAAS,YAAY,IAClC;EACA,OAAO,QAAQ,WAAW,IAAI,EAAE,MAAM,UAAU,IAAI;GAAE,MAAM;GAAY,SAAS;EAAQ;CAC3F,CAAC,CACH;AACF;AAEA,SAAS,iBACP,aACA,YACsB;CACtB,IAAI,WAAW,SAAS,UAAU,OAAO,EAAE,MAAM,UAAU;CAC3D,MAAM,WAAWC,MAAc,YAAY,MAAM,YAAY,WAAW,CAAC;CACzE,OAAO,WAAW,QAAQ,MACvB,WACC,OAAO,SAAS,YAAY,QAC5B,OAAO,SAAS,YAAY,QAC5BA,MAAc,OAAO,MAAM,OAAO,IAAI,MAAM,QAChD,IACI,EAAE,MAAM,aAAa,IACrB;EAAE,MAAM;EAAY,SAAS,WAAW,QAAQ,KAAK,EAAE,WAAW,IAAI;CAAE;AAC9E;AAEA,SAAS,YAAY,aAA0C;CAC7D,MAAMC,SAAOC,KAAe,WAAW;CACvC,QAAQ,YAAY,MAApB;EACE,KAAK;EACL,KAAK,QACH,OAAO,OAAOD,OAAK,OAAO;EAC5B,KAAK;EACL,KAAK,MACH,OAAO,OAAOA,OAAK,MAAM;EAC3B,KAAK,OACH,OAAO,OAAOA,OAAK,KAAK;EAC1B,KAAK,MACH,OAAO,GAAGA,OAAK,SAAS,GAAGA,OAAK;EAClC,KAAK,OACH,OAAO,GAAGA,OAAK,MAAM,GAAGA,OAAK,IAAI,GAAGA,OAAK;EAC3C,KAAK,OACH,OAAO,GAAGA,OAAK,SAAS,GAAGA,OAAK,OAAO,GAAGA,OAAK,KAAK,GAAGA,OAAK;CAChE;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domainkit",
3
- "version": "0.1.0-beta.0",
3
+ "version": "0.1.0-beta.1",
4
4
  "description": "Provider-independent DNS provisioning plans and authorization for TypeScript",
5
5
  "keywords": [
6
6
  "dns",
@@ -69,6 +69,8 @@
69
69
  "test": "vitest run --exclude tests/artifact/**/*.test.ts",
70
70
  "test:artifact": "vitest run tests/artifact",
71
71
  "test:consumers": "vitest run tests/artifact/packed-consumers.test.ts",
72
+ "test:live:cloudflare": "bun tests/live/cloudflare.ts",
73
+ "test:live:vercel": "bun tests/live/vercel.ts",
72
74
  "test:providers": "vitest run tests/providers",
73
75
  "test:watch": "vitest",
74
76
  "typecheck": "tsc --noEmit",
@@ -92,7 +94,7 @@
92
94
  "vitest": "4.1.11"
93
95
  },
94
96
  "peerDependencies": {
95
- "effect": ">=4.0.0-rc.112 <5"
97
+ "effect": ">=4.0.0-rc.111 <5"
96
98
  },
97
99
  "engines": {
98
100
  "node": ">=24.10.0"
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-Df9BuC25.mjs","names":["S","S","decode","DomainName.decode","failure","DnsRecord.decode","DnsRecord.Opaque","DnsProvider.Error","Protocol.ZoneListEnvelope","Protocol.RecordListEnvelope","Records.decode","Records.encode","Protocol.RecordEnvelope","Protocol.TokenEnvelope","DomainName.decode","S","Protocol.BaseEnvelope","DnsProvider.Error","Client.make"],"sources":["../src/providers/cloudflare/protocol.ts","../src/providers/cloudflare/records.ts","../src/providers/cloudflare/client.ts","../src/providers/cloudflare/auth.ts"],"sourcesContent":["import { Schema as S } from \"effect\";\n\nexport const ErrorDetail = S.Struct({\n code: S.Number,\n message: S.String,\n});\nexport interface ErrorDetail extends S.Schema.Type<typeof ErrorDetail> {}\n\nexport const ResultInfo = S.Struct({\n count: S.optionalKey(S.Number),\n page: S.optionalKey(S.Number),\n per_page: S.optionalKey(S.Number),\n total_count: S.optionalKey(S.Number),\n total_pages: S.optionalKey(S.Number),\n});\n\nconst Message = S.Struct({\n code: S.optionalKey(S.Number),\n message: S.String,\n});\n\nexport const BaseEnvelope = S.Struct({\n errors: S.Array(ErrorDetail),\n messages: S.Array(Message),\n success: S.Boolean,\n});\n\nexport const Account = S.Struct({\n id: S.String,\n name: S.String,\n});\nexport interface Account extends S.Schema.Type<typeof Account> {}\n\nexport const Zone = S.Struct({\n account: Account,\n id: S.String,\n name: S.String,\n name_servers: S.Array(S.String),\n status: S.optionalKey(S.String),\n});\nexport interface Zone extends S.Schema.Type<typeof Zone> {}\n\nexport const Record = S.Struct({\n content: S.optionalKey(S.String),\n data: S.optionalKey(S.Unknown),\n id: S.String,\n name: S.String,\n priority: S.optionalKey(S.Number),\n proxied: S.optionalKey(S.Boolean),\n ttl: S.Number,\n type: S.String,\n});\nexport interface Record extends S.Schema.Type<typeof Record> {}\n\nexport const Token = S.Struct({\n expires_on: S.optionalKey(S.String),\n id: S.String,\n not_before: S.optionalKey(S.String),\n status: S.Literals([\"active\", \"disabled\", \"expired\"]),\n});\nexport interface Token extends S.Schema.Type<typeof Token> {}\n\nexport const ZoneListEnvelope = S.Struct({\n errors: S.Array(ErrorDetail),\n messages: S.Array(Message),\n result: S.Array(Zone),\n result_info: S.optionalKey(ResultInfo),\n success: S.Boolean,\n});\nexport const RecordListEnvelope = S.Struct({\n errors: S.Array(ErrorDetail),\n messages: S.Array(Message),\n result: S.Array(Record),\n result_info: S.optionalKey(ResultInfo),\n success: S.Boolean,\n});\nexport const RecordEnvelope = S.Struct({\n errors: S.Array(ErrorDetail),\n messages: S.Array(Message),\n result: Record,\n success: S.Boolean,\n});\nexport const TokenEnvelope = S.Struct({\n errors: S.Array(ErrorDetail),\n messages: S.Array(Message),\n result: Token,\n success: S.Boolean,\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 * as DnsProvider from \"../../provider/provider.ts\";\nimport type * as Protocol from \"./protocol.ts\";\n\nconst Data = S.Struct({\n flags: S.optionalKey(S.Number),\n port: S.optionalKey(S.Number),\n priority: S.optionalKey(S.Number),\n tag: S.optionalKey(S.String),\n target: S.optionalKey(S.String),\n value: S.optionalKey(S.String),\n weight: S.optionalKey(S.Number),\n});\n\nexport type CreateBody = Readonly<Record<string, unknown>>;\n\nexport const decode = Effect.fn(\"CloudflareRecords.decode\")((record: Protocol.Record) =>\n Effect.gen(function* () {\n const name = yield* DomainName.decode(record.name).pipe(\n Effect.match({ onFailure: () => null, onSuccess: (value) => value }),\n );\n if (name === null) return yield* decodeOpaque(record);\n const common = {\n metadata: {\n ownership: \"provider\",\n provenance: record.proxied === true ? \"cloudflare:proxied\" : \"cloudflare\",\n purpose: \"existing DNS record\",\n },\n name,\n policy: record.type === \"CNAME\" ? \"exclusive\" : \"append\",\n ttl: record.ttl === 1 ? null : record.ttl,\n } as const;\n const content = () =>\n record.content === undefined\n ? Effect.fail(failure(\"decodeRecord\", `Cloudflare ${record.type} record has no content`))\n : Effect.succeed(record.content);\n\n switch (record.type) {\n case \"A\":\n case \"AAAA\":\n return yield* DnsRecord.decode({\n ...common,\n _tag: record.type,\n address: yield* content(),\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)));\n case \"CNAME\":\n case \"NS\":\n return yield* DnsRecord.decode({\n ...common,\n _tag: record.type,\n target: yield* content(),\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)));\n case \"TXT\":\n return yield* DnsRecord.decode({\n ...common,\n _tag: \"TXT\",\n value: yield* content(),\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)));\n case \"MX\":\n return yield* DnsRecord.decode({\n ...common,\n _tag: \"MX\",\n exchange: yield* content(),\n priority: record.priority,\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)));\n case \"CAA\": {\n const data = yield* decodeData(record);\n return yield* DnsRecord.decode({ ...common, _tag: \"CAA\", ...data }).pipe(\n Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)),\n );\n }\n case \"SRV\": {\n const data = yield* decodeData(record);\n return yield* DnsRecord.decode({ ...common, _tag: \"SRV\", ...data }).pipe(\n Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)),\n );\n }\n default:\n return yield* decodeOpaque(record);\n }\n }),\n);\n\nconst decodeOpaque = Effect.fn(\"CloudflareRecords.decodeOpaque\")((record: Protocol.Record) =>\n S.decodeUnknownEffect(DnsRecord.Opaque)({\n _tag: \"Opaque\",\n name: record.name,\n providerRecordId: record.id,\n providerType: record.type,\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message))),\n);\n\nexport function encode(record: DnsRecord.DnsRecord): CreateBody {\n const common = {\n name: record.name,\n proxied: false,\n ttl: record.ttl ?? 1,\n type: record._tag,\n };\n switch (record._tag) {\n case \"A\":\n case \"AAAA\":\n return { ...common, content: record.address };\n case \"CNAME\":\n case \"NS\":\n return { ...common, content: record.target };\n case \"TXT\":\n return { ...common, content: record.value };\n case \"MX\":\n return { ...common, content: record.exchange, priority: record.priority };\n case \"CAA\":\n return {\n ...common,\n data: { flags: record.flags, tag: record.tag, value: record.value },\n };\n case \"SRV\":\n return {\n ...common,\n data: {\n port: record.port,\n priority: record.priority,\n target: record.target,\n weight: record.weight,\n },\n };\n }\n}\n\nconst decodeData = Effect.fn(\"CloudflareRecords.decodeData\")((record: Protocol.Record) =>\n S.decodeUnknownEffect(Data)(record.data).pipe(\n Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)),\n ),\n);\n\nfunction failure(\n operation: string,\n message: string,\n fields: Partial<Pick<DnsProvider.Error, \"reason\">> = {},\n): DnsProvider.Error {\n return new DnsProvider.Error({\n message,\n operation,\n providerId: \"cloudflare\",\n reason: fields.reason ?? \"response\",\n });\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport type * as ProviderAuth from \"../../auth/manifest.ts\";\nimport type * as Secret from \"../../auth/secret.ts\";\nimport * as DomainName from \"../../domain/domain-name.ts\";\nimport type * as DnsRecord from \"../../domain/dns-record.ts\";\nimport * as DnsProvider from \"../../provider/provider.ts\";\nimport * as Protocol from \"./protocol.ts\";\nimport * as Records from \"./records.ts\";\n\nexport type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\n/** Configuration for an Effect-native Cloudflare authoritative-DNS client. */\nexport interface Options {\n readonly accountId: string;\n readonly baseUrl?: string;\n /** Capabilities the host required when issuing or authorizing this credential. */\n readonly capabilities: ProviderAuth.TokenValidation[\"capabilities\"];\n readonly fetch?: Fetch;\n readonly token: Secret.Value;\n readonly tokenKind?: \"account\" | \"user\";\n}\n\nexport interface ListZonesInput {\n readonly accountId?: string;\n readonly name?: DomainName.DomainName;\n}\n\nexport type Account = Protocol.Account;\n\n/** A portable Cloudflare authoritative zone with normalized nameserver evidence. */\nexport interface Zone {\n readonly accountId: string;\n readonly id: string;\n readonly name: DomainName.DomainName;\n readonly nameservers: ReadonlyArray<DomainName.DomainName>;\n readonly status: string | null;\n}\n\nexport interface Interface extends DnsProvider.Interface {\n readonly listAccounts: () => Effect.Effect<ReadonlyArray<Account>, DnsProvider.Error>;\n readonly listZones: (\n input?: ListZonesInput,\n ) => Effect.Effect<ReadonlyArray<Zone>, DnsProvider.Error>;\n readonly validateToken: () => Effect.Effect<ProviderAuth.TokenValidation, DnsProvider.Error>;\n}\n\n/** Creates an Effect-native Cloudflare client without owning the credential lifecycle. */\nexport function make(options: Options): Interface {\n const fetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"https://api.cloudflare.com/client/v4\").replace(/\\/$/, \"\");\n\n const request = Effect.fn(\"CloudflareClient.request\")(\n (path: string, operation: string, init?: RequestInit) =>\n Effect.gen(function* () {\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(`${baseUrl}${path}`, {\n ...init,\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${options.token.expose()}`,\n ...(init?.body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n ...init?.headers,\n },\n }),\n catch: () =>\n failure(operation, \"Cloudflare request failed\", {\n reason: \"transport\",\n }),\n });\n const body = yield* Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () => {\n const retryAfterMs = retryAfter(response.headers.get(\"retry-after\"));\n return failure(\n operation,\n response.ok\n ? \"Cloudflare returned a non-JSON response\"\n : `Cloudflare request failed with HTTP ${response.status}`,\n {\n reason: response.ok ? \"response\" : reason(response.status),\n ...(retryAfterMs === undefined ? {} : { retryAfterMs }),\n status: response.status,\n },\n );\n },\n });\n return { body, response } as const;\n }),\n );\n\n const listZonesPage = Effect.fn(\"CloudflareClient.listZonesPage\")(\n (accountId: string | undefined, name: DomainName.DomainName | undefined, page: number) =>\n Effect.gen(function* () {\n const query = new URLSearchParams({ page: String(page), per_page: \"50\" });\n query.set(\"type\", \"full,partial,secondary,internal\");\n if (accountId !== undefined) query.set(\"account.id\", accountId);\n if (name !== undefined) query.set(\"name\", name);\n const { body, response } = yield* request(`/zones?${query}`, \"listZones\");\n yield* ensureSuccess(body, \"listZones\", response);\n const envelope = yield* decode(Protocol.ZoneListEnvelope, body, \"listZones\", response);\n return envelope;\n }),\n );\n\n const allZones = Effect.fn(\"CloudflareClient.allZones\")(\n (accountId?: string, name?: DomainName.DomainName) =>\n Effect.gen(function* () {\n const zones: Array<Protocol.Zone> = [];\n let page = 1;\n while (true) {\n const envelope = yield* listZonesPage(accountId, name, page);\n zones.push(...envelope.result);\n const totalPages = envelope.result_info?.total_pages;\n if (\n (totalPages !== undefined && page >= totalPages) ||\n (totalPages === undefined && envelope.result.length < 50)\n ) {\n return zones;\n }\n page += 1;\n }\n }),\n );\n\n const resolveZone = Effect.fn(\"CloudflareClient.resolveZone\")((name: DomainName.DomainName) =>\n Effect.gen(function* () {\n const matches = yield* allZones(options.accountId, name);\n const match = matches[0];\n if (matches.length === 1 && match !== undefined) return match;\n return yield* Effect.fail(\n failure(\n \"resolveZone\",\n matches.length === 0\n ? `Cloudflare zone ${name} was not found in account ${options.accountId}`\n : `Cloudflare returned multiple zones named ${name} in account ${options.accountId}`,\n { reason: matches.length === 0 ? \"not_found\" : \"response\" },\n ),\n );\n }),\n );\n\n const listRecords = Effect.fn(\"CloudflareClient.listRecords\")((zoneName: DomainName.DomainName) =>\n Effect.gen(function* () {\n const zone = yield* resolveZone(zoneName);\n const records: Array<DnsRecord.Observed> = [];\n let page = 1;\n while (true) {\n const query = new URLSearchParams({ page: String(page), per_page: \"100\" });\n const { body, response } = yield* request(\n `/zones/${encodeURIComponent(zone.id)}/dns_records?${query}`,\n \"listRecords\",\n );\n yield* ensureSuccess(body, \"listRecords\", response);\n const envelope = yield* decode(Protocol.RecordListEnvelope, body, \"listRecords\", response);\n records.push(...(yield* Effect.forEach(envelope.result, Records.decode)));\n const totalPages = envelope.result_info?.total_pages;\n if (\n (totalPages !== undefined && page >= totalPages) ||\n (totalPages === undefined && envelope.result.length < 100)\n ) {\n return records;\n }\n page += 1;\n }\n }),\n );\n\n const createRecord = Effect.fn(\"CloudflareClient.createRecord\")(\n (zoneName: DomainName.DomainName, record: DnsRecord.DnsRecord) =>\n Effect.gen(function* () {\n const zone = yield* resolveZone(zoneName);\n const { body, response } = yield* request(\n `/zones/${encodeURIComponent(zone.id)}/dns_records`,\n \"createRecord\",\n { body: JSON.stringify(Records.encode(record)), method: \"POST\" },\n );\n yield* ensureSuccess(body, \"createRecord\", response);\n const envelope = yield* decode(Protocol.RecordEnvelope, body, \"createRecord\", response);\n return { providerRecordId: envelope.result.id };\n }),\n );\n\n const listAccounts = Effect.fn(\"CloudflareClient.listAccounts\")(() =>\n allZones().pipe(\n Effect.map((zones) => {\n const accounts = new Map<string, Protocol.Account>();\n for (const zone of zones) accounts.set(zone.account.id, zone.account);\n return [...accounts.values()].sort((left, right) => left.name.localeCompare(right.name));\n }),\n ),\n );\n\n const listZones = Effect.fn(\"CloudflareClient.listZones\")((input: ListZonesInput = {}) =>\n allZones(input.accountId ?? options.accountId, input.name).pipe(\n Effect.flatMap((zones) => Effect.forEach(zones, projectZone)),\n ),\n );\n\n const validateToken = Effect.fn(\"CloudflareClient.validateToken\")(() =>\n Effect.gen(function* () {\n const path =\n options.tokenKind === \"account\"\n ? `/accounts/${encodeURIComponent(options.accountId)}/tokens/verify`\n : \"/user/tokens/verify\";\n const { body, response } = yield* request(path, \"validateToken\");\n yield* ensureSuccess(body, \"validateToken\", response);\n const envelope = yield* decode(Protocol.TokenEnvelope, body, \"validateToken\", response);\n if (envelope.result.status !== \"active\") {\n return yield* Effect.fail(\n failure(\"validateToken\", `Cloudflare token is ${envelope.result.status}`, {\n reason: \"authentication\",\n status: response.status,\n }),\n );\n }\n yield* allZones(options.accountId);\n const expiresAt =\n envelope.result.expires_on === undefined ? null : new Date(envelope.result.expires_on);\n if (expiresAt !== null && Number.isNaN(expiresAt.valueOf())) {\n return yield* Effect.fail(\n failure(\"validateToken\", \"Cloudflare token expiry is not a valid timestamp\", {\n reason: \"response\",\n status: response.status,\n }),\n );\n }\n return {\n accountId: options.accountId,\n capabilities: options.capabilities,\n expiresAt,\n scopes: [],\n };\n }),\n );\n\n return {\n id: \"cloudflare\",\n createRecord,\n listAccounts,\n listRecords,\n listZones,\n validateToken,\n };\n}\n\nconst projectZone = Effect.fn(\"CloudflareClient.projectZone\")((zone: Protocol.Zone) =>\n Effect.gen(function* () {\n const name = yield* DomainName.decode(zone.name).pipe(\n Effect.mapError((cause) => failure(\"listZones\", cause.message, { reason: \"response\" })),\n );\n const nameservers = yield* Effect.forEach(zone.name_servers, (nameserver) =>\n DomainName.decode(nameserver).pipe(\n Effect.mapError((cause) => failure(\"listZones\", cause.message, { reason: \"response\" })),\n ),\n );\n return {\n accountId: zone.account.id,\n id: zone.id,\n name,\n nameservers,\n status: zone.status ?? null,\n };\n }),\n);\n\nfunction decode<A>(\n schema: S.ConstraintCodec<A, unknown, never, unknown>,\n input: unknown,\n operation: string,\n response: Response,\n): Effect.Effect<A, DnsProvider.Error> {\n return S.decodeUnknownEffect(schema)(input).pipe(\n Effect.mapError((cause) =>\n failure(operation, `Cloudflare response did not match its API contract: ${cause.message}`, {\n reason: \"response\",\n status: response.status,\n }),\n ),\n );\n}\n\nfunction ensureSuccess(\n input: unknown,\n operation: string,\n response: Response,\n): Effect.Effect<void, DnsProvider.Error> {\n return S.decodeUnknownEffect(Protocol.BaseEnvelope)(input).pipe(\n Effect.mapError(() =>\n failure(operation, \"Cloudflare response did not contain a valid API envelope\", {\n reason: \"response\",\n status: response.status,\n }),\n ),\n Effect.flatMap((envelope) => {\n if (response.ok && envelope.success) return Effect.void;\n const detail = envelope.errors[0];\n const retryAfterMs = retryAfter(response.headers.get(\"retry-after\"));\n return Effect.fail(\n failure(\n operation,\n detail?.message ?? `Cloudflare request failed with HTTP ${response.status}`,\n {\n ...(detail === undefined ? {} : { code: detail.code }),\n reason: reason(response.status, detail?.code),\n ...(retryAfterMs === undefined ? {} : { retryAfterMs }),\n status: response.status,\n },\n ),\n );\n }),\n );\n}\n\nfunction reason(status: number, code?: number): DnsProvider.ErrorReason {\n if (status === 401) return \"authentication\";\n if (status === 403) return \"authorization\";\n if (status === 404) return \"not_found\";\n if (status === 409 || code === 81056 || code === 81057 || code === 81058) return \"conflict\";\n if (status === 429) return \"rate_limit\";\n if (status >= 500) return \"response\";\n return \"request\";\n}\n\nfunction retryAfter(value: string | null): number | undefined {\n if (value === null) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1_000);\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nfunction failure(\n operation: string,\n message: string,\n fields: Partial<Pick<DnsProvider.Error, \"code\" | \"reason\" | \"retryAfterMs\" | \"status\">> = {},\n): DnsProvider.Error {\n return new DnsProvider.Error({\n ...fields,\n message,\n operation,\n providerId: \"cloudflare\",\n });\n}\n","import type * as oauth from \"oauth4webapi\";\nimport { Clock, Effect } from \"effect\";\n\nimport type * as ProviderAuth from \"../../auth/manifest.ts\";\nimport type * as Secret from \"../../auth/secret.ts\";\nimport * as Client from \"./client.ts\";\n\nconst authorizationServer = {\n authorization_endpoint: \"https://dash.cloudflare.com/oauth2/auth\",\n issuer: \"https://dash.cloudflare.com\",\n revocation_endpoint: \"https://dash.cloudflare.com/oauth2/revoke\",\n token_endpoint: \"https://dash.cloudflare.com/oauth2/token\",\n} as const;\n\n/** Describes Cloudflare's caller-created API-token authorization method. */\nexport function tokenMethod(\n capabilities: ProviderAuth.TokenValidation[\"capabilities\"],\n): Extract<ProviderAuth.Manifest[\"methods\"][number], { readonly _tag: \"token\" }> {\n return {\n _tag: \"token\",\n capabilities: [...capabilities],\n instructionsUrl: \"https://developers.cloudflare.com/fundamentals/api/get-started/create-token/\",\n };\n}\n\nexport interface OAuthMethodOptions {\n /** Scope IDs assigned to the OAuth client by Cloudflare. */\n readonly scopes: ReadonlyArray<string>;\n /** Capabilities represented by those assigned scope IDs. */\n readonly capabilities: ProviderAuth.TokenValidation[\"capabilities\"];\n readonly clientAuth: ProviderAuth.OAuthMethod[\"clientAuth\"];\n}\n\n/** Describes a registered Cloudflare OAuth client and its assigned scope IDs. */\nexport function oauthMethod(options: OAuthMethodOptions): ProviderAuth.OAuthMethod {\n return {\n _tag: \"oauth2\",\n authorizationServer,\n capabilities: [...options.capabilities],\n clientAuth: options.clientAuth,\n scopes: [...options.scopes],\n };\n}\n\n/** Creates the Cloudflare token and OAuth authorization manifest. */\nexport function manifest(options: OAuthMethodOptions): ProviderAuth.Manifest {\n return {\n methods: [tokenMethod(options.capabilities), oauthMethod(options)],\n providerId: \"cloudflare\",\n };\n}\n\nexport interface SubjectResolverOptions extends Omit<Client.Options, \"token\" | \"tokenKind\"> {}\n\n/** Resolves the Cloudflare account selected by a completed OAuth grant. */\nexport function subjectResolver(\n options: SubjectResolverOptions,\n): ProviderAuth.OAuthSubjectResolver {\n return (tokens: oauth.TokenEndpointResponse, accessToken: Secret.Value) =>\n Effect.gen(function* () {\n const client = Client.make({ ...options, token: accessToken, tokenKind: \"user\" });\n yield* client.listZones();\n const now = yield* Clock.currentTimeMillis;\n return {\n accountId: options.accountId,\n expiresAt:\n typeof tokens.expires_in === \"number\" ? new Date(now + tokens.expires_in * 1_000) : null,\n };\n });\n}\n\n/** Creates a host callback that validates a Cloudflare API token. */\nexport function tokenValidator(\n options: Omit<Client.Options, \"token\">,\n): (token: Secret.Value) => ReturnType<Client.Interface[\"validateToken\"]> {\n return (token) => Client.make({ ...options, token }).validateToken();\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-DvXfJx_E.mjs","names":["make","S","failure","S","Protocol.ErrorEnvelope","Protocol.IntegrationToken","Secret.make","DnsProvider.Error","decode","DomainName.decode","DnsRecord.decode","failure","S","DnsRecord.Opaque","DnsProvider.Error","Protocol.TeamListEnvelope","Protocol.DomainListEnvelope","Protocol.DomainConfig","Protocol.DomainEnvelope","DomainName.decode","Protocol.RecordListEnvelope","Records.decode","Records.encode","DnsProvider.Error","Protocol.CreateRecordEnvelope","Protocol.UserEnvelope","S","Protocol.ErrorEnvelope"],"sources":["../src/auth/secret.ts","../src/providers/vercel/protocol.ts","../src/providers/vercel/auth.ts","../src/providers/vercel/records.ts","../src/providers/vercel/client.ts"],"sourcesContent":["/** A deliberately non-serializable credential value. */\nexport class Value {\n readonly #value: string;\n\n private constructor(value: string) {\n this.#value = value;\n }\n\n static from(value: string): Value {\n if (value.length === 0) throw new Error(\"Secret values cannot be empty\");\n return new Value(value);\n }\n\n expose(): string {\n return this.#value;\n }\n\n toJSON(): string {\n return \"[REDACTED]\";\n }\n\n toString(): string {\n return \"[REDACTED]\";\n }\n}\n\nexport const make = Value.from;\n","import { Schema as S } from \"effect\";\n\nexport const Pagination = S.Struct({\n count: S.Number,\n next: S.NullOr(S.Number),\n prev: S.NullOr(S.Number),\n});\nexport interface Pagination extends S.Schema.Type<typeof Pagination> {}\n\nexport const ErrorDetail = S.Struct({\n code: S.String,\n message: S.String,\n limit: S.optionalKey(\n S.Struct({\n remaining: S.Number,\n reset: S.optionalKey(S.Number),\n resetMs: S.optionalKey(S.Number),\n total: S.Number,\n }),\n ),\n});\nexport interface ErrorDetail extends S.Schema.Type<typeof ErrorDetail> {}\n\nexport const ErrorEnvelope = S.Struct({ error: ErrorDetail });\n\nexport const User = S.Struct({\n id: S.String,\n name: S.NullOr(S.String),\n username: S.String,\n});\nexport interface User extends S.Schema.Type<typeof User> {}\n\nexport const UserEnvelope = S.Struct({ user: User });\n\nexport const Team = S.Struct({\n id: S.String,\n name: S.NullOr(S.String),\n slug: S.String,\n});\nexport interface Team extends S.Schema.Type<typeof Team> {}\n\nexport const TeamListEnvelope = S.Struct({\n pagination: Pagination,\n teams: S.Array(Team),\n});\n\nexport const Domain = S.Struct({\n id: S.String,\n intendedNameservers: S.Array(S.String),\n name: S.String,\n nameservers: S.Array(S.String),\n serviceType: S.Literals([\"zeit.world\", \"external\", \"na\"]),\n teamId: S.NullOr(S.String),\n userId: S.String,\n verified: S.Boolean,\n});\nexport interface Domain extends S.Schema.Type<typeof Domain> {}\n\nexport const DomainConfig = S.Struct({\n misconfigured: S.Boolean,\n serviceType: S.Literals([\"zeit.world\", \"external\", \"na\"]),\n});\nexport interface DomainConfig extends S.Schema.Type<typeof DomainConfig> {}\n\nexport const DomainEnvelope = S.Struct({ domain: Domain });\n\nexport const DomainListEnvelope = S.Struct({\n domains: S.Array(Domain),\n pagination: Pagination,\n});\n\nexport const Record = S.Struct({\n id: S.String,\n mxPriority: S.optionalKey(S.Number),\n name: S.String,\n priority: S.optionalKey(S.Number),\n ttl: S.optionalKey(S.Number),\n type: S.String,\n value: S.String,\n});\nexport interface Record extends S.Schema.Type<typeof Record> {}\n\nexport const RecordListEnvelope = S.Struct({\n pagination: S.optionalKey(Pagination),\n records: S.Array(Record),\n});\n\nexport const CreateRecordEnvelope = S.Struct({\n uid: S.String,\n updated: S.optionalKey(S.Number),\n});\n\nexport const IntegrationToken = S.Struct({\n access_token: S.String,\n installation_id: S.optionalKey(S.String),\n team_id: S.NullOr(S.String),\n token_type: S.optionalKey(S.String),\n user_id: S.String,\n});\nexport interface IntegrationToken extends S.Schema.Type<typeof IntegrationToken> {}\n","import { Effect, Schema as S } from \"effect\";\n\nimport type * as ProviderAuth from \"../../auth/manifest.ts\";\nimport * as Secret from \"../../auth/secret.ts\";\nimport * as DnsProvider from \"../../provider/provider.ts\";\nimport type * as Client from \"./client.ts\";\nimport * as Protocol from \"./protocol.ts\";\n\n/** Describes Vercel's caller-created personal access-token method. */\nexport function tokenMethod(\n capabilities: ProviderAuth.TokenValidation[\"capabilities\"],\n): Extract<ProviderAuth.Manifest[\"methods\"][number], { readonly _tag: \"token\" }> {\n return {\n _tag: \"token\",\n capabilities: [...capabilities],\n instructionsUrl: \"https://vercel.com/account/settings/tokens\",\n };\n}\n\nexport interface IntegrationMethodOptions {\n readonly capabilities: ProviderAuth.TokenValidation[\"capabilities\"];\n readonly slug: string;\n}\n\n/** Describes Vercel's provider-specific integration installation flow. */\nexport function integrationMethod(\n options: IntegrationMethodOptions,\n): ProviderAuth.IntegrationMethod {\n return {\n _tag: \"integration\",\n capabilities: [...options.capabilities],\n installUrl: `https://vercel.com/integrations/${encodeURIComponent(options.slug)}/new`,\n tokenEndpoint: \"https://api.vercel.com/v2/oauth/access_token\",\n };\n}\n\n/** Creates the Vercel token and integration authorization manifest. */\nexport function manifest(options: IntegrationMethodOptions): ProviderAuth.Manifest {\n return {\n methods: [tokenMethod(options.capabilities), integrationMethod(options)],\n providerId: \"vercel\",\n };\n}\n\nexport interface ExchangeCodeOptions {\n readonly baseUrl?: string;\n readonly clientId: string;\n readonly clientSecret: Secret.Value;\n readonly code: Secret.Value;\n readonly fetch?: Client.Fetch;\n readonly redirectUri: string;\n}\n\nexport interface IntegrationCredential {\n readonly accessToken: Secret.Value;\n readonly context: Client.AccountContext;\n readonly installationId: string | null;\n readonly userId: string;\n}\n\n/** Exchanges Vercel's one-time integration code and preserves its account context. */\nexport const exchangeCode = Effect.fn(\"VercelAuth.exchangeCode\")((options: ExchangeCodeOptions) =>\n Effect.gen(function* () {\n const fetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"https://api.vercel.com\").replace(/\\/$/, \"\");\n const body = new URLSearchParams({\n client_id: options.clientId,\n client_secret: options.clientSecret.expose(),\n code: options.code.expose(),\n redirect_uri: options.redirectUri,\n });\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(`${baseUrl}/v2/oauth/access_token`, {\n body,\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n method: \"POST\",\n }),\n catch: () => failure(\"exchangeCode\", \"Vercel token exchange failed\", \"transport\"),\n });\n const input = yield* Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () =>\n failure(\n \"exchangeCode\",\n response.ok\n ? \"Vercel returned a non-JSON token response\"\n : `Vercel token exchange failed with HTTP ${response.status}`,\n response.ok ? \"response\" : response.status === 401 ? \"authentication\" : \"request\",\n response.status,\n ),\n });\n if (!response.ok) {\n const detail = S.decodeUnknownOption(Protocol.ErrorEnvelope)(input);\n return yield* Effect.fail(\n failure(\n \"exchangeCode\",\n detail._tag === \"Some\"\n ? detail.value.error.message\n : `Vercel token exchange failed with HTTP ${response.status}`,\n response.status === 401 ? \"authentication\" : \"request\",\n response.status,\n detail._tag === \"Some\" ? detail.value.error.code : undefined,\n ),\n );\n }\n const token = yield* S.decodeUnknownEffect(Protocol.IntegrationToken)(input).pipe(\n Effect.mapError((cause) =>\n failure(\n \"exchangeCode\",\n `Vercel token response did not match its API contract: ${cause.message}`,\n \"response\",\n response.status,\n ),\n ),\n );\n return {\n accessToken: Secret.make(token.access_token),\n context:\n token.team_id === null\n ? ({ _tag: \"personal\" } as const)\n : ({ _tag: \"team\", teamId: token.team_id } as const),\n installationId: token.installation_id ?? null,\n userId: token.user_id,\n };\n }),\n);\n\nfunction failure(\n operation: string,\n message: string,\n reason: DnsProvider.ErrorReason,\n status?: number,\n code?: string,\n): DnsProvider.Error {\n return new DnsProvider.Error({\n ...(code === undefined ? {} : { code }),\n message,\n operation,\n providerId: \"vercel\",\n reason,\n ...(status === undefined ? {} : { status }),\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 * as DnsProvider from \"../../provider/provider.ts\";\nimport type * as Protocol from \"./protocol.ts\";\n\nexport type CreateBody = Readonly<Record<string, unknown>>;\n\nexport const decode = Effect.fn(\"VercelRecords.decode\")(\n (zone: DomainName.DomainName, record: Protocol.Record) =>\n Effect.gen(function* () {\n const absolute = absoluteNameCandidate(zone, record.name);\n const name = yield* DomainName.decode(absolute).pipe(\n Effect.match({ onFailure: () => null, onSuccess: (value) => value }),\n );\n if (name === null) return yield* decodeOpaque(record, absolute);\n const common = {\n metadata: {\n ownership: \"provider\",\n provenance: \"vercel\",\n purpose: \"existing DNS record\",\n },\n name,\n policy: record.type === \"CNAME\" ? \"exclusive\" : \"append\",\n ttl: record.ttl ?? 60,\n } as const;\n const fromRecord = (input: unknown) =>\n DnsRecord.decode(input).pipe(\n Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)),\n );\n\n switch (record.type) {\n case \"A\":\n case \"AAAA\":\n return yield* fromRecord({ ...common, _tag: record.type, address: record.value });\n case \"CNAME\":\n case \"NS\":\n return yield* fromRecord({ ...common, _tag: record.type, target: record.value });\n case \"TXT\":\n return yield* fromRecord({ ...common, _tag: \"TXT\", value: record.value });\n case \"MX\":\n return yield* fromRecord({\n ...common,\n _tag: \"MX\",\n exchange: record.value,\n priority: record.mxPriority ?? record.priority,\n });\n case \"CAA\": {\n const match = record.value.match(\n /^(\\d{1,3})\\s+(issue|issuewild|iodef)\\s+(?:\"((?:\\\\.|[^\"])*)\"|(\\S.*))$/,\n );\n if (match === null) {\n return yield* Effect.fail(\n failure(\"decodeRecord\", \"Vercel CAA record has an invalid value\"),\n );\n }\n return yield* fromRecord({\n ...common,\n _tag: \"CAA\",\n flags: Number(match[1]),\n tag: match[2],\n value: unescapeQuoted(match[3] ?? match[4] ?? \"\"),\n });\n }\n case \"SRV\": {\n const parts = record.value.trim().split(/\\s+/);\n const [priority, weight, port, target] =\n parts.length === 4\n ? parts\n : [String(record.priority ?? \"\"), parts[0], parts[1], parts[2]];\n return yield* fromRecord({\n ...common,\n _tag: \"SRV\",\n port: Number(port),\n priority: Number(priority),\n target,\n weight: Number(weight),\n });\n }\n default:\n return yield* decodeOpaque(record, name);\n }\n }),\n);\n\nconst decodeOpaque = Effect.fn(\"VercelRecords.decodeOpaque\")(\n (record: Protocol.Record, name: string) =>\n S.decodeUnknownEffect(DnsRecord.Opaque)({\n _tag: \"Opaque\",\n name,\n providerRecordId: record.id,\n providerType: record.type,\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message))),\n);\n\nexport function encode(zone: DomainName.DomainName, record: DnsRecord.DnsRecord): CreateBody {\n const common = {\n name: relativeName(zone, record.name),\n ...(record.ttl === null ? {} : { ttl: record.ttl }),\n type: record._tag,\n };\n switch (record._tag) {\n case \"A\":\n case \"AAAA\":\n return { ...common, value: record.address };\n case \"CNAME\":\n case \"NS\":\n return { ...common, value: record.target };\n case \"TXT\":\n return { ...common, value: record.value };\n case \"MX\":\n return { ...common, mxPriority: record.priority, value: record.exchange };\n case \"CAA\":\n return {\n ...common,\n value: `${record.flags} ${record.tag} \"${escapeQuoted(record.value)}\"`,\n };\n case \"SRV\":\n return {\n ...common,\n srv: {\n port: record.port,\n priority: record.priority,\n target: record.target,\n weight: record.weight,\n },\n };\n }\n}\n\nfunction absoluteNameCandidate(zone: DomainName.DomainName, name: string): string {\n return name === \"\" || name === \"@\"\n ? zone\n : name === zone || name.endsWith(`.${zone}`)\n ? name\n : `${name}.${zone}`;\n}\n\nfunction relativeName(zone: DomainName.DomainName, name: DomainName.DomainName): string {\n if (name === zone) return \"\";\n const suffix = `.${zone}`;\n if (!name.endsWith(suffix)) {\n throw failure(\"encodeRecord\", `DNS record ${name} is outside Vercel zone ${zone}`, {\n reason: \"request\",\n });\n }\n return name.slice(0, -suffix.length);\n}\n\nfunction escapeQuoted(value: string): string {\n return value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\nfunction unescapeQuoted(value: string): string {\n return value.replace(/\\\\([\\\\\"])/g, \"$1\");\n}\n\nfunction failure(\n operation: string,\n message: string,\n fields: Partial<Pick<DnsProvider.Error, \"reason\">> = {},\n): DnsProvider.Error {\n return new DnsProvider.Error({\n message,\n operation,\n providerId: \"vercel\",\n reason: fields.reason ?? \"response\",\n });\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport type * as ProviderAuth from \"../../auth/manifest.ts\";\nimport type * as Secret from \"../../auth/secret.ts\";\nimport * as DomainName from \"../../domain/domain-name.ts\";\nimport type * as DnsRecord from \"../../domain/dns-record.ts\";\nimport * as DnsProvider from \"../../provider/provider.ts\";\nimport * as Protocol from \"./protocol.ts\";\nimport * as Records from \"./records.ts\";\n\nexport type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\n/** Selects whether Vercel requests operate on a personal account or a team. */\nexport type AccountContext =\n | { readonly _tag: \"personal\" }\n | { readonly _tag: \"team\"; readonly teamId: string };\n\n/** Configuration for an Effect-native Vercel authoritative-DNS client. */\nexport interface Options {\n readonly baseUrl?: string;\n /** Capabilities the host required when issuing or authorizing this credential. */\n readonly capabilities: ProviderAuth.TokenValidation[\"capabilities\"];\n readonly context: AccountContext;\n readonly fetch?: Fetch;\n readonly token: Secret.Value;\n}\n\nexport interface ListZonesInput {\n readonly name?: DomainName.DomainName;\n}\n\n/** A Vercel account visible to the supplied credential. */\nexport interface Account {\n readonly id: string;\n readonly name: string;\n readonly type: \"personal\" | \"team\";\n}\n\n/** A Vercel-managed authoritative zone with normalized nameserver evidence. */\nexport interface Zone {\n readonly accountId: string;\n readonly id: string;\n readonly name: DomainName.DomainName;\n readonly nameservers: ReadonlyArray<DomainName.DomainName>;\n readonly status: \"active\" | \"pending\";\n}\n\nexport interface Interface extends DnsProvider.Interface {\n readonly listAccounts: () => Effect.Effect<ReadonlyArray<Account>, DnsProvider.Error>;\n readonly listZones: (\n input?: ListZonesInput,\n ) => Effect.Effect<ReadonlyArray<Zone>, DnsProvider.Error>;\n readonly validateToken: () => Effect.Effect<ProviderAuth.TokenValidation, DnsProvider.Error>;\n}\n\n/** Creates an Effect-native Vercel client without owning the credential lifecycle. */\nexport function make(options: Options): Interface {\n const fetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"https://api.vercel.com\").replace(/\\/$/, \"\");\n\n const withContext = (path: string, values: Readonly<Record<string, string>> = {}) => {\n const url = new URL(`${baseUrl}${path}`);\n for (const [key, value] of Object.entries(values)) url.searchParams.set(key, value);\n if (options.context._tag === \"team\") url.searchParams.set(\"teamId\", options.context.teamId);\n return url;\n };\n\n const request = Effect.fn(\"VercelClient.request\")(\n (url: URL, operation: string, init?: RequestInit) =>\n Effect.gen(function* () {\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(url, {\n ...init,\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${options.token.expose()}`,\n ...(init?.body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n ...init?.headers,\n },\n }),\n catch: () => failure(operation, \"Vercel request failed\", { reason: \"transport\" }),\n });\n const body = yield* Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () =>\n failure(\n operation,\n response.ok\n ? \"Vercel returned a non-JSON response\"\n : `Vercel request failed with HTTP ${response.status}`,\n {\n reason: response.ok ? \"response\" : reason(response.status),\n ...rateLimit(response),\n status: response.status,\n },\n ),\n });\n if (!response.ok) return yield* Effect.fail(apiFailure(body, operation, response));\n return { body, response } as const;\n }),\n );\n\n const allTeams = Effect.fn(\"VercelClient.allTeams\")(() =>\n Effect.gen(function* () {\n const teams: Array<Protocol.Team> = [];\n let until: number | null = null;\n while (true) {\n const url = new URL(`${baseUrl}/v2/teams`);\n url.searchParams.set(\"limit\", \"100\");\n if (until !== null) url.searchParams.set(\"until\", String(until));\n const { body, response } = yield* request(url, \"listAccounts\");\n const envelope = yield* decode(Protocol.TeamListEnvelope, body, \"listAccounts\", response);\n teams.push(...envelope.teams);\n if (envelope.pagination.next === null) return teams;\n until = envelope.pagination.next;\n }\n }),\n );\n\n const allDomains = Effect.fn(\"VercelClient.allDomains\")(() =>\n Effect.gen(function* () {\n const domains: Array<Protocol.Domain> = [];\n let until: number | null = null;\n while (true) {\n const values: Record<string, string> = { limit: \"100\" };\n if (until !== null) values.until = String(until);\n const { body, response } = yield* request(withContext(\"/v5/domains\", values), \"listZones\");\n const envelope = yield* decode(Protocol.DomainListEnvelope, body, \"listZones\", response);\n domains.push(...envelope.domains);\n if (envelope.pagination.next === null) return domains;\n until = envelope.pagination.next;\n }\n }),\n );\n\n const resolveZone = Effect.fn(\"VercelClient.resolveZone\")((name: DomainName.DomainName) =>\n Effect.gen(function* () {\n const configResult = yield* request(\n withContext(`/v6/domains/${encodeURIComponent(name)}/config`),\n \"resolveZone\",\n );\n const config = yield* decode(\n Protocol.DomainConfig,\n configResult.body,\n \"resolveZone\",\n configResult.response,\n );\n if (config.serviceType !== \"zeit.world\") {\n return yield* Effect.fail(\n failure(\n \"resolveZone\",\n `Vercel zone ${name} is not configured for authoritative DNS in the selected account`,\n { reason: \"not_found\" },\n ),\n );\n }\n const domainResult = yield* request(\n withContext(`/v5/domains/${encodeURIComponent(name)}`),\n \"resolveZone\",\n );\n const envelope = yield* decode(\n Protocol.DomainEnvelope,\n domainResult.body,\n \"resolveZone\",\n domainResult.response,\n );\n return yield* DomainName.decode(envelope.domain.name).pipe(\n Effect.mapError((cause) =>\n failure(\"resolveZone\", `Vercel returned an invalid storage zone: ${cause.message}`),\n ),\n );\n }),\n );\n\n const listRecords = Effect.fn(\"VercelClient.listRecords\")((zoneName: DomainName.DomainName) =>\n Effect.gen(function* () {\n const storageZone = yield* resolveZone(zoneName);\n const records: Array<DnsRecord.Observed> = [];\n let until: number | null = null;\n while (true) {\n const values: Record<string, string> = { limit: \"100\" };\n if (until !== null) values.until = String(until);\n const { body, response } = yield* request(\n withContext(`/v5/domains/${encodeURIComponent(storageZone)}/records`, values),\n \"listRecords\",\n );\n const envelope = yield* decode(Protocol.RecordListEnvelope, body, \"listRecords\", response);\n records.push(\n ...(yield* Effect.forEach(envelope.records, (record) =>\n Records.decode(storageZone, record),\n )),\n );\n const next = envelope.pagination?.next ?? null;\n if (next === null) {\n return records.filter(\n (record) => record.name === zoneName || record.name.endsWith(`.${zoneName}`),\n );\n }\n until = next;\n }\n }),\n );\n\n const createRecord = Effect.fn(\"VercelClient.createRecord\")(\n (zoneName: DomainName.DomainName, record: DnsRecord.DnsRecord) =>\n Effect.gen(function* () {\n const storageZone = yield* resolveZone(zoneName);\n const body = yield* Effect.try({\n try: () => Records.encode(storageZone, record),\n catch: (cause) =>\n cause instanceof DnsProvider.Error\n ? cause\n : failure(\"createRecord\", \"Vercel record could not be encoded\", {\n reason: \"request\",\n }),\n });\n const result = yield* request(\n withContext(`/v2/domains/${encodeURIComponent(storageZone)}/records`),\n \"createRecord\",\n { body: JSON.stringify(body), method: \"POST\" },\n );\n const envelope = yield* decode(\n Protocol.CreateRecordEnvelope,\n result.body,\n \"createRecord\",\n result.response,\n );\n return { providerRecordId: envelope.uid };\n }),\n );\n\n const listAccounts = Effect.fn(\"VercelClient.listAccounts\")(() =>\n Effect.gen(function* () {\n const userResult = yield* request(new URL(`${baseUrl}/v2/user`), \"listAccounts\");\n const { user } = yield* decode(\n Protocol.UserEnvelope,\n userResult.body,\n \"listAccounts\",\n userResult.response,\n );\n const teams = yield* allTeams();\n return [\n { id: user.id, name: user.name ?? user.username, type: \"personal\" as const },\n ...teams.map((team) => ({\n id: team.id,\n name: team.name ?? team.slug,\n type: \"team\" as const,\n })),\n ];\n }),\n );\n\n const listZones = Effect.fn(\"VercelClient.listZones\")((input: ListZonesInput = {}) =>\n Effect.gen(function* () {\n const domains = (yield* allDomains()).filter(\n (domain) =>\n domain.serviceType === \"zeit.world\" &&\n (input.name === undefined || domain.name === input.name),\n );\n return yield* Effect.forEach(domains, projectZone);\n }),\n );\n\n const validateToken = Effect.fn(\"VercelClient.validateToken\")(() =>\n Effect.gen(function* () {\n let accountId: string;\n if (options.context._tag === \"team\") {\n yield* allDomains();\n accountId = options.context.teamId;\n } else {\n const result = yield* request(new URL(`${baseUrl}/v2/user`), \"validateToken\");\n const { user } = yield* decode(\n Protocol.UserEnvelope,\n result.body,\n \"validateToken\",\n result.response,\n );\n accountId = user.id;\n }\n return {\n accountId,\n capabilities: options.capabilities,\n expiresAt: null,\n scopes: [],\n };\n }),\n );\n\n return {\n id: \"vercel\",\n createRecord,\n listAccounts,\n listRecords,\n listZones,\n validateToken,\n };\n}\n\nconst projectZone = Effect.fn(\"VercelClient.projectZone\")((domain: Protocol.Domain) =>\n Effect.gen(function* () {\n const name = yield* DomainName.decode(domain.name).pipe(\n Effect.mapError((cause) => failure(\"listZones\", cause.message, { reason: \"response\" })),\n );\n const nameservers = yield* Effect.forEach(domain.nameservers, (nameserver) =>\n DomainName.decode(nameserver).pipe(\n Effect.mapError((cause) => failure(\"listZones\", cause.message, { reason: \"response\" })),\n ),\n );\n return {\n accountId: domain.teamId ?? domain.userId,\n id: domain.id,\n name,\n nameservers,\n status: domain.verified ? \"active\" : \"pending\",\n } as const;\n }),\n);\n\nfunction decode<A>(\n schema: S.ConstraintCodec<A, unknown, never, unknown>,\n input: unknown,\n operation: string,\n response: Response,\n): Effect.Effect<A, DnsProvider.Error> {\n return S.decodeUnknownEffect(schema)(input).pipe(\n Effect.mapError((cause) =>\n failure(operation, `Vercel response did not match its API contract: ${cause.message}`, {\n reason: \"response\",\n status: response.status,\n }),\n ),\n );\n}\n\nfunction apiFailure(input: unknown, operation: string, response: Response): DnsProvider.Error {\n const detail = S.decodeUnknownOption(Protocol.ErrorEnvelope)(input);\n return failure(\n operation,\n detail._tag === \"Some\"\n ? detail.value.error.message\n : `Vercel request failed with HTTP ${response.status}`,\n {\n ...(detail._tag === \"Some\" ? { code: detail.value.error.code } : {}),\n reason: reason(response.status, detail._tag === \"Some\" ? detail.value.error.code : undefined),\n ...rateLimit(response, detail._tag === \"Some\" ? detail.value.error : undefined),\n status: response.status,\n },\n );\n}\n\nfunction reason(status: number, code?: string): DnsProvider.ErrorReason {\n if (status === 401 || code === \"invalid_token\") return \"authentication\";\n if (status === 403) return \"authorization\";\n if (status === 404 || code === \"not_found\") return \"not_found\";\n if (status === 409 || code === \"conflict\") return \"conflict\";\n if (status === 429 || code === \"rate_limited\") return \"rate_limit\";\n if (status >= 500) return \"response\";\n return \"request\";\n}\n\nfunction rateLimit(\n response: Response,\n detail?: Protocol.ErrorDetail,\n): Partial<Pick<DnsProvider.Error, \"retryAfterMs\">> {\n const resetMs = detail?.limit?.resetMs;\n const header = response.headers.get(\"x-ratelimit-reset\");\n const reset = resetMs ?? (header === null ? undefined : Number(header) * 1_000);\n return reset === undefined || !Number.isFinite(reset)\n ? {}\n : { retryAfterMs: Math.max(0, reset - Date.now()) };\n}\n\nfunction failure(\n operation: string,\n message: string,\n fields: Partial<Pick<DnsProvider.Error, \"code\" | \"reason\" | \"retryAfterMs\" | \"status\">> = {},\n): DnsProvider.Error {\n return new DnsProvider.Error({ ...fields, message, operation, providerId: \"vercel\" });\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"dns-record-Dzo4flM5.mjs","names":["Error","Type","S","Schema","decode","InvalidInputError","parse","Error","S","DomainName.Schema","Schema","InvalidInputError"],"sources":["../src/invalid-input.ts","../src/domain/domain-name.ts","../src/provider/provider.ts","../src/domain/dns-record.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 { 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 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 listRecords: (zone: DomainName.DomainName) => Promise<ReadonlyArray<DnsRecord.Observed>>;\n}\n\nexport const layerFromAsync = (provider: AsyncInterface): Layer.Layer<Service> =>\n Layer.succeed(Service, {\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 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 toAsync = (provider: Interface): AsyncInterface => ({\n id: provider.id,\n createRecord: (zone, record) => Effect.runPromise(provider.createRecord(zone, record)),\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 { 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"],"mappings":"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"}