domainkit 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/{auth-B4jq3yk3.mjs → auth-BR-19zj-.mjs} +2 -2
- package/dist/{auth-B4jq3yk3.mjs.map → auth-BR-19zj-.mjs.map} +1 -1
- package/dist/{auth-6-KRy1gN.mjs → auth-g-waCHcz.mjs} +2 -2
- package/dist/{auth-6-KRy1gN.mjs.map → auth-g-waCHcz.mjs.map} +1 -1
- package/dist/{authorization-CQSKKMrW.mjs → authorization-OeaSR47S.mjs} +31 -2
- package/dist/authorization-OeaSR47S.mjs.map +1 -0
- package/dist/{cloudflare-FDl5q7Dm.d.mts → cloudflare-BrZPU9li.d.mts} +4 -4
- package/dist/{cloudflare-Bg_p-M2c.mjs → cloudflare-CGmasR8A.mjs} +3 -3
- package/dist/{cloudflare-Bg_p-M2c.mjs.map → cloudflare-CGmasR8A.mjs.map} +1 -1
- package/dist/cloudflare.d.mts +2 -2
- package/dist/cloudflare.mjs +1 -1
- package/dist/{connection-CEqadXSm.d.mts → connection-BfkloPZy.d.mts} +8 -4
- package/dist/{connection-X3rZhrBZ.mjs → connection-BwtOwpH6.mjs} +12 -3
- package/dist/connection-BwtOwpH6.mjs.map +1 -0
- package/dist/{connection-BXoSrhZs.mjs → connection-CjNQe_E-.mjs} +2 -2
- package/dist/{connection-BXoSrhZs.mjs.map → connection-CjNQe_E-.mjs.map} +1 -1
- package/dist/connection-api-DNuEZ_jR.d.mts +7 -0
- package/dist/effect-cloudflare.d.mts +1 -1
- package/dist/effect-cloudflare.mjs +1 -1
- package/dist/effect-vercel.d.mts +1 -1
- package/dist/effect-vercel.mjs +1 -1
- package/dist/effect.d.mts +6 -6
- package/dist/effect.mjs +6 -5
- package/dist/effect.mjs.map +1 -1
- package/dist/{index-B1opsgls.d.mts → index-BHWRTThN.d.mts} +2 -2
- package/dist/{index-Ewc__bQu.d.mts → index-D3PVknwE.d.mts} +2 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +5 -5
- package/dist/{resolver-BbVzTbCX.d.mts → resolver-Dc0hwV-J.d.mts} +2 -2
- package/dist/testing.d.mts +2 -2
- package/dist/{vercel-DgJaUX9D.d.mts → vercel-BsNDu4Np.d.mts} +4 -4
- package/dist/{vercel-BIFpZRPu.mjs → vercel-CfoJaaCu.mjs} +3 -3
- package/dist/{vercel-BIFpZRPu.mjs.map → vercel-CfoJaaCu.mjs.map} +1 -1
- package/dist/vercel.d.mts +2 -2
- package/dist/vercel.mjs +1 -1
- package/dist/{verify-Q5RYpnuw.mjs → verify-BKbvq7IN.mjs} +3 -3
- package/dist/{verify-Q5RYpnuw.mjs.map → verify-BKbvq7IN.mjs.map} +1 -1
- package/dist/{verify-7_EbKbFM.d.mts → verify-Dls29YC-.d.mts} +3 -3
- package/dist/{zone-discovery-BA5I24vu.d.mts → zone-discovery-BPnH3sLU.d.mts} +9 -2
- package/package.json +1 -1
- package/dist/authorization-CQSKKMrW.mjs.map +0 -1
- package/dist/connection-X3rZhrBZ.mjs.map +0 -1
- package/dist/connection-api-DftK7eHo.d.mts +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-Q5RYpnuw.mjs","names":["S","Schema","InvalidInputError","DomainName.Schema","DomainName.parse","Zones.candidates","Connection.authorizationError","Connection.assertGrant","Connection.AuthorizationError","InvalidInputError","Connection.authorizationError","Provisioning.authorize","DomainName.parse","InvalidInputError","make","DnsResolver.Error","layer","DnsResolver.Service","toAsync","DnsResolver.toAsync","DomainName.parse","DomainName.decode","DnsData.parse","endpoint","make","DnsOverHttps.make","layer","DnsResolver.Service","toAsync","DnsResolver.toAsync","make","DnsOverHttps.make","DnsResolver.Service","DnsResolver.toAsync","observe","CloudflareDnsOverHttps.make","GoogleDnsOverHttps.make","DnsProvider.Service","DnsRecord.equals","InvalidInputError","DnsResolverPool.Service","DnsResolverPool.defaultMake","DnsData.parse","data","DnsRecord.data"],"sources":["../package.json","../src/auth/diagnostic.ts","../src/auth/manifest.ts","../src/discovery/selection.ts","../src/plan/connection-authorization.ts","../src/verification/dns-data.ts","../src/verification/doh.ts","../src/verification/cloudflare-doh.ts","../src/verification/google-doh.ts","../src/verification/resolver-pool.ts","../src/verification/verify.ts"],"sourcesContent":["","import { Schema } from \"effect\";\n\nexport const Category = Schema.Literals([\n \"authorization\",\n \"configuration\",\n \"provider\",\n \"storage\",\n \"validation\",\n]);\nexport type Category = typeof Category.Type;\n\nexport const RetryAdvice = Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]);\nexport type RetryAdvice = typeof RetryAdvice.Type;\n\nexport const Fields = {\n category: Category,\n message: Schema.String,\n operation: Schema.String,\n retry: RetryAdvice,\n} as const;\n\nexport interface Diagnostic {\n readonly category: Category;\n readonly message: string;\n readonly operation: string;\n readonly retry: RetryAdvice;\n readonly tag: string;\n}\n\nexport function from(error: {\n readonly _tag: string;\n readonly category: Category;\n readonly message: string;\n readonly operation: string;\n readonly retry: RetryAdvice;\n}): Diagnostic {\n return {\n category: error.category,\n message: error.message,\n operation: error.operation,\n retry: error.retry,\n tag: error._tag,\n };\n}\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 { 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.providerAccountId === input.explicit.accountId &&\n DomainName.parse(connected.zone) === explicitZone,\n );\n if (index < 0) {\n throw Connection.authorizationError(\n \"Explicit provider zone is not connected or granted\",\n \"ProviderDiscovery.select\",\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.providerAccountId,\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 { 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 : Connection.authorizationError(\n \"Connection grant is invalid\",\n \"ConnectionAuthorization.authorize\",\n ),\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* Connection.authorizationError(\n `Plan operations are outside the granted domain ${domain}`,\n \"ConnectionAuthorization.authorize\",\n );\n }\n return authorization;\n});\n\nexport type Error = Connection.AuthorizationError | InvalidInputError | CryptoError;\nexport type Requirements = 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 { Layer } from \"effect\";\n\nimport * as DnsOverHttps from \"./doh.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\n\nconst endpoint = \"https://dns.google/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 { Context, Data, Effect, Layer, Schema } from \"effect\";\n\nimport * as CloudflareDnsOverHttps from \"./cloudflare-doh.ts\";\nimport * as DnsOverHttps from \"./doh.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\nimport * as GoogleDnsOverHttps from \"./google-doh.ts\";\n\nexport interface Entry {\n readonly id: string;\n readonly resolver: DnsResolver.Interface;\n readonly timeoutMs?: number;\n}\n\nexport type Observation = Data.TaggedEnum<{\n Answer: { readonly answers: ReadonlyArray<DnsResolver.Answer>; readonly resolverId: string };\n Failed: {\n readonly message: string;\n readonly reason: Exclude<DnsResolver.Error[\"reason\"], \"timeout\">;\n readonly resolverId: string;\n };\n NoData: { readonly resolverId: string };\n TimedOut: { readonly resolverId: string; readonly timeoutMs: number };\n}>;\nexport const Observation = Data.taggedEnum<Observation>();\n\nexport type Policy = Data.TaggedEnum<{\n AllMatch: {};\n AnyMatch: {};\n Quorum: { readonly minimum: number };\n}>;\nconst PolicyVariants = Data.taggedEnum<Policy>();\nconst QuorumMinimum = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));\nconst PolicySchema = Schema.TaggedUnion({\n AllMatch: {},\n AnyMatch: {},\n Quorum: { minimum: QuorumMinimum },\n});\nexport const Policy = {\n AllMatch: PolicyVariants.AllMatch,\n AnyMatch: PolicyVariants.AnyMatch,\n Quorum: ({ minimum }: { readonly minimum: number }): Policy =>\n PolicyVariants.Quorum({ minimum: Schema.decodeUnknownSync(QuorumMinimum)(minimum) }),\n Schema: PolicySchema,\n};\n\nexport interface Interface {\n readonly observe: (query: DnsResolver.Query) => Effect.Effect<ReadonlyArray<Observation>>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@domainkit/DnsResolverPool\") {}\n\nexport function make(entries: ReadonlyArray<Entry>): Interface {\n return Service.of({\n observe: Effect.fn(\"DnsResolverPool.observe\")((query) =>\n Effect.forEach(entries, (entry) => observe(entry, query), { concurrency: \"unbounded\" }),\n ),\n });\n}\n\nexport interface DefaultOptions extends Omit<DnsOverHttps.Options, \"endpoint\"> {}\n\n/** Cloudflare and Google RFC wire-format DoH resolvers. */\nexport function defaultMake(options: DefaultOptions = {}): Interface {\n const timeoutMs = options.timeoutMs ?? 5_000;\n return make([\n {\n id: \"cloudflare\",\n resolver: CloudflareDnsOverHttps.make(options),\n timeoutMs,\n },\n { id: \"google\", resolver: GoogleDnsOverHttps.make(options), timeoutMs },\n ]);\n}\n\nexport const defaultLayer = (options: DefaultOptions = {}): Layer.Layer<Service> =>\n Layer.succeed(Service, defaultMake(options));\n\nfunction observe(entry: Entry, query: DnsResolver.Query): Effect.Effect<Observation> {\n const timeoutMs = entry.timeoutMs ?? 5_000;\n return entry.resolver.resolve(query).pipe(\n Effect.timeout(timeoutMs),\n Effect.match({\n onFailure: (failure): Observation => {\n if (\n failure._tag === \"TimeoutError\" ||\n (failure._tag === \"ResolverError\" && failure.reason === \"timeout\")\n ) {\n return Observation.TimedOut({ resolverId: entry.id, timeoutMs });\n }\n return Observation.Failed({\n message: failure.message,\n reason: failure.reason === \"response\" ? \"response\" : \"transport\",\n resolverId: entry.id,\n });\n },\n onSuccess: (resolution): Observation =>\n resolution._tag === \"nodata\"\n ? Observation.NoData({ resolverId: entry.id })\n : Observation.Answer({ answers: resolution.answers, resolverId: entry.id }),\n }),\n );\n}\n","import { Data, Effect, Option, Schema } from \"effect\";\n\nimport type * 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 * as DnsData from \"./dns-data.ts\";\nimport * as DnsResolverPool from \"./resolver-pool.ts\";\n\nexport type PublicDns = Data.TaggedEnum<{\n Disabled: {};\n Enabled: { readonly policy?: DnsResolverPool.Policy };\n}>;\nexport const PublicDns = Data.taggedEnum<PublicDns>();\n\nexport type Provider = Data.TaggedEnum<{\n Disabled: {};\n Enabled: { readonly zone: DomainName.DomainName };\n}>;\nexport const Provider = Data.taggedEnum<Provider>();\n\ntype ProviderEnabled = Extract<Provider, { readonly _tag: \"Enabled\" }>;\ntype ProviderDisabled = Extract<Provider, { readonly _tag: \"Disabled\" }>;\n\nexport interface PublicOnlyConfig {\n readonly provider?: ProviderDisabled;\n readonly publicDns?: PublicDns;\n readonly record: DnsRecord.DnsRecord;\n}\n\nexport interface ProviderConfig {\n readonly provider: ProviderEnabled;\n readonly publicDns?: PublicDns;\n readonly record: DnsRecord.DnsRecord;\n}\n\nexport type Config = ProviderConfig | PublicOnlyConfig;\n\nexport type ProviderObservation = Data.TaggedEnum<{\n Matched: {};\n Mismatch: { readonly records: ReadonlyArray<DnsRecord.DnsRecord> };\n Pending: {};\n Unavailable: { readonly message: string };\n}>;\nexport const ProviderObservation = Data.taggedEnum<ProviderObservation>();\n\nexport type PublicDnsObservation = Data.TaggedEnum<{\n Verified: {\n readonly evidence: ReadonlyArray<DnsResolverPool.Observation>;\n readonly matchedResolverIds: ReadonlyArray<string>;\n };\n Mismatch: { readonly evidence: ReadonlyArray<DnsResolverPool.Observation> };\n Pending: { readonly evidence: ReadonlyArray<DnsResolverPool.Observation> };\n Unavailable: { readonly evidence: ReadonlyArray<DnsResolverPool.Observation> };\n}>;\nexport const PublicDnsObservation = Data.taggedEnum<PublicDnsObservation>();\n\ninterface Evidence {\n readonly provider: ProviderObservation | null;\n readonly publicDns: PublicDnsObservation | null;\n}\n\nexport type Result = Data.TaggedEnum<{\n Mismatch: Evidence;\n NotObserved: Evidence;\n Pending: Evidence;\n Unavailable: Evidence;\n Verified: Evidence;\n}>;\nexport const Result = Data.taggedEnum<Result>();\n\nexport function observe(input: PublicOnlyConfig): Effect.Effect<Result, InvalidInputError>;\nexport function observe(\n input: ProviderConfig,\n): Effect.Effect<Result, InvalidInputError, DnsProvider.Service>;\nexport function observe(\n input: Config,\n): Effect.Effect<Result, InvalidInputError, DnsProvider.Service>;\nexport function observe(\n input: Config,\n): Effect.Effect<Result, InvalidInputError, DnsProvider.Service> {\n return observeEffect(input);\n}\n\nconst observeEffect = Effect.fn(\"Verification.observe\")(function* (input: Config) {\n const publicDns = input.publicDns ?? PublicDns.Enabled({});\n const provider = input.provider ?? Provider.Disabled();\n const publicEffect =\n publicDns._tag === \"Disabled\"\n ? Effect.succeed<PublicDnsObservation | null>(null)\n : observePublicDns(input.record, publicDns.policy ?? DnsResolverPool.Policy.AnyMatch());\n const providerEffect =\n provider._tag === \"Disabled\"\n ? Effect.succeed<ProviderObservation | null>(null)\n : Effect.flatMap(DnsProvider.Service, (service) =>\n observeProvider(service, provider.zone, input.record).pipe(\n Effect.catch((failure) =>\n Effect.succeed<ProviderObservation>(\n ProviderObservation.Unavailable({ message: failure.message }),\n ),\n ),\n ),\n );\n const [providerObservation, publicDnsObservation] = yield* Effect.all(\n [providerEffect, publicEffect] as const,\n { concurrency: \"unbounded\" },\n );\n return aggregate({ provider: providerObservation, publicDns: publicDnsObservation });\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 ProviderObservation.Matched();\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\n ? ProviderObservation.Pending()\n : ProviderObservation.Mismatch({ records: sameSet });\n }),\n );\n}\n\nfunction observePublicDns(\n requirement: DnsRecord.DnsRecord,\n policy: DnsResolverPool.Policy,\n): Effect.Effect<PublicDnsObservation, InvalidInputError> {\n return Effect.gen(function* () {\n const validatedPolicy = yield* Schema.decodeUnknownEffect(DnsResolverPool.Policy.Schema)(\n policy,\n ).pipe(Effect.mapError((cause) => new InvalidInputError({ message: cause.message })));\n const configuredPool = yield* Effect.serviceOption(DnsResolverPool.Service);\n const pool = Option.getOrElse(configuredPool, () => DnsResolverPool.defaultMake());\n const evidence = yield* pool.observe({ name: requirement.name, type: requirement._tag });\n if (validatedPolicy._tag === \"Quorum\" && validatedPolicy.minimum > evidence.length) {\n return yield* new InvalidInputError({\n message: `Quorum minimum ${validatedPolicy.minimum} exceeds the ${evidence.length} configured resolvers`,\n });\n }\n return evaluatePublicDns(requirement, validatedPolicy, evidence);\n });\n}\n\nfunction evaluatePublicDns(\n requirement: DnsRecord.DnsRecord,\n policy: DnsResolverPool.Policy,\n evidence: ReadonlyArray<DnsResolverPool.Observation>,\n): PublicDnsObservation {\n const matchedResolverIds = evidence.flatMap((observation) =>\n observation._tag === \"Answer\" && answersMatch(requirement, observation.answers)\n ? [observation.resolverId]\n : [],\n );\n const required =\n policy._tag === \"AnyMatch\" ? 1 : policy._tag === \"AllMatch\" ? evidence.length : policy.minimum;\n if (required > 0 && matchedResolverIds.length >= required) {\n return PublicDnsObservation.Verified({ evidence, matchedResolverIds });\n }\n const unavailable = evidence.filter(\n (observation) => observation._tag === \"TimedOut\" || observation._tag === \"Failed\",\n ).length;\n if (unavailable > 0 && matchedResolverIds.length + unavailable >= required) {\n return PublicDnsObservation.Unavailable({ evidence });\n }\n if (\n evidence.some(\n (observation) =>\n observation._tag === \"Answer\" && !answersMatch(requirement, observation.answers),\n )\n ) {\n return PublicDnsObservation.Mismatch({ evidence });\n }\n if (evidence.some((observation) => observation._tag === \"NoData\")) {\n return PublicDnsObservation.Pending({ evidence });\n }\n return PublicDnsObservation.Unavailable({ evidence });\n}\n\nfunction answersMatch(\n requirement: DnsRecord.DnsRecord,\n answers: ReadonlyArray<{ readonly data: string; readonly name: string; readonly type: string }>,\n): boolean {\n const expected = DnsData.parse(requirement._tag, recordValue(requirement));\n return answers.some(\n (answer) =>\n answer.name === requirement.name &&\n answer.type === requirement._tag &&\n DnsData.parse(requirement._tag, answer.data) === expected,\n );\n}\n\nfunction aggregate(evidence: Evidence): Result {\n const requested = [evidence.provider, evidence.publicDns].filter(\n (observation): observation is ProviderObservation | PublicDnsObservation =>\n observation !== null,\n );\n if (requested.length === 0) return Result.NotObserved(evidence);\n if (\n requested.every(\n (observation) => observation._tag === \"Matched\" || observation._tag === \"Verified\",\n )\n ) {\n return Result.Verified(evidence);\n }\n if (requested.some((observation) => observation._tag === \"Unavailable\")) {\n return Result.Unavailable(evidence);\n }\n if (requested.some((observation) => observation._tag === \"Mismatch\")) {\n return Result.Mismatch(evidence);\n }\n return Result.Pending(evidence);\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":"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"}
|
|
1
|
+
{"version":3,"file":"verify-BKbvq7IN.mjs","names":["S","Schema","InvalidInputError","DomainName.Schema","DomainName.parse","Zones.candidates","Connection.authorizationError","Connection.assertGrant","Connection.AuthorizationError","InvalidInputError","Connection.authorizationError","Provisioning.authorize","DomainName.parse","InvalidInputError","make","DnsResolver.Error","layer","DnsResolver.Service","toAsync","DnsResolver.toAsync","DomainName.parse","DomainName.decode","DnsData.parse","endpoint","make","DnsOverHttps.make","layer","DnsResolver.Service","toAsync","DnsResolver.toAsync","make","DnsOverHttps.make","DnsResolver.Service","DnsResolver.toAsync","observe","CloudflareDnsOverHttps.make","GoogleDnsOverHttps.make","DnsProvider.Service","DnsRecord.equals","InvalidInputError","DnsResolverPool.Service","DnsResolverPool.defaultMake","DnsData.parse","data","DnsRecord.data"],"sources":["../package.json","../src/auth/diagnostic.ts","../src/auth/manifest.ts","../src/discovery/selection.ts","../src/plan/connection-authorization.ts","../src/verification/dns-data.ts","../src/verification/doh.ts","../src/verification/cloudflare-doh.ts","../src/verification/google-doh.ts","../src/verification/resolver-pool.ts","../src/verification/verify.ts"],"sourcesContent":["","import { Schema } from \"effect\";\n\nexport const Category = Schema.Literals([\n \"authorization\",\n \"configuration\",\n \"provider\",\n \"storage\",\n \"validation\",\n]);\nexport type Category = typeof Category.Type;\n\nexport const RetryAdvice = Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]);\nexport type RetryAdvice = typeof RetryAdvice.Type;\n\nexport const Fields = {\n category: Category,\n message: Schema.String,\n operation: Schema.String,\n retry: RetryAdvice,\n} as const;\n\nexport interface Diagnostic {\n readonly category: Category;\n readonly message: string;\n readonly operation: string;\n readonly retry: RetryAdvice;\n readonly tag: string;\n}\n\nexport function from(error: {\n readonly _tag: string;\n readonly category: Category;\n readonly message: string;\n readonly operation: string;\n readonly retry: RetryAdvice;\n}): Diagnostic {\n return {\n category: error.category,\n message: error.message,\n operation: error.operation,\n retry: error.retry,\n tag: error._tag,\n };\n}\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 { 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.providerAccountId === input.explicit.accountId &&\n DomainName.parse(connected.zone) === explicitZone,\n );\n if (index < 0) {\n throw Connection.authorizationError(\n \"Explicit provider zone is not connected or granted\",\n \"ProviderDiscovery.select\",\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.providerAccountId,\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 { 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 : Connection.authorizationError(\n \"Connection grant is invalid\",\n \"ConnectionAuthorization.authorize\",\n ),\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* Connection.authorizationError(\n `Plan operations are outside the granted domain ${domain}`,\n \"ConnectionAuthorization.authorize\",\n );\n }\n return authorization;\n});\n\nexport type Error = Connection.AuthorizationError | InvalidInputError | CryptoError;\nexport type Requirements = 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 { Layer } from \"effect\";\n\nimport * as DnsOverHttps from \"./doh.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\n\nconst endpoint = \"https://dns.google/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 { Context, Data, Effect, Layer, Schema } from \"effect\";\n\nimport * as CloudflareDnsOverHttps from \"./cloudflare-doh.ts\";\nimport * as DnsOverHttps from \"./doh.ts\";\nimport * as DnsResolver from \"./resolver.ts\";\nimport * as GoogleDnsOverHttps from \"./google-doh.ts\";\n\nexport interface Entry {\n readonly id: string;\n readonly resolver: DnsResolver.Interface;\n readonly timeoutMs?: number;\n}\n\nexport type Observation = Data.TaggedEnum<{\n Answer: { readonly answers: ReadonlyArray<DnsResolver.Answer>; readonly resolverId: string };\n Failed: {\n readonly message: string;\n readonly reason: Exclude<DnsResolver.Error[\"reason\"], \"timeout\">;\n readonly resolverId: string;\n };\n NoData: { readonly resolverId: string };\n TimedOut: { readonly resolverId: string; readonly timeoutMs: number };\n}>;\nexport const Observation = Data.taggedEnum<Observation>();\n\nexport type Policy = Data.TaggedEnum<{\n AllMatch: {};\n AnyMatch: {};\n Quorum: { readonly minimum: number };\n}>;\nconst PolicyVariants = Data.taggedEnum<Policy>();\nconst QuorumMinimum = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));\nconst PolicySchema = Schema.TaggedUnion({\n AllMatch: {},\n AnyMatch: {},\n Quorum: { minimum: QuorumMinimum },\n});\nexport const Policy = {\n AllMatch: PolicyVariants.AllMatch,\n AnyMatch: PolicyVariants.AnyMatch,\n Quorum: ({ minimum }: { readonly minimum: number }): Policy =>\n PolicyVariants.Quorum({ minimum: Schema.decodeUnknownSync(QuorumMinimum)(minimum) }),\n Schema: PolicySchema,\n};\n\nexport interface Interface {\n readonly observe: (query: DnsResolver.Query) => Effect.Effect<ReadonlyArray<Observation>>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@domainkit/DnsResolverPool\") {}\n\nexport function make(entries: ReadonlyArray<Entry>): Interface {\n return Service.of({\n observe: Effect.fn(\"DnsResolverPool.observe\")((query) =>\n Effect.forEach(entries, (entry) => observe(entry, query), { concurrency: \"unbounded\" }),\n ),\n });\n}\n\nexport interface DefaultOptions extends Omit<DnsOverHttps.Options, \"endpoint\"> {}\n\n/** Cloudflare and Google RFC wire-format DoH resolvers. */\nexport function defaultMake(options: DefaultOptions = {}): Interface {\n const timeoutMs = options.timeoutMs ?? 5_000;\n return make([\n {\n id: \"cloudflare\",\n resolver: CloudflareDnsOverHttps.make(options),\n timeoutMs,\n },\n { id: \"google\", resolver: GoogleDnsOverHttps.make(options), timeoutMs },\n ]);\n}\n\nexport const defaultLayer = (options: DefaultOptions = {}): Layer.Layer<Service> =>\n Layer.succeed(Service, defaultMake(options));\n\nfunction observe(entry: Entry, query: DnsResolver.Query): Effect.Effect<Observation> {\n const timeoutMs = entry.timeoutMs ?? 5_000;\n return entry.resolver.resolve(query).pipe(\n Effect.timeout(timeoutMs),\n Effect.match({\n onFailure: (failure): Observation => {\n if (\n failure._tag === \"TimeoutError\" ||\n (failure._tag === \"ResolverError\" && failure.reason === \"timeout\")\n ) {\n return Observation.TimedOut({ resolverId: entry.id, timeoutMs });\n }\n return Observation.Failed({\n message: failure.message,\n reason: failure.reason === \"response\" ? \"response\" : \"transport\",\n resolverId: entry.id,\n });\n },\n onSuccess: (resolution): Observation =>\n resolution._tag === \"nodata\"\n ? Observation.NoData({ resolverId: entry.id })\n : Observation.Answer({ answers: resolution.answers, resolverId: entry.id }),\n }),\n );\n}\n","import { Data, Effect, Option, Schema } from \"effect\";\n\nimport type * 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 * as DnsData from \"./dns-data.ts\";\nimport * as DnsResolverPool from \"./resolver-pool.ts\";\n\nexport type PublicDns = Data.TaggedEnum<{\n Disabled: {};\n Enabled: { readonly policy?: DnsResolverPool.Policy };\n}>;\nexport const PublicDns = Data.taggedEnum<PublicDns>();\n\nexport type Provider = Data.TaggedEnum<{\n Disabled: {};\n Enabled: { readonly zone: DomainName.DomainName };\n}>;\nexport const Provider = Data.taggedEnum<Provider>();\n\ntype ProviderEnabled = Extract<Provider, { readonly _tag: \"Enabled\" }>;\ntype ProviderDisabled = Extract<Provider, { readonly _tag: \"Disabled\" }>;\n\nexport interface PublicOnlyConfig {\n readonly provider?: ProviderDisabled;\n readonly publicDns?: PublicDns;\n readonly record: DnsRecord.DnsRecord;\n}\n\nexport interface ProviderConfig {\n readonly provider: ProviderEnabled;\n readonly publicDns?: PublicDns;\n readonly record: DnsRecord.DnsRecord;\n}\n\nexport type Config = ProviderConfig | PublicOnlyConfig;\n\nexport type ProviderObservation = Data.TaggedEnum<{\n Matched: {};\n Mismatch: { readonly records: ReadonlyArray<DnsRecord.DnsRecord> };\n Pending: {};\n Unavailable: { readonly message: string };\n}>;\nexport const ProviderObservation = Data.taggedEnum<ProviderObservation>();\n\nexport type PublicDnsObservation = Data.TaggedEnum<{\n Verified: {\n readonly evidence: ReadonlyArray<DnsResolverPool.Observation>;\n readonly matchedResolverIds: ReadonlyArray<string>;\n };\n Mismatch: { readonly evidence: ReadonlyArray<DnsResolverPool.Observation> };\n Pending: { readonly evidence: ReadonlyArray<DnsResolverPool.Observation> };\n Unavailable: { readonly evidence: ReadonlyArray<DnsResolverPool.Observation> };\n}>;\nexport const PublicDnsObservation = Data.taggedEnum<PublicDnsObservation>();\n\ninterface Evidence {\n readonly provider: ProviderObservation | null;\n readonly publicDns: PublicDnsObservation | null;\n}\n\nexport type Result = Data.TaggedEnum<{\n Mismatch: Evidence;\n NotObserved: Evidence;\n Pending: Evidence;\n Unavailable: Evidence;\n Verified: Evidence;\n}>;\nexport const Result = Data.taggedEnum<Result>();\n\nexport function observe(input: PublicOnlyConfig): Effect.Effect<Result, InvalidInputError>;\nexport function observe(\n input: ProviderConfig,\n): Effect.Effect<Result, InvalidInputError, DnsProvider.Service>;\nexport function observe(\n input: Config,\n): Effect.Effect<Result, InvalidInputError, DnsProvider.Service>;\nexport function observe(\n input: Config,\n): Effect.Effect<Result, InvalidInputError, DnsProvider.Service> {\n return observeEffect(input);\n}\n\nconst observeEffect = Effect.fn(\"Verification.observe\")(function* (input: Config) {\n const publicDns = input.publicDns ?? PublicDns.Enabled({});\n const provider = input.provider ?? Provider.Disabled();\n const publicEffect =\n publicDns._tag === \"Disabled\"\n ? Effect.succeed<PublicDnsObservation | null>(null)\n : observePublicDns(input.record, publicDns.policy ?? DnsResolverPool.Policy.AnyMatch());\n const providerEffect =\n provider._tag === \"Disabled\"\n ? Effect.succeed<ProviderObservation | null>(null)\n : Effect.flatMap(DnsProvider.Service, (service) =>\n observeProvider(service, provider.zone, input.record).pipe(\n Effect.catch((failure) =>\n Effect.succeed<ProviderObservation>(\n ProviderObservation.Unavailable({ message: failure.message }),\n ),\n ),\n ),\n );\n const [providerObservation, publicDnsObservation] = yield* Effect.all(\n [providerEffect, publicEffect] as const,\n { concurrency: \"unbounded\" },\n );\n return aggregate({ provider: providerObservation, publicDns: publicDnsObservation });\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 ProviderObservation.Matched();\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\n ? ProviderObservation.Pending()\n : ProviderObservation.Mismatch({ records: sameSet });\n }),\n );\n}\n\nfunction observePublicDns(\n requirement: DnsRecord.DnsRecord,\n policy: DnsResolverPool.Policy,\n): Effect.Effect<PublicDnsObservation, InvalidInputError> {\n return Effect.gen(function* () {\n const validatedPolicy = yield* Schema.decodeUnknownEffect(DnsResolverPool.Policy.Schema)(\n policy,\n ).pipe(Effect.mapError((cause) => new InvalidInputError({ message: cause.message })));\n const configuredPool = yield* Effect.serviceOption(DnsResolverPool.Service);\n const pool = Option.getOrElse(configuredPool, () => DnsResolverPool.defaultMake());\n const evidence = yield* pool.observe({ name: requirement.name, type: requirement._tag });\n if (validatedPolicy._tag === \"Quorum\" && validatedPolicy.minimum > evidence.length) {\n return yield* new InvalidInputError({\n message: `Quorum minimum ${validatedPolicy.minimum} exceeds the ${evidence.length} configured resolvers`,\n });\n }\n return evaluatePublicDns(requirement, validatedPolicy, evidence);\n });\n}\n\nfunction evaluatePublicDns(\n requirement: DnsRecord.DnsRecord,\n policy: DnsResolverPool.Policy,\n evidence: ReadonlyArray<DnsResolverPool.Observation>,\n): PublicDnsObservation {\n const matchedResolverIds = evidence.flatMap((observation) =>\n observation._tag === \"Answer\" && answersMatch(requirement, observation.answers)\n ? [observation.resolverId]\n : [],\n );\n const required =\n policy._tag === \"AnyMatch\" ? 1 : policy._tag === \"AllMatch\" ? evidence.length : policy.minimum;\n if (required > 0 && matchedResolverIds.length >= required) {\n return PublicDnsObservation.Verified({ evidence, matchedResolverIds });\n }\n const unavailable = evidence.filter(\n (observation) => observation._tag === \"TimedOut\" || observation._tag === \"Failed\",\n ).length;\n if (unavailable > 0 && matchedResolverIds.length + unavailable >= required) {\n return PublicDnsObservation.Unavailable({ evidence });\n }\n if (\n evidence.some(\n (observation) =>\n observation._tag === \"Answer\" && !answersMatch(requirement, observation.answers),\n )\n ) {\n return PublicDnsObservation.Mismatch({ evidence });\n }\n if (evidence.some((observation) => observation._tag === \"NoData\")) {\n return PublicDnsObservation.Pending({ evidence });\n }\n return PublicDnsObservation.Unavailable({ evidence });\n}\n\nfunction answersMatch(\n requirement: DnsRecord.DnsRecord,\n answers: ReadonlyArray<{ readonly data: string; readonly name: string; readonly type: string }>,\n): boolean {\n const expected = DnsData.parse(requirement._tag, recordValue(requirement));\n return answers.some(\n (answer) =>\n answer.name === requirement.name &&\n answer.type === requirement._tag &&\n DnsData.parse(requirement._tag, answer.data) === expected,\n );\n}\n\nfunction aggregate(evidence: Evidence): Result {\n const requested = [evidence.provider, evidence.publicDns].filter(\n (observation): observation is ProviderObservation | PublicDnsObservation =>\n observation !== null,\n );\n if (requested.length === 0) return Result.NotObserved(evidence);\n if (\n requested.every(\n (observation) => observation._tag === \"Matched\" || observation._tag === \"Verified\",\n )\n ) {\n return Result.Verified(evidence);\n }\n if (requested.some((observation) => observation._tag === \"Unavailable\")) {\n return Result.Unavailable(evidence);\n }\n if (requested.some((observation) => observation._tag === \"Mismatch\")) {\n return Result.Mismatch(evidence);\n }\n return Result.Pending(evidence);\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":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as Interface$1, c as Service$2, i as Error$1, n as AsyncInterface, o as Query, t as Answer } from "./resolver-
|
|
1
|
+
import { Ft as DomainName, K as ProviderAuthorization, M as Connection, bt as DnsRecord, mt as Service$1, zt as Error } from "./zone-discovery-BPnH3sLU.mjs";
|
|
2
|
+
import { a as Interface$1, c as Service$2, i as Error$1, n as AsyncInterface, o as Query, t as Answer } from "./resolver-Dc0hwV-J.mjs";
|
|
3
3
|
import { Context, Data, Effect, Layer, Schema } from "effect";
|
|
4
4
|
declare namespace diagnostic_d_exports {
|
|
5
5
|
export { Category, Diagnostic, Fields, RetryAdvice, from };
|
|
@@ -802,4 +802,4 @@ declare function observe(input: ProviderConfig): Effect.Effect<Result, Error, Se
|
|
|
802
802
|
declare function observe(input: Config): Effect.Effect<Result, Error, Service$1>;
|
|
803
803
|
//#endregion
|
|
804
804
|
export { selection_d_exports as _, verify_d_exports as a, Policy as c, google_doh_d_exports as d, Options$1 as f, zones_d_exports as g, doh_d_exports as h, Result as i, resolver_pool_d_exports as l, Options$2 as m, PublicDns as n, DefaultOptions as o, cloudflare_doh_d_exports as p, PublicDnsObservation as r, Observation as s, ProviderObservation as t, Options as u, diagnostic_d_exports as v };
|
|
805
|
-
//# sourceMappingURL=verify-
|
|
805
|
+
//# sourceMappingURL=verify-Dls29YC-.d.mts.map
|
|
@@ -1256,6 +1256,11 @@ interface CompleteInput {
|
|
|
1256
1256
|
readonly continuations: ContinuationStore;
|
|
1257
1257
|
readonly flow: InteractiveFlow;
|
|
1258
1258
|
}
|
|
1259
|
+
interface ExtendInput {
|
|
1260
|
+
readonly connectionId: string;
|
|
1261
|
+
readonly grant: Grant;
|
|
1262
|
+
readonly ownerId: string;
|
|
1263
|
+
}
|
|
1259
1264
|
declare const start: (input: BaseInput & {
|
|
1260
1265
|
readonly method: Method;
|
|
1261
1266
|
}) => Effect.Effect<{
|
|
@@ -1267,6 +1272,8 @@ declare const start: (input: BaseInput & {
|
|
|
1267
1272
|
readonly continuationId: string;
|
|
1268
1273
|
}, Error$1 | AuthenticationFailure, Crypto.Crypto | Service$1>;
|
|
1269
1274
|
declare const complete: (input: CompleteInput) => Effect.Effect<Aggregate, Error$1 | AuthenticationFailure, Crypto.Crypto | Service$1>;
|
|
1275
|
+
/** Extends one owner binding without repeating provider authentication. */
|
|
1276
|
+
declare const extend: (input: ExtendInput) => Effect.Effect<Aggregate, Error$1 | Error, Service$1>;
|
|
1270
1277
|
type Requirements = Service$1 | Crypto.Crypto;
|
|
1271
1278
|
type Failure = AuthenticationFailure | Error$1 | CryptoError;
|
|
1272
1279
|
declare namespace zone_discovery_d_exports {
|
|
@@ -1386,5 +1393,5 @@ declare class Service extends Service_base {}
|
|
|
1386
1393
|
/** Compose provider-account discovery sources without expanding the record-provider contract. */
|
|
1387
1394
|
declare function make(sources: ReadonlyArray<Source>): Interface;
|
|
1388
1395
|
//#endregion
|
|
1389
|
-
export {
|
|
1390
|
-
//# sourceMappingURL=zone-discovery-
|
|
1396
|
+
export { IntegrationMethod as $, lifecycle_repository_d_exports as A, Type as At, encode$1 as B, invalid_input_d_exports as Bt, Envelope as C, Ns as Ct, Error$1 as D, Schema$4 as Dt, DetachResult as E, RequirementMetadata as Et, Schema$1 as F, DomainName as Ft, EvidenceSchema as G, Capability as H, StoredCredential as I, Schema$5 as It, authorization_d_exports as J, ProviderAuthorization as K, assertGrant as L, domain_name_d_exports as Lt, Connection as M, dns_record_d_exports as Mt, Grant as N, equals as Nt, Interface$1 as O, Srv as Ot, OAuthContinuation as P, parse as Pt, AsyncOAuthSubjectResolver as Q, authorizationError as R, parse$1 as Rt, Codec as S, Mx as St, Aggregate as T, Opaque as Tt, CapabilityEvidence as U, validate as V, Evidence as W, CryptoError as X, encode$2 as Y, canonical_json_d_exports as Z, Requirements as _, Aaaa as _t, Authentication as a, Schema$3 as at, extend as b, DnsRecord as bt, CompleteInput as c, Value as ct, Error as d, CreateResult as dt, Manifest as et, ExtendInput as f, Error$2 as ft, Method as g, A as gt, InteractiveStart as h, provider_d_exports as ht, zone_discovery_d_exports as i, OAuthSubjectResolver as it, AuthorizationError as j, data as jt, Service$1 as k, Txt as kt, Continuation as l, secret_d_exports as lt, InteractiveFlow as m, Service$2 as mt, Service as n, OAuthClientConfiguration as nt, AuthenticationFailure as o, TokenValidation as ot, Failure as p, Interface$2 as pt, Schema$2 as q, Source as r, OAuthMethod as rt, BaseInput as s, manifest_d_exports as st, Candidate as t, Method$1 as tt, ContinuationStore as u, AsyncInterface as ut, StartResult as v, Caa as vt, provider_context_d_exports as w, Observed as wt, start as x, Encoded as xt, complete as y, Cname as yt, decode$1 as z, Error$3 as zt };
|
|
1397
|
+
//# sourceMappingURL=zone-discovery-BPnH3sLU.d.mts.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-CQSKKMrW.mjs","names":["Error","Repository.Service","InvalidInputError","decode","encode","S","Schema","ProviderContext.Envelope","InvalidInputError"],"sources":["../src/auth/connect.ts","../src/auth/secret.ts","../src/auth/provider-context.ts","../src/auth/authorization.ts"],"sourcesContent":["import { Clock, Crypto, Data, Effect, Schema } from \"effect\";\n\nimport { CryptoError } from \"../plan/canonical-json.ts\";\nimport type { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport type * as DnsProvider from \"../provider/provider.ts\";\nimport * as ProviderAuthorization from \"./authorization.ts\";\nimport type * as Binding from \"./connection.ts\";\nimport * as Repository from \"./lifecycle-repository.ts\";\nimport type * as ProviderContext from \"./provider-context.ts\";\nimport type * as Secret from \"./secret.ts\";\n\nexport interface Authentication {\n readonly capabilityEvidence: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>;\n readonly credential: Binding.StoredCredential;\n readonly expiresAt: Date | null;\n readonly providerAccountId: string;\n readonly providerContext: ProviderContext.Envelope;\n readonly scopes: ReadonlyArray<string>;\n}\n\nexport type AuthenticationFailure = Error | InvalidInputError | DnsProvider.Error;\n\nexport interface InteractiveStart {\n readonly authorizationUrl: URL;\n readonly payload: Secret.Value;\n}\n\nexport interface Continuation extends BaseInput {\n readonly expiresAt: Date;\n readonly id: string;\n readonly method: \"integration\" | \"oauth2\";\n readonly payload: Secret.Value;\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n}\n\nexport interface ContinuationStore {\n readonly consume: (id: string, now: Date) => Effect.Effect<Continuation | null, Error>;\n readonly put: (continuation: Continuation) => Effect.Effect<void, Error>;\n}\n\nexport interface InteractiveFlow {\n readonly complete: (\n payload: Secret.Value,\n callbackUrl: URL,\n ) => Effect.Effect<Authentication, AuthenticationFailure>;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n readonly start: (\n continuationId: string,\n ) => Effect.Effect<InteractiveStart, AuthenticationFailure, Crypto.Crypto>;\n}\n\nexport type Method = Data.TaggedEnum<{\n Interactive: {\n readonly continuations: ContinuationStore;\n readonly flow: InteractiveFlow;\n readonly ttlMs?: number;\n };\n Token: {\n readonly authenticate: (\n token: Secret.Value,\n ) => Effect.Effect<Authentication, AuthenticationFailure>;\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n readonly token: Secret.Value;\n };\n}>;\nexport const Method = Data.taggedEnum<Method>();\n\nexport type StartResult = Data.TaggedEnum<{\n Connected: { readonly aggregate: Repository.Aggregate };\n Redirect: { readonly authorizationUrl: URL; readonly continuationId: string };\n}>;\nexport const StartResult = Data.taggedEnum<StartResult>();\n\nexport class Error extends Schema.TaggedError<Error>()(\"ConnectionError\", {\n category: Schema.Literals([\"authorization\", \"provider\", \"validation\"]),\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\nexport interface BaseInput {\n readonly authorizedById: string;\n readonly grant: Binding.Grant;\n readonly ownerId: string;\n}\n\nexport interface CompleteInput {\n readonly callbackUrl: URL;\n readonly continuationId: string;\n readonly continuations: ContinuationStore;\n readonly flow: InteractiveFlow;\n}\n\nconst mergeGrant = (\n current: Binding.Grant | undefined,\n requested: Binding.Grant,\n): Binding.Grant => {\n if (current === undefined) return requested;\n if (current._tag === \"account\" || requested._tag === \"account\") return { _tag: \"account\" };\n return {\n _tag: \"domains\",\n domains: [...new Set([...current.domains, ...requested.domains])],\n };\n};\n\nconst persist = Effect.fn(\"Connection.persist\")(function* (\n input: BaseInput & {\n readonly authentication: Authentication;\n readonly method: \"integration\" | \"oauth2\" | \"token\";\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n },\n) {\n const repository = yield* Repository.Service;\n const crypto = yield* Crypto.Crypto;\n const now = new Date(yield* Clock.currentTimeMillis);\n const missingCapability = input.requiredCapabilities.find(\n (capability) =>\n !input.authentication.capabilityEvidence.some((item) => item.capability === capability),\n );\n if (missingCapability !== undefined) {\n return yield* new Error({\n category: \"authorization\",\n message: `Provider authorization lacks evidence for ${missingCapability}`,\n operation: \"Connection.persist\",\n retry: \"after-user-action\",\n });\n }\n const existing = yield* repository.findByProviderAccount(\n input.providerId,\n input.authentication.providerAccountId,\n );\n const authorizationId =\n existing?.authorization.id ??\n (yield* crypto.randomUUIDv4.pipe(\n Effect.mapError(\n (cause) =>\n new Error({\n category: \"validation\",\n message: cause.message,\n operation: \"Connection.persist\",\n retry: \"safe\",\n }),\n ),\n ));\n const existingBinding = existing?.bindings.find((binding) => binding.ownerId === input.ownerId);\n const binding: Binding.Connection = {\n authorizationId,\n createdAt: existingBinding?.createdAt ?? now,\n grant: mergeGrant(existingBinding?.grant, input.grant),\n id:\n existingBinding?.id ??\n (yield* crypto.randomUUIDv4.pipe(\n Effect.mapError(\n (cause) =>\n new Error({\n category: \"validation\",\n message: cause.message,\n operation: \"Connection.persist\",\n retry: \"safe\",\n }),\n ),\n )),\n ownerId: input.ownerId,\n };\n const aggregate: Repository.Aggregate = {\n authorization: {\n authorizedById: input.authorizedById,\n capabilityEvidence: [...input.authentication.capabilityEvidence],\n createdAt: existing?.authorization.createdAt ?? now,\n expiresAt: input.authentication.expiresAt,\n id: authorizationId,\n method: input.method,\n providerAccountId: input.authentication.providerAccountId,\n providerContext: input.authentication.providerContext,\n providerId: input.providerId,\n requiredCapabilities: [...input.requiredCapabilities],\n revocation: { _tag: \"Active\" },\n scopes: [...input.authentication.scopes],\n },\n bindings: [\n ...(existing?.bindings.filter((candidate) => candidate.id !== binding.id) ?? []),\n binding,\n ],\n credential: input.authentication.credential,\n };\n return yield* repository.connect(aggregate);\n});\n\nexport const start = Effect.fn(\"Connection.start\")(function* (\n input: BaseInput & { readonly method: Method },\n) {\n if (input.method._tag === \"Interactive\") {\n const crypto = yield* Crypto.Crypto;\n const now = yield* Clock.currentTimeMillis;\n const continuationId = yield* crypto.randomUUIDv4.pipe(\n Effect.mapError(\n (cause) =>\n new Error({\n category: \"validation\",\n message: cause.message,\n operation: \"Connection.start\",\n retry: \"safe\",\n }),\n ),\n );\n const started = yield* input.method.flow.start(continuationId);\n yield* input.method.continuations.put({\n authorizedById: input.authorizedById,\n expiresAt: new Date(now + (input.method.ttlMs ?? 10 * 60_000)),\n grant: input.grant,\n id: continuationId,\n method: input.method.flow.method,\n ownerId: input.ownerId,\n payload: started.payload,\n providerId: input.method.flow.providerId,\n requiredCapabilities: [...input.method.flow.requiredCapabilities],\n });\n return StartResult.Redirect({\n authorizationUrl: started.authorizationUrl,\n continuationId,\n });\n }\n const authentication = yield* input.method.authenticate(input.method.token);\n const aggregate = yield* persist({\n authentication,\n authorizedById: input.authorizedById,\n grant: input.grant,\n method: \"token\",\n ownerId: input.ownerId,\n providerId: input.method.providerId,\n requiredCapabilities: input.method.requiredCapabilities,\n });\n return StartResult.Connected({ aggregate });\n});\n\nexport const complete = Effect.fn(\"Connection.complete\")(function* (input: CompleteInput) {\n const continuation = yield* input.continuations.consume(\n input.continuationId,\n new Date(yield* Clock.currentTimeMillis),\n );\n if (continuation === null) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Connection continuation is expired, unknown, or already consumed\",\n operation: \"Connection.complete\",\n retry: \"after-user-action\",\n });\n }\n if (\n continuation.providerId !== input.flow.providerId ||\n continuation.method !== input.flow.method\n ) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Connection continuation does not match the provider flow\",\n operation: \"Connection.complete\",\n retry: \"never\",\n });\n }\n const authentication = yield* input.flow.complete(continuation.payload, input.callbackUrl);\n return yield* persist({\n authentication,\n authorizedById: continuation.authorizedById,\n grant: continuation.grant,\n method: continuation.method,\n ownerId: continuation.ownerId,\n providerId: continuation.providerId,\n requiredCapabilities: continuation.requiredCapabilities,\n });\n});\n\nexport type Requirements = Repository.Service | Crypto.Crypto;\nexport type Failure = AuthenticationFailure | Repository.Error | CryptoError;\n","/** 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 { Effect, Schema } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\n/** A provider-owned, versioned, non-secret context value persisted by the host. */\nexport const Envelope = Schema.Struct({\n value: Schema.Json,\n version: Schema.String,\n});\nexport interface Envelope extends Schema.Schema.Type<typeof Envelope> {}\n\nexport interface Codec<A> {\n readonly decode: (envelope: Envelope) => Effect.Effect<A, InvalidInputError>;\n readonly encode: (value: A) => Effect.Effect<Envelope, InvalidInputError>;\n readonly version: string;\n}\n\n/** Build an adapter-owned context codec from a schema and stable version identifier. */\nexport function codec<A, I>(version: string, schema: Schema.Codec<A, I>): Codec<A> {\n return {\n decode: Effect.fn(\"ProviderContext.decode\")((envelope) =>\n envelope.version !== version\n ? Effect.fail(\n new InvalidInputError({\n message: `Unsupported provider context version: ${envelope.version}`,\n }),\n )\n : Schema.decodeUnknownEffect(schema)(envelope.value).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n ),\n encode: Effect.fn(\"ProviderContext.encode\")((value) =>\n Schema.encodeEffect(schema)(value).pipe(\n Effect.flatMap((encoded) => Schema.decodeUnknownEffect(Schema.Json)(encoded)),\n Effect.map((encoded) => ({ value: encoded, version })),\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n ),\n version,\n };\n}\n\nexport const decode = Effect.fn(\"ProviderContext.Envelope.decode\")((input: unknown) =>\n Schema.decodeUnknownEffect(Envelope)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = Schema.encodeSync(Envelope);\n","import { Data, Effect, Schema as S } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport * as ProviderContext from \"./provider-context.ts\";\n\nexport const Capability = S.Literals([\"dns:read\", \"dns:write\"]);\nexport type Capability = typeof Capability.Type;\n\nexport type Evidence = Data.TaggedEnum<{\n Declared: {};\n Exercised: { readonly observedAt: Date };\n Introspected: { readonly observedAt: Date };\n}>;\nexport const Evidence = Data.taggedEnum<Evidence>();\n\nexport const EvidenceSchema = S.TaggedUnion({\n Declared: {},\n Exercised: { observedAt: S.DateFromString },\n Introspected: { observedAt: S.DateFromString },\n});\n\nexport const CapabilityEvidence = S.Struct({\n capability: Capability,\n evidence: EvidenceSchema,\n});\nexport interface CapabilityEvidence extends S.Schema.Type<typeof CapabilityEvidence> {}\n\nexport const Revocation = S.TaggedUnion({\n Active: {},\n Pending: { requestedAt: S.DateFromString },\n});\nexport type Revocation = typeof Revocation.Type;\n\n/** A provider credential authorization shared by one or more owner connections. */\nexport const Schema = S.Struct({\n authorizedById: S.String,\n capabilityEvidence: S.Array(CapabilityEvidence),\n createdAt: S.DateFromString,\n expiresAt: S.NullOr(S.DateFromString),\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n providerAccountId: S.String,\n providerContext: ProviderContext.Envelope,\n providerId: S.String,\n requiredCapabilities: S.Array(Capability),\n revocation: Revocation,\n scopes: S.Array(S.String),\n});\nexport interface ProviderAuthorization extends S.Schema.Type<typeof Schema> {}\n\nexport const decode = Effect.fn(\"ProviderAuthorization.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const validate = Effect.fn(\"ProviderAuthorization.validate\")((input: unknown) =>\n S.decodeUnknownEffect(S.toType(Schema))(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = S.encodeSync(Schema);\n\nexport function evidenceFor(\n authorization: ProviderAuthorization,\n capability: Capability,\n): Evidence | undefined {\n return authorization.capabilityEvidence.find((item) => item.capability === capability)?.evidence;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connection-X3rZhrBZ.mjs","names":["Lifecycle.Error","Lifecycle.Service","Connection.decode","Connect.Error","Connect.start","LifecycleRepository.layerFrom","Connect.complete"],"sources":["../src/promise/authorization-lifecycle.ts","../src/promise/connection.ts"],"sourcesContent":["import { Effect, Layer } from \"effect\";\n\nimport type * as ProviderAuthorization from \"../auth/authorization.ts\";\nimport type * as Connection from \"../auth/connection.ts\";\nimport * as Lifecycle from \"../auth/lifecycle-repository.ts\";\n\nexport interface Repository {\n readonly bind: (\n authorizationId: string,\n binding: Connection.Connection,\n ) => Promise<Lifecycle.Aggregate>;\n readonly connect: (aggregate: Lifecycle.Aggregate) => Promise<Lifecycle.Aggregate>;\n readonly detach: (input: {\n readonly connectionId: string;\n readonly revoke: (aggregate: Lifecycle.Aggregate) => Promise<void>;\n }) => Promise<Lifecycle.DetachResult>;\n readonly findByProviderAccount: (\n providerId: string,\n providerAccountId: string,\n ) => Promise<Lifecycle.Aggregate | null>;\n readonly get: (authorizationId: string) => Promise<Lifecycle.Aggregate | null>;\n readonly getByConnectionId: (connectionId: string) => Promise<Lifecycle.Aggregate | null>;\n readonly promoteEvidence: (\n authorizationId: string,\n evidence: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>,\n ) => Promise<Lifecycle.Aggregate>;\n readonly recover: (input: {\n readonly authorizationId: string;\n readonly revoke: (aggregate: Lifecycle.Aggregate) => Promise<void>;\n }) => Promise<Lifecycle.DetachResult>;\n readonly rotate: (\n authorizationId: string,\n credential: Connection.StoredCredential,\n expiresAt: Date | null,\n ) => Promise<Lifecycle.Aggregate>;\n}\n\nconst failure = (operation: string, cause: unknown): Lifecycle.Error =>\n cause instanceof Lifecycle.Error\n ? cause\n : new Lifecycle.Error({\n category: \"storage\",\n message: cause instanceof globalThis.Error ? cause.message : String(cause),\n operation,\n retry: \"safe\",\n });\n\nexport const layerFrom = (repository: Repository): Layer.Layer<Lifecycle.Service> =>\n Layer.succeed(Lifecycle.Service, {\n bind: Effect.fn(\"AuthorizationLifecycleRepository.bind\")((authorizationId, binding) =>\n Effect.tryPromise({\n try: () => repository.bind(authorizationId, binding),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.bind\", cause),\n }),\n ),\n connect: Effect.fn(\"AuthorizationLifecycleRepository.connect\")((aggregate) =>\n Effect.tryPromise({\n try: () => repository.connect(aggregate),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.connect\", cause),\n }),\n ),\n detach: ({ connectionId, revoke }) =>\n Effect.tryPromise({\n try: () =>\n repository.detach({\n connectionId,\n revoke: (aggregate) => Effect.runPromise(revoke(aggregate)),\n }),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.detach\", cause),\n }),\n findByProviderAccount: Effect.fn(\"AuthorizationLifecycleRepository.findByProviderAccount\")(\n (providerId, providerAccountId) =>\n Effect.tryPromise({\n try: () => repository.findByProviderAccount(providerId, providerAccountId),\n catch: (cause) =>\n failure(\"AuthorizationLifecycleRepository.findByProviderAccount\", cause),\n }),\n ),\n get: Effect.fn(\"AuthorizationLifecycleRepository.get\")((authorizationId) =>\n Effect.tryPromise({\n try: () => repository.get(authorizationId),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.get\", cause),\n }),\n ),\n getByConnectionId: Effect.fn(\"AuthorizationLifecycleRepository.getByConnectionId\")(\n (connectionId) =>\n Effect.tryPromise({\n try: () => repository.getByConnectionId(connectionId),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.getByConnectionId\", cause),\n }),\n ),\n promoteEvidence: Effect.fn(\"AuthorizationLifecycleRepository.promoteEvidence\")(\n (authorizationId, evidence) =>\n Effect.tryPromise({\n try: () => repository.promoteEvidence(authorizationId, evidence),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.promoteEvidence\", cause),\n }),\n ),\n recover: ({ authorizationId, revoke }) =>\n Effect.tryPromise({\n try: () =>\n repository.recover({\n authorizationId,\n revoke: (aggregate) => Effect.runPromise(revoke(aggregate)),\n }),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.recover\", cause),\n }),\n rotate: Effect.fn(\"AuthorizationLifecycleRepository.rotate\")(\n (authorizationId, credential, expiresAt) =>\n Effect.tryPromise({\n try: () => repository.rotate(authorizationId, credential, expiresAt),\n catch: (cause) => failure(\"AuthorizationLifecycleRepository.rotate\", cause),\n }),\n ),\n });\n\nexport const toAsync = (repository: Lifecycle.Interface): Repository => ({\n bind: (authorizationId, binding) => Effect.runPromise(repository.bind(authorizationId, binding)),\n connect: (aggregate) => Effect.runPromise(repository.connect(aggregate)),\n detach: ({ connectionId, revoke }) =>\n Effect.runPromise(\n repository.detach({\n connectionId,\n revoke: (aggregate) => Effect.tryPromise(() => revoke(aggregate)),\n }),\n ),\n findByProviderAccount: (providerId, providerAccountId) =>\n Effect.runPromise(repository.findByProviderAccount(providerId, providerAccountId)),\n get: (authorizationId) => Effect.runPromise(repository.get(authorizationId)),\n getByConnectionId: (connectionId) =>\n Effect.runPromise(repository.getByConnectionId(connectionId)),\n promoteEvidence: (authorizationId, evidence) =>\n Effect.runPromise(repository.promoteEvidence(authorizationId, evidence)),\n recover: ({ authorizationId, revoke }) =>\n Effect.runPromise(\n repository.recover({\n authorizationId,\n revoke: (aggregate) => Effect.tryPromise(() => revoke(aggregate)),\n }),\n ),\n rotate: (authorizationId, credential, expiresAt) =>\n Effect.runPromise(repository.rotate(authorizationId, credential, expiresAt)),\n});\n\nexport const from = (repository: Repository): Repository => repository;\n\nexport { Error } from \"../auth/lifecycle-repository.ts\";\nexport type { Aggregate, DetachResult } from \"../auth/lifecycle-repository.ts\";\n","import { Data, Effect, Layer } from \"effect\";\n\nimport * as Connection from \"../auth/connection.ts\";\nimport * as Connect from \"../auth/connect.ts\";\nimport type * as Repository from \"./authorization-lifecycle.ts\";\nimport type * as ProviderAuthorization from \"../auth/authorization.ts\";\nimport { webCryptoLayer } from \"../plan/canonical-json.ts\";\nimport * as LifecycleRepository from \"./authorization-lifecycle.ts\";\nimport type * as Secret from \"../auth/secret.ts\";\n\nexport { assertGrant, AuthorizationError, encode, Grant, Schema } from \"../auth/connection.ts\";\nexport type { Connection, OAuthContinuation, StoredCredential } from \"../auth/connection.ts\";\n\nexport function decode(input: unknown): Promise<Connection.Connection> {\n return Effect.runPromise(Connection.decode(input));\n}\n\nexport type Method = Data.TaggedEnum<{\n Interactive: {\n readonly continuations: ContinuationStore;\n readonly flow: InteractiveFlow;\n readonly ttlMs?: number;\n };\n Token: {\n readonly authenticate: (token: Secret.Value) => Promise<Connect.Authentication>;\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n readonly token: Secret.Value;\n };\n}>;\nexport const Method = Data.taggedEnum<Method>();\n\nexport interface ContinuationStore {\n readonly consume: (id: string, now: Date) => Promise<Connect.Continuation | null>;\n readonly put: (continuation: Connect.Continuation) => Promise<void>;\n}\n\nexport interface InteractiveFlow {\n readonly complete: (payload: Secret.Value, callbackUrl: URL) => Promise<Connect.Authentication>;\n readonly method: \"integration\" | \"oauth2\";\n readonly providerId: string;\n readonly requiredCapabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n readonly start: (continuationId: string) => Promise<Connect.InteractiveStart>;\n}\n\nconst connectionFailure = (operation: string, cause: unknown): Connect.Error =>\n cause instanceof Connect.Error\n ? cause\n : new Connect.Error({\n category: \"provider\",\n message: cause instanceof globalThis.Error ? cause.message : String(cause),\n operation,\n retry: \"unknown\",\n });\n\nconst effectMethod = (method: Method): Connect.Method =>\n method._tag === \"Interactive\"\n ? Connect.Method.Interactive({\n continuations: effectContinuations(method.continuations),\n flow: effectFlow(method.flow),\n ...(method.ttlMs === undefined ? {} : { ttlMs: method.ttlMs }),\n })\n : Connect.Method.Token({\n authenticate: (token) =>\n Effect.tryPromise({\n try: () => method.authenticate(token),\n catch: (cause) => connectionFailure(\"Connection.start\", cause),\n }),\n providerId: method.providerId,\n requiredCapabilities: method.requiredCapabilities,\n token: method.token,\n });\n\nconst effectContinuations = (store: ContinuationStore): Connect.ContinuationStore => ({\n consume: (id, now) =>\n Effect.tryPromise({\n try: () => store.consume(id, now),\n catch: (cause) => connectionFailure(\"ConnectionContinuations.consume\", cause),\n }),\n put: (continuation) =>\n Effect.tryPromise({\n try: () => store.put(continuation),\n catch: (cause) => connectionFailure(\"ConnectionContinuations.put\", cause),\n }),\n});\n\nexport const toAsyncContinuations = (store: Connect.ContinuationStore): ContinuationStore => ({\n consume: (id, now) => Effect.runPromise(store.consume(id, now)),\n put: (continuation) => Effect.runPromise(store.put(continuation)),\n});\n\nconst effectFlow = (flow: InteractiveFlow): Connect.InteractiveFlow => ({\n complete: (payload, callbackUrl) =>\n Effect.tryPromise({\n try: () => flow.complete(payload, callbackUrl),\n catch: (cause) => connectionFailure(\"Connection.complete\", cause),\n }),\n method: flow.method,\n providerId: flow.providerId,\n requiredCapabilities: flow.requiredCapabilities,\n start: (continuationId) =>\n Effect.tryPromise({\n try: () => flow.start(continuationId),\n catch: (cause) => connectionFailure(\"Connection.start\", cause),\n }),\n});\n\n/** Adapts an Effect-native provider flow to the Promise facade. */\nexport const fromEffectFlow = (flow: Connect.InteractiveFlow): InteractiveFlow => ({\n complete: (payload, callbackUrl) => Effect.runPromise(flow.complete(payload, callbackUrl)),\n method: flow.method,\n providerId: flow.providerId,\n requiredCapabilities: flow.requiredCapabilities,\n start: (continuationId) =>\n Effect.runPromise(flow.start(continuationId).pipe(Effect.provide(webCryptoLayer))),\n});\n\n/** Adapts an Effect-native token method to the Promise facade. */\nexport function fromEffectTokenMethod(\n method: Extract<Connect.Method, { readonly _tag: \"Token\" }>,\n): Extract<Method, { readonly _tag: \"Token\" }> {\n return Method.Token({\n authenticate: (token) => Effect.runPromise(method.authenticate(token)),\n providerId: method.providerId,\n requiredCapabilities: method.requiredCapabilities,\n token: method.token,\n });\n}\n\nexport async function start(\n input: Connect.BaseInput & {\n readonly method: Method;\n readonly repository: Repository.Repository;\n },\n): Promise<Connect.StartResult> {\n return Effect.runPromise(\n Connect.start({\n authorizedById: input.authorizedById,\n grant: input.grant,\n method: effectMethod(input.method),\n ownerId: input.ownerId,\n }).pipe(\n Effect.provide(Layer.merge(LifecycleRepository.layerFrom(input.repository), webCryptoLayer)),\n ),\n );\n}\n\nexport async function complete(input: {\n readonly callbackUrl: URL;\n readonly continuationId: string;\n readonly continuations: ContinuationStore;\n readonly flow: InteractiveFlow;\n readonly repository: Repository.Repository;\n}): Promise<Repository.Aggregate> {\n return Effect.runPromise(\n Connect.complete({\n callbackUrl: input.callbackUrl,\n continuationId: input.continuationId,\n continuations: effectContinuations(input.continuations),\n flow: effectFlow(input.flow),\n }).pipe(\n Effect.provide(Layer.merge(LifecycleRepository.layerFrom(input.repository), webCryptoLayer)),\n ),\n );\n}\n\nexport { Error, StartResult } from \"../auth/connect.ts\";\nexport type { Authentication, ConnectionStartResult } from \"../auth/connection-api.ts\";\n"],"mappings":";;;;;;;;;;;;;AAqCA,MAAM,WAAW,WAAmB,UAClC,iBAAiBA,QACb,QACA,IAAIA,MAAgB;CAClB,UAAU;CACV,SAAS,iBAAiB,WAAW,QAAQ,MAAM,UAAU,OAAO,KAAK;CACzE;CACA,OAAO;AACT,CAAC;AAEP,MAAa,aAAa,eACxB,MAAM,QAAQC,SAAmB;CAC/B,MAAM,OAAO,GAAG,uCAAuC,CAAC,EAAE,iBAAiB,YACzE,OAAO,WAAW;EAChB,WAAW,WAAW,KAAK,iBAAiB,OAAO;EACnD,QAAQ,UAAU,QAAQ,yCAAyC,KAAK;CAC1E,CAAC,CACH;CACA,SAAS,OAAO,GAAG,0CAA0C,CAAC,EAAE,cAC9D,OAAO,WAAW;EAChB,WAAW,WAAW,QAAQ,SAAS;EACvC,QAAQ,UAAU,QAAQ,4CAA4C,KAAK;CAC7E,CAAC,CACH;CACA,SAAS,EAAE,cAAc,aACvB,OAAO,WAAW;EAChB,WACE,WAAW,OAAO;GAChB;GACA,SAAS,cAAc,OAAO,WAAW,OAAO,SAAS,CAAC;EAC5D,CAAC;EACH,QAAQ,UAAU,QAAQ,2CAA2C,KAAK;CAC5E,CAAC;CACH,uBAAuB,OAAO,GAAG,wDAAwD,CAAC,EACvF,YAAY,sBACX,OAAO,WAAW;EAChB,WAAW,WAAW,sBAAsB,YAAY,iBAAiB;EACzE,QAAQ,UACN,QAAQ,0DAA0D,KAAK;CAC3E,CAAC,CACL;CACA,KAAK,OAAO,GAAG,sCAAsC,CAAC,EAAE,oBACtD,OAAO,WAAW;EAChB,WAAW,WAAW,IAAI,eAAe;EACzC,QAAQ,UAAU,QAAQ,wCAAwC,KAAK;CACzE,CAAC,CACH;CACA,mBAAmB,OAAO,GAAG,oDAAoD,CAAC,EAC/E,iBACC,OAAO,WAAW;EAChB,WAAW,WAAW,kBAAkB,YAAY;EACpD,QAAQ,UAAU,QAAQ,sDAAsD,KAAK;CACvF,CAAC,CACL;CACA,iBAAiB,OAAO,GAAG,kDAAkD,CAAC,EAC3E,iBAAiB,aAChB,OAAO,WAAW;EAChB,WAAW,WAAW,gBAAgB,iBAAiB,QAAQ;EAC/D,QAAQ,UAAU,QAAQ,oDAAoD,KAAK;CACrF,CAAC,CACL;CACA,UAAU,EAAE,iBAAiB,aAC3B,OAAO,WAAW;EAChB,WACE,WAAW,QAAQ;GACjB;GACA,SAAS,cAAc,OAAO,WAAW,OAAO,SAAS,CAAC;EAC5D,CAAC;EACH,QAAQ,UAAU,QAAQ,4CAA4C,KAAK;CAC7E,CAAC;CACH,QAAQ,OAAO,GAAG,yCAAyC,CAAC,EACzD,iBAAiB,YAAY,cAC5B,OAAO,WAAW;EAChB,WAAW,WAAW,OAAO,iBAAiB,YAAY,SAAS;EACnE,QAAQ,UAAU,QAAQ,2CAA2C,KAAK;CAC5E,CAAC,CACL;AACF,CAAC;AAEH,MAAa,WAAW,gBAAiD;CACvE,OAAO,iBAAiB,YAAY,OAAO,WAAW,WAAW,KAAK,iBAAiB,OAAO,CAAC;CAC/F,UAAU,cAAc,OAAO,WAAW,WAAW,QAAQ,SAAS,CAAC;CACvE,SAAS,EAAE,cAAc,aACvB,OAAO,WACL,WAAW,OAAO;EAChB;EACA,SAAS,cAAc,OAAO,iBAAiB,OAAO,SAAS,CAAC;CAClE,CAAC,CACH;CACF,wBAAwB,YAAY,sBAClC,OAAO,WAAW,WAAW,sBAAsB,YAAY,iBAAiB,CAAC;CACnF,MAAM,oBAAoB,OAAO,WAAW,WAAW,IAAI,eAAe,CAAC;CAC3E,oBAAoB,iBAClB,OAAO,WAAW,WAAW,kBAAkB,YAAY,CAAC;CAC9D,kBAAkB,iBAAiB,aACjC,OAAO,WAAW,WAAW,gBAAgB,iBAAiB,QAAQ,CAAC;CACzE,UAAU,EAAE,iBAAiB,aAC3B,OAAO,WACL,WAAW,QAAQ;EACjB;EACA,SAAS,cAAc,OAAO,iBAAiB,OAAO,SAAS,CAAC;CAClE,CAAC,CACH;CACF,SAAS,iBAAiB,YAAY,cACpC,OAAO,WAAW,WAAW,OAAO,iBAAiB,YAAY,SAAS,CAAC;AAC/E;AAEA,MAAa,QAAQ,eAAuC;;;;;;;;;;;;;;;;;;;ACnI5D,SAAgB,OAAO,OAAgD;CACrE,OAAO,OAAO,WAAWC,SAAkB,KAAK,CAAC;AACnD;AAeA,MAAa,SAAS,KAAK,WAAmB;AAe9C,MAAM,qBAAqB,WAAmB,UAC5C,iBAAiBC,UACb,QACA,IAAIA,QAAc;CAChB,UAAU;CACV,SAAS,iBAAiB,WAAW,QAAQ,MAAM,UAAU,OAAO,KAAK;CACzE;CACA,OAAO;AACT,CAAC;AAEP,MAAM,gBAAgB,WACpB,OAAO,SAAS,gBAAA,SACG,YAAY;CACzB,eAAe,oBAAoB,OAAO,aAAa;CACvD,MAAM,WAAW,OAAO,IAAI;CAC5B,GAAI,OAAO,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,OAAO,MAAM;AAC9D,CAAC,IAAA,SACc,MAAM;CACnB,eAAe,UACb,OAAO,WAAW;EAChB,WAAW,OAAO,aAAa,KAAK;EACpC,QAAQ,UAAU,kBAAkB,oBAAoB,KAAK;CAC/D,CAAC;CACH,YAAY,OAAO;CACnB,sBAAsB,OAAO;CAC7B,OAAO,OAAO;AAChB,CAAC;AAEP,MAAM,uBAAuB,WAAyD;CACpF,UAAU,IAAI,QACZ,OAAO,WAAW;EAChB,WAAW,MAAM,QAAQ,IAAI,GAAG;EAChC,QAAQ,UAAU,kBAAkB,mCAAmC,KAAK;CAC9E,CAAC;CACH,MAAM,iBACJ,OAAO,WAAW;EAChB,WAAW,MAAM,IAAI,YAAY;EACjC,QAAQ,UAAU,kBAAkB,+BAA+B,KAAK;CAC1E,CAAC;AACL;AAEA,MAAa,wBAAwB,WAAyD;CAC5F,UAAU,IAAI,QAAQ,OAAO,WAAW,MAAM,QAAQ,IAAI,GAAG,CAAC;CAC9D,MAAM,iBAAiB,OAAO,WAAW,MAAM,IAAI,YAAY,CAAC;AAClE;AAEA,MAAM,cAAc,UAAoD;CACtE,WAAW,SAAS,gBAClB,OAAO,WAAW;EAChB,WAAW,KAAK,SAAS,SAAS,WAAW;EAC7C,QAAQ,UAAU,kBAAkB,uBAAuB,KAAK;CAClE,CAAC;CACH,QAAQ,KAAK;CACb,YAAY,KAAK;CACjB,sBAAsB,KAAK;CAC3B,QAAQ,mBACN,OAAO,WAAW;EAChB,WAAW,KAAK,MAAM,cAAc;EACpC,QAAQ,UAAU,kBAAkB,oBAAoB,KAAK;CAC/D,CAAC;AACL;;AAGA,MAAa,kBAAkB,UAAoD;CACjF,WAAW,SAAS,gBAAgB,OAAO,WAAW,KAAK,SAAS,SAAS,WAAW,CAAC;CACzF,QAAQ,KAAK;CACb,YAAY,KAAK;CACjB,sBAAsB,KAAK;CAC3B,QAAQ,mBACN,OAAO,WAAW,KAAK,MAAM,cAAc,CAAC,CAAC,KAAK,OAAO,QAAQ,cAAc,CAAC,CAAC;AACrF;;AAGA,SAAgB,sBACd,QAC6C;CAC7C,OAAO,OAAO,MAAM;EAClB,eAAe,UAAU,OAAO,WAAW,OAAO,aAAa,KAAK,CAAC;EACrE,YAAY,OAAO;EACnB,sBAAsB,OAAO;EAC7B,OAAO,OAAO;CAChB,CAAC;AACH;AAEA,eAAsB,MACpB,OAI8B;CAC9B,OAAO,OAAO,WACZC,QAAc;EACZ,gBAAgB,MAAM;EACtB,OAAO,MAAM;EACb,QAAQ,aAAa,MAAM,MAAM;EACjC,SAAS,MAAM;CACjB,CAAC,CAAC,CAAC,KACD,OAAO,QAAQ,MAAM,MAAMC,UAA8B,MAAM,UAAU,GAAG,cAAc,CAAC,CAC7F,CACF;AACF;AAEA,eAAsB,SAAS,OAMG;CAChC,OAAO,OAAO,WACZC,WAAiB;EACf,aAAa,MAAM;EACnB,gBAAgB,MAAM;EACtB,eAAe,oBAAoB,MAAM,aAAa;EACtD,MAAM,WAAW,MAAM,IAAI;CAC7B,CAAC,CAAC,CAAC,KACD,OAAO,QAAQ,MAAM,MAAMD,UAA8B,MAAM,UAAU,GAAG,cAAc,CAAC,CAC7F,CACF;AACF"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { A as Connection, F as assertGrant, I as authorizationError, L as decode, N as Schema, P as StoredCredential, R as encode, _ as StartResult, a as Authentication, c as CompleteInput, d as Error, f as Failure, g as Requirements, h as Method, j as Grant, k as AuthorizationError, l as Continuation, m as InteractiveStart, o as AuthenticationFailure, p as InteractiveFlow, s as BaseInput, u as ContinuationStore, v as complete, y as start, z as validate } from "./zone-discovery-BA5I24vu.mjs";
|
|
2
|
-
declare namespace connection_api_d_exports {
|
|
3
|
-
export { Authentication, AuthenticationFailure, AuthorizationError, BaseInput, CompleteInput, Connection, Method as ConnectionMethod, StartResult as ConnectionStartResult, Continuation, ContinuationStore, Error, Failure, Grant, InteractiveFlow, InteractiveStart, Method, Requirements, Schema, StartResult, StoredCredential, assertGrant, authorizationError, complete, decode, encode, start, validate };
|
|
4
|
-
}
|
|
5
|
-
//#endregion
|
|
6
|
-
export { connection_api_d_exports as t };
|
|
7
|
-
//# sourceMappingURL=connection-api-DftK7eHo.d.mts.map
|