domainkit 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -26
- package/dist/index.d.mts +639 -187
- package/dist/index.mjs +301 -300
- package/dist/index.mjs.map +1 -1
- package/dist/promise.d.mts +464 -0
- package/dist/promise.mjs +636 -0
- package/dist/promise.mjs.map +1 -0
- package/dist/{resolver-CxE-VDw4.mjs → resolver-CvK7JoJM.mjs} +401 -54
- package/dist/resolver-CvK7JoJM.mjs.map +1 -0
- package/dist/{resolver-Dc0hwV-J.d.mts → resolver-uqe1h5Vz.d.mts} +1513 -25
- package/dist/testing.d.mts +4 -5
- package/dist/testing.mjs +17 -3
- package/dist/testing.mjs.map +1 -1
- package/dist/verify-B00c81-n.mjs +2420 -0
- package/dist/verify-B00c81-n.mjs.map +1 -0
- package/dist/{verify-Dls29YC-.d.mts → verify-CkgVrwyl.d.mts} +318 -21
- package/package.json +6 -30
- package/dist/auth-BR-19zj-.mjs +0 -738
- package/dist/auth-BR-19zj-.mjs.map +0 -1
- package/dist/auth-g-waCHcz.mjs +0 -671
- package/dist/auth-g-waCHcz.mjs.map +0 -1
- package/dist/authorization-OeaSR47S.mjs +0 -284
- package/dist/authorization-OeaSR47S.mjs.map +0 -1
- package/dist/canonical-json-CpvqGMcr.mjs +0 -57
- package/dist/canonical-json-CpvqGMcr.mjs.map +0 -1
- package/dist/cloudflare-BrZPU9li.d.mts +0 -32
- package/dist/cloudflare-CGmasR8A.mjs +0 -69
- package/dist/cloudflare-CGmasR8A.mjs.map +0 -1
- package/dist/cloudflare.d.mts +0 -3
- package/dist/cloudflare.mjs +0 -2
- package/dist/connection-BfkloPZy.d.mts +0 -186
- package/dist/connection-BwtOwpH6.mjs +0 -195
- package/dist/connection-BwtOwpH6.mjs.map +0 -1
- package/dist/connection-CjNQe_E-.mjs +0 -58
- package/dist/connection-CjNQe_E-.mjs.map +0 -1
- package/dist/connection-api-DNuEZ_jR.d.mts +0 -7
- package/dist/dns-record-BLeqo56C.mjs +0 -289
- package/dist/dns-record-BLeqo56C.mjs.map +0 -1
- package/dist/effect-cloudflare.d.mts +0 -2
- package/dist/effect-cloudflare.mjs +0 -2
- package/dist/effect-vercel.d.mts +0 -2
- package/dist/effect-vercel.mjs +0 -2
- package/dist/effect.d.mts +0 -36
- package/dist/effect.mjs +0 -51
- package/dist/effect.mjs.map +0 -1
- package/dist/index-BHWRTThN.d.mts +0 -159
- package/dist/index-D3PVknwE.d.mts +0 -145
- package/dist/resolver-CxE-VDw4.mjs.map +0 -1
- package/dist/vercel-BsNDu4Np.d.mts +0 -31
- package/dist/vercel-CfoJaaCu.mjs +0 -60
- package/dist/vercel-CfoJaaCu.mjs.map +0 -1
- package/dist/vercel.d.mts +0 -3
- package/dist/vercel.mjs +0 -2
- package/dist/verify-BKbvq7IN.mjs +0 -642
- package/dist/verify-BKbvq7IN.mjs.map +0 -1
- package/dist/zone-discovery-BPnH3sLU.d.mts +0 -1397
- package/dist/zones-DKHTpX9C.mjs +0 -19
- package/dist/zones-DKHTpX9C.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-g-waCHcz.mjs","names":["S","decode","DomainName.decode","DnsRecord.decode","failure","S","DnsRecord.Opaque","DnsProvider.Error","failure","Protocol.TeamListEnvelope","Protocol.DomainListEnvelope","Protocol.DomainConfig","Protocol.DomainEnvelope","DomainName.decode","Protocol.RecordListEnvelope","Records.decode","Records.encode","DnsProvider.Error","Protocol.CreateRecordEnvelope","Protocol.UserEnvelope","S","Protocol.ErrorEnvelope","Context","S","ProviderContext.codec","Protocol.ErrorEnvelope","Protocol.IntegrationToken","Secret.make","Client.make","Connection.Error","DnsProvider.Error"],"sources":["../src/providers/vercel/protocol.ts","../src/providers/vercel/records.ts","../src/providers/vercel/client.ts","../src/providers/vercel/auth.ts"],"sourcesContent":["import { Schema as S } from \"effect\";\n\nexport const Pagination = S.Struct({\n count: S.Number,\n next: S.NullOr(S.Number),\n prev: S.NullOr(S.Number),\n});\nexport interface Pagination extends S.Schema.Type<typeof Pagination> {}\n\nexport const ErrorDetail = S.Struct({\n code: S.String,\n message: S.String,\n limit: S.optionalKey(\n S.Struct({\n remaining: S.Number,\n reset: S.optionalKey(S.Number),\n resetMs: S.optionalKey(S.Number),\n total: S.Number,\n }),\n ),\n});\nexport interface ErrorDetail extends S.Schema.Type<typeof ErrorDetail> {}\n\nexport const ErrorEnvelope = S.Struct({ error: ErrorDetail });\n\nexport const User = S.Struct({\n id: S.String,\n name: S.NullOr(S.String),\n username: S.String,\n});\nexport interface User extends S.Schema.Type<typeof User> {}\n\nexport const UserEnvelope = S.Struct({ user: User });\n\nexport const Team = S.Struct({\n id: S.String,\n name: S.NullOr(S.String),\n slug: S.String,\n});\nexport interface Team extends S.Schema.Type<typeof Team> {}\n\nexport const TeamListEnvelope = S.Struct({\n pagination: Pagination,\n teams: S.Array(Team),\n});\n\nexport const Domain = S.Struct({\n id: S.String,\n intendedNameservers: S.Array(S.String),\n name: S.String,\n nameservers: S.Array(S.String),\n serviceType: S.Literals([\"zeit.world\", \"external\", \"na\"]),\n teamId: S.NullOr(S.String),\n userId: S.String,\n verified: S.Boolean,\n zone: S.optionalKey(S.Boolean),\n});\nexport interface Domain extends S.Schema.Type<typeof Domain> {}\n\nexport const DomainConfig = S.Struct({\n misconfigured: S.Boolean,\n serviceType: S.Literals([\"zeit.world\", \"external\", \"na\"]),\n});\nexport interface DomainConfig extends S.Schema.Type<typeof DomainConfig> {}\n\nexport const DomainEnvelope = S.Struct({ domain: Domain });\n\nexport const DomainListEnvelope = S.Struct({\n domains: S.Array(Domain),\n pagination: Pagination,\n});\n\nexport const Record = S.Struct({\n id: S.String,\n mxPriority: S.optionalKey(S.Number),\n name: S.String,\n priority: S.optionalKey(S.Number),\n ttl: S.optionalKey(S.Number),\n type: S.String,\n value: S.String,\n});\nexport interface Record extends S.Schema.Type<typeof Record> {}\n\nexport const RecordListEnvelope = S.Struct({\n pagination: S.optionalKey(Pagination),\n records: S.Array(Record),\n});\n\nexport const CreateRecordEnvelope = S.Struct({\n uid: S.String,\n updated: S.optionalKey(S.Number),\n});\n\nexport const IntegrationToken = S.Struct({\n access_token: S.String,\n installation_id: S.optionalKey(S.String),\n team_id: S.NullOr(S.String),\n token_type: S.optionalKey(S.String),\n user_id: S.String,\n});\nexport interface IntegrationToken extends S.Schema.Type<typeof IntegrationToken> {}\n","import { Effect, Schema as S } from \"effect\";\n\nimport * as DomainName from \"../../domain/domain-name.ts\";\nimport * as DnsRecord from \"../../domain/dns-record.ts\";\nimport * as DnsProvider from \"../../provider/provider.ts\";\nimport type * as Protocol from \"./protocol.ts\";\n\nexport type CreateBody = Readonly<Record<string, unknown>>;\n\nexport const decode = Effect.fn(\"VercelRecords.decode\")(\n (zone: DomainName.DomainName, record: Protocol.Record) =>\n Effect.gen(function* () {\n const absolute = absoluteNameCandidate(zone, record.name);\n const name = yield* DomainName.decode(absolute).pipe(\n Effect.match({ onFailure: () => null, onSuccess: (value) => value }),\n );\n if (name === null) return yield* decodeOpaque(record, absolute);\n const common = {\n metadata: {\n ownership: \"provider\",\n provenance: \"vercel\",\n purpose: \"existing DNS record\",\n },\n name,\n policy: record.type === \"CNAME\" ? \"exclusive\" : \"append\",\n ttl: record.ttl ?? 60,\n } as const;\n const fromRecord = (input: unknown) =>\n DnsRecord.decode(input).pipe(\n Effect.mapError((cause) => failure(\"decodeRecord\", cause.message)),\n );\n\n switch (record.type) {\n case \"A\":\n case \"AAAA\":\n return yield* fromRecord({ ...common, _tag: record.type, address: record.value });\n case \"CNAME\":\n case \"NS\":\n return yield* fromRecord({ ...common, _tag: record.type, target: record.value });\n case \"TXT\":\n return yield* fromRecord({ ...common, _tag: \"TXT\", value: record.value });\n case \"MX\":\n return yield* fromRecord({\n ...common,\n _tag: \"MX\",\n exchange: record.value,\n priority: record.mxPriority ?? record.priority,\n });\n case \"CAA\": {\n const match = record.value.match(\n /^(\\d{1,3})\\s+(issue|issuewild|iodef)\\s+(?:\"((?:\\\\.|[^\"])*)\"|(\\S.*))$/,\n );\n if (match === null) {\n return yield* Effect.fail(\n failure(\"decodeRecord\", \"Vercel CAA record has an invalid value\"),\n );\n }\n return yield* fromRecord({\n ...common,\n _tag: \"CAA\",\n flags: Number(match[1]),\n tag: match[2],\n value: unescapeQuoted(match[3] ?? match[4] ?? \"\"),\n });\n }\n case \"SRV\": {\n const parts = record.value.trim().split(/\\s+/);\n const [priority, weight, port, target] =\n parts.length === 4\n ? parts\n : [String(record.priority ?? \"\"), parts[0], parts[1], parts[2]];\n return yield* fromRecord({\n ...common,\n _tag: \"SRV\",\n port: Number(port),\n priority: Number(priority),\n target,\n weight: Number(weight),\n });\n }\n default:\n return yield* decodeOpaque(record, name);\n }\n }),\n);\n\nconst decodeOpaque = Effect.fn(\"VercelRecords.decodeOpaque\")(\n (record: Protocol.Record, name: string) =>\n S.decodeUnknownEffect(DnsRecord.Opaque)({\n _tag: \"Opaque\",\n name,\n providerRecordId: record.id,\n providerType: record.type,\n }).pipe(Effect.mapError((cause) => failure(\"decodeRecord\", cause.message))),\n);\n\nexport function encode(zone: DomainName.DomainName, record: DnsRecord.DnsRecord): CreateBody {\n const common = {\n name: relativeName(zone, record.name),\n ...(record.ttl === null ? {} : { ttl: record.ttl }),\n type: record._tag,\n };\n switch (record._tag) {\n case \"A\":\n case \"AAAA\":\n return { ...common, value: record.address };\n case \"CNAME\":\n case \"NS\":\n return { ...common, value: record.target };\n case \"TXT\":\n return { ...common, value: record.value };\n case \"MX\":\n return { ...common, mxPriority: record.priority, value: record.exchange };\n case \"CAA\":\n return {\n ...common,\n value: `${record.flags} ${record.tag} \"${escapeQuoted(record.value)}\"`,\n };\n case \"SRV\":\n return {\n ...common,\n srv: {\n port: record.port,\n priority: record.priority,\n target: record.target,\n weight: record.weight,\n },\n };\n }\n}\n\nfunction absoluteNameCandidate(zone: DomainName.DomainName, name: string): string {\n return name === \"\" || name === \"@\"\n ? zone\n : name === zone || name.endsWith(`.${zone}`)\n ? name\n : `${name}.${zone}`;\n}\n\nfunction relativeName(zone: DomainName.DomainName, name: DomainName.DomainName): string {\n if (name === zone) return \"\";\n const suffix = `.${zone}`;\n if (!name.endsWith(suffix)) {\n throw failure(\"encodeRecord\", `DNS record ${name} is outside Vercel zone ${zone}`, {\n reason: \"request\",\n });\n }\n return name.slice(0, -suffix.length);\n}\n\nfunction escapeQuoted(value: string): string {\n return value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\nfunction unescapeQuoted(value: string): string {\n return value.replace(/\\\\([\\\\\"])/g, \"$1\");\n}\n\nfunction failure(\n operation: string,\n message: string,\n fields: Partial<Pick<DnsProvider.Error, \"reason\">> = {},\n): DnsProvider.Error {\n return new DnsProvider.Error({\n message,\n operation,\n providerId: \"vercel\",\n reason: fields.reason ?? \"response\",\n });\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport type * as ProviderAuth from \"../../auth/manifest.ts\";\nimport type * as Secret from \"../../auth/secret.ts\";\nimport * as DomainName from \"../../domain/domain-name.ts\";\nimport type * as DnsRecord from \"../../domain/dns-record.ts\";\nimport type * as ZoneDiscovery from \"../../discovery/zone-discovery.ts\";\nimport * as DnsProvider from \"../../provider/provider.ts\";\nimport * as Protocol from \"./protocol.ts\";\nimport * as Records from \"./records.ts\";\n\nexport type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\n/** Selects whether Vercel requests operate on a personal account or a team. */\nexport type AccountContext =\n | { readonly _tag: \"personal\" }\n | { readonly _tag: \"team\"; readonly teamId: string };\n\n/** Configuration for an Effect-native Vercel authoritative-DNS client. */\nexport interface Options {\n readonly baseUrl?: string;\n /** Capabilities the host required when issuing or authorizing this credential. */\n readonly capabilities: ProviderAuth.TokenValidation[\"capabilities\"];\n readonly context: AccountContext;\n readonly fetch?: Fetch;\n readonly token: Secret.Value;\n}\n\nexport interface ListZonesInput {\n readonly name?: DomainName.DomainName;\n}\n\n/** A Vercel account visible to the supplied credential. */\nexport interface Account {\n readonly id: string;\n readonly name: string;\n readonly type: \"personal\" | \"team\";\n}\n\n/** A Vercel-managed authoritative zone with normalized nameserver evidence. */\nexport interface Zone {\n readonly accountId: string;\n readonly id: string;\n readonly name: DomainName.DomainName;\n readonly nameservers: ReadonlyArray<DomainName.DomainName>;\n readonly status: \"active\" | \"pending\";\n}\n\nexport interface Interface extends DnsProvider.Interface {\n readonly listAccounts: () => Effect.Effect<ReadonlyArray<Account>, DnsProvider.Error>;\n readonly listZones: (\n input?: ListZonesInput,\n ) => Effect.Effect<ReadonlyArray<Zone>, DnsProvider.Error>;\n readonly validateToken: () => Effect.Effect<ProviderAuth.TokenValidation, DnsProvider.Error>;\n}\n\n/** Exposes Vercel zone lookup as the optional provider discovery capability. */\nexport function discovery(client: Interface): ZoneDiscovery.Source {\n return {\n listZones: (name) => client.listZones({ name }),\n provider: client,\n };\n}\n\n/** Creates an Effect-native Vercel client without owning the credential lifecycle. */\nexport function make(options: Options): Interface {\n const fetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"https://api.vercel.com\").replace(/\\/$/, \"\");\n\n const withContext = (path: string, values: Readonly<Record<string, string>> = {}) => {\n const url = new URL(`${baseUrl}${path}`);\n for (const [key, value] of Object.entries(values)) url.searchParams.set(key, value);\n if (options.context._tag === \"team\") url.searchParams.set(\"teamId\", options.context.teamId);\n return url;\n };\n\n const request = Effect.fn(\"VercelClient.request\")(\n (url: URL, operation: string, init?: RequestInit) =>\n Effect.gen(function* () {\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(url, {\n ...init,\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${options.token.expose()}`,\n ...(init?.body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n ...init?.headers,\n },\n }),\n catch: () => failure(operation, \"Vercel request failed\", { reason: \"transport\" }),\n });\n const body = yield* Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () =>\n failure(\n operation,\n response.ok\n ? \"Vercel returned a non-JSON response\"\n : `Vercel request failed with HTTP ${response.status}`,\n {\n reason: response.ok ? \"response\" : reason(response.status),\n ...rateLimit(response),\n status: response.status,\n },\n ),\n });\n if (!response.ok) return yield* Effect.fail(apiFailure(body, operation, response));\n return { body, response } as const;\n }),\n );\n\n const allTeams = Effect.fn(\"VercelClient.allTeams\")(() =>\n Effect.gen(function* () {\n const teams: Array<Protocol.Team> = [];\n let until: number | null = null;\n while (true) {\n const url = new URL(`${baseUrl}/v2/teams`);\n url.searchParams.set(\"limit\", \"100\");\n if (until !== null) url.searchParams.set(\"until\", String(until));\n const { body, response } = yield* request(url, \"listAccounts\");\n const envelope = yield* decode(Protocol.TeamListEnvelope, body, \"listAccounts\", response);\n teams.push(...envelope.teams);\n if (envelope.pagination.next === null) return teams;\n until = envelope.pagination.next;\n }\n }),\n );\n\n const allDomains = Effect.fn(\"VercelClient.allDomains\")(() =>\n Effect.gen(function* () {\n const domains: Array<Protocol.Domain> = [];\n let until: number | null = null;\n while (true) {\n const values: Record<string, string> = { limit: \"100\" };\n if (until !== null) values.until = String(until);\n const { body, response } = yield* request(withContext(\"/v5/domains\", values), \"listZones\");\n const envelope = yield* decode(Protocol.DomainListEnvelope, body, \"listZones\", response);\n domains.push(...envelope.domains);\n if (envelope.pagination.next === null) return domains;\n until = envelope.pagination.next;\n }\n }),\n );\n\n const discoverZone = Effect.fn(\"VercelClient.discoverZone\")((name: DomainName.DomainName) =>\n Effect.gen(function* () {\n const configResult = yield* request(\n withContext(`/v6/domains/${encodeURIComponent(name)}/config`),\n \"resolveZone\",\n );\n const config = yield* decode(\n Protocol.DomainConfig,\n configResult.body,\n \"resolveZone\",\n configResult.response,\n );\n const domainResult = yield* request(\n withContext(`/v5/domains/${encodeURIComponent(name)}`),\n \"resolveZone\",\n );\n const envelope = yield* decode(\n Protocol.DomainEnvelope,\n domainResult.body,\n \"resolveZone\",\n domainResult.response,\n );\n if (!hasDnsStorage(envelope.domain, config.serviceType)) {\n return null;\n }\n return envelope.domain;\n }).pipe(\n Effect.catchTag(\"ProviderError\", (cause) =>\n cause.reason === \"not_found\" ? Effect.succeed(null) : Effect.fail(cause),\n ),\n ),\n );\n\n const resolveZone = Effect.fn(\"VercelClient.resolveZone\")((name: DomainName.DomainName) =>\n Effect.gen(function* () {\n const domain = yield* discoverZone(name);\n if (domain === null) {\n return yield* Effect.fail(\n failure(\n \"resolveZone\",\n `Vercel zone ${name} is not configured for authoritative DNS in the selected account`,\n { reason: \"not_found\" },\n ),\n );\n }\n return yield* DomainName.decode(domain.name).pipe(\n Effect.mapError((cause) =>\n failure(\"resolveZone\", `Vercel returned an invalid storage zone: ${cause.message}`),\n ),\n );\n }),\n );\n\n const listRecords = Effect.fn(\"VercelClient.listRecords\")((zoneName: DomainName.DomainName) =>\n Effect.gen(function* () {\n const storageZone = yield* resolveZone(zoneName);\n const records: Array<DnsRecord.Observed> = [];\n let until: number | null = null;\n while (true) {\n const values: Record<string, string> = { limit: \"100\" };\n if (until !== null) values.until = String(until);\n const { body, response } = yield* request(\n withContext(`/v5/domains/${encodeURIComponent(storageZone)}/records`, values),\n \"listRecords\",\n );\n const envelope = yield* decode(Protocol.RecordListEnvelope, body, \"listRecords\", response);\n records.push(\n ...(yield* Effect.forEach(envelope.records, (record) =>\n Records.decode(storageZone, record),\n )),\n );\n const next = envelope.pagination?.next ?? null;\n if (next === null) {\n return records.filter(\n (record) => record.name === zoneName || record.name.endsWith(`.${zoneName}`),\n );\n }\n until = next;\n }\n }),\n );\n\n const createRecord = Effect.fn(\"VercelClient.createRecord\")(\n (zoneName: DomainName.DomainName, record: DnsRecord.DnsRecord) =>\n Effect.gen(function* () {\n const storageZone = yield* resolveZone(zoneName);\n const body = yield* Effect.try({\n try: () => Records.encode(storageZone, record),\n catch: (cause) =>\n cause instanceof DnsProvider.Error\n ? cause\n : failure(\"createRecord\", \"Vercel record could not be encoded\", {\n reason: \"request\",\n }),\n });\n const result = yield* request(\n withContext(`/v2/domains/${encodeURIComponent(storageZone)}/records`),\n \"createRecord\",\n { body: JSON.stringify(body), method: \"POST\" },\n );\n const envelope = yield* decode(\n Protocol.CreateRecordEnvelope,\n result.body,\n \"createRecord\",\n result.response,\n );\n return { providerRecordId: envelope.uid };\n }),\n );\n\n const getRecord = Effect.fn(\"VercelClient.getRecord\")(\n (zoneName: DomainName.DomainName, providerRecordId: string) =>\n Effect.gen(function* () {\n const storageZone = yield* resolveZone(zoneName);\n let until: number | null = null;\n while (true) {\n const values: Record<string, string> = { limit: \"100\" };\n if (until !== null) values.until = String(until);\n const { body, response } = yield* request(\n withContext(`/v5/domains/${encodeURIComponent(storageZone)}/records`, values),\n \"getRecord\",\n );\n const envelope = yield* decode(Protocol.RecordListEnvelope, body, \"getRecord\", response);\n const record = envelope.records.find(({ id }) => id === providerRecordId);\n if (record !== undefined) return yield* Records.decode(storageZone, record);\n const next = envelope.pagination?.next ?? null;\n if (next === null) return null;\n until = next;\n }\n }),\n );\n\n const deleteRecord = Effect.fn(\"VercelClient.deleteRecord\")(\n (zoneName: DomainName.DomainName, providerRecordId: string) =>\n Effect.gen(function* () {\n const storageZone = yield* resolveZone(zoneName);\n yield* request(\n withContext(\n `/v2/domains/${encodeURIComponent(storageZone)}/records/${encodeURIComponent(providerRecordId)}`,\n ),\n \"deleteRecord\",\n { method: \"DELETE\" },\n );\n }),\n );\n\n const listAccounts = Effect.fn(\"VercelClient.listAccounts\")(() =>\n Effect.gen(function* () {\n const userResult = yield* request(new URL(`${baseUrl}/v2/user`), \"listAccounts\");\n const { user } = yield* decode(\n Protocol.UserEnvelope,\n userResult.body,\n \"listAccounts\",\n userResult.response,\n );\n const teams = yield* allTeams();\n return [\n { id: user.id, name: user.name ?? user.username, type: \"personal\" as const },\n ...teams.map((team) => ({\n id: team.id,\n name: team.name ?? team.slug,\n type: \"team\" as const,\n })),\n ];\n }),\n );\n\n const listZones = Effect.fn(\"VercelClient.listZones\")((input: ListZonesInput = {}) =>\n Effect.gen(function* () {\n const domains = (yield* allDomains()).filter(\n (domain) =>\n hasDnsStorage(domain) && (input.name === undefined || domain.name === input.name),\n );\n if (domains.length > 0 || input.name === undefined) {\n return yield* Effect.forEach(domains, projectZone);\n }\n const discovered = yield* discoverZone(input.name);\n return discovered === null ? [] : [yield* projectZone(discovered)];\n }),\n );\n\n const validateToken = Effect.fn(\"VercelClient.validateToken\")(() =>\n Effect.gen(function* () {\n let accountId: string;\n if (options.context._tag === \"team\") {\n yield* allDomains();\n accountId = options.context.teamId;\n } else {\n const result = yield* request(new URL(`${baseUrl}/v2/user`), \"validateToken\");\n const { user } = yield* decode(\n Protocol.UserEnvelope,\n result.body,\n \"validateToken\",\n result.response,\n );\n accountId = user.id;\n }\n return {\n accountId,\n capabilities: options.capabilities,\n expiresAt: null,\n scopes: [],\n };\n }),\n );\n\n return {\n id: \"vercel\",\n createRecord,\n deleteRecord,\n getRecord,\n listAccounts,\n listRecords,\n listZones,\n validateToken,\n };\n}\n\nfunction hasDnsStorage(\n domain: Protocol.Domain,\n configuredServiceType: Protocol.DomainConfig[\"serviceType\"] = domain.serviceType,\n): boolean {\n return (\n configuredServiceType === \"zeit.world\" ||\n domain.zone === true ||\n domain.intendedNameservers.length > 0\n );\n}\n\nconst projectZone = Effect.fn(\"VercelClient.projectZone\")((domain: Protocol.Domain) =>\n Effect.gen(function* () {\n const name = yield* DomainName.decode(domain.name).pipe(\n Effect.mapError((cause) => failure(\"listZones\", cause.message, { reason: \"response\" })),\n );\n const nameservers = yield* Effect.forEach(domain.intendedNameservers, (nameserver) =>\n DomainName.decode(nameserver).pipe(\n Effect.mapError((cause) => failure(\"listZones\", cause.message, { reason: \"response\" })),\n ),\n );\n return {\n accountId: domain.teamId ?? domain.userId,\n id: domain.id,\n name,\n nameservers,\n status: domain.verified ? \"active\" : \"pending\",\n } as const;\n }),\n);\n\nfunction decode<A>(\n schema: S.ConstraintCodec<A, unknown, never, unknown>,\n input: unknown,\n operation: string,\n response: Response,\n): Effect.Effect<A, DnsProvider.Error> {\n return S.decodeUnknownEffect(schema)(input).pipe(\n Effect.mapError((cause) =>\n failure(operation, `Vercel response did not match its API contract: ${cause.message}`, {\n reason: \"response\",\n status: response.status,\n }),\n ),\n );\n}\n\nfunction apiFailure(input: unknown, operation: string, response: Response): DnsProvider.Error {\n const detail = S.decodeUnknownOption(Protocol.ErrorEnvelope)(input);\n return failure(\n operation,\n detail._tag === \"Some\"\n ? detail.value.error.message\n : `Vercel request failed with HTTP ${response.status}`,\n {\n ...(detail._tag === \"Some\" ? { code: detail.value.error.code } : {}),\n reason: reason(response.status, detail._tag === \"Some\" ? detail.value.error.code : undefined),\n ...rateLimit(response, detail._tag === \"Some\" ? detail.value.error : undefined),\n status: response.status,\n },\n );\n}\n\nfunction reason(status: number, code?: string): DnsProvider.ErrorReason {\n if (status === 401 || code === \"invalid_token\") return \"authentication\";\n if (status === 403) return \"authorization\";\n if (status === 404 || code === \"not_found\") return \"not_found\";\n if (status === 409 || code === \"conflict\") return \"conflict\";\n if (status === 429 || code === \"rate_limited\") return \"rate_limit\";\n if (status >= 500) return \"response\";\n return \"request\";\n}\n\nfunction rateLimit(\n response: Response,\n detail?: Protocol.ErrorDetail,\n): Partial<Pick<DnsProvider.Error, \"retryAfterMs\">> {\n const resetMs = detail?.limit?.resetMs;\n const header = response.headers.get(\"x-ratelimit-reset\");\n const reset = resetMs ?? (header === null ? undefined : Number(header) * 1_000);\n return reset === undefined || !Number.isFinite(reset)\n ? {}\n : { retryAfterMs: Math.max(0, reset - Date.now()) };\n}\n\nfunction failure(\n operation: string,\n message: string,\n fields: Partial<Pick<DnsProvider.Error, \"code\" | \"reason\" | \"retryAfterMs\" | \"status\">> = {},\n): DnsProvider.Error {\n return new DnsProvider.Error({ ...fields, message, operation, providerId: \"vercel\" });\n}\n","import { Clock, Effect, Schema as S } from \"effect\";\n\nimport * as Connection from \"../../auth/connect.ts\";\nimport * as ProviderAuthorization from \"../../auth/authorization.ts\";\nimport type * as ProviderAuth from \"../../auth/manifest.ts\";\nimport * as ProviderContext from \"../../auth/provider-context.ts\";\nimport * as Secret from \"../../auth/secret.ts\";\nimport * as DnsProvider from \"../../provider/provider.ts\";\nimport * as Client from \"./client.ts\";\nimport * as Protocol from \"./protocol.ts\";\n\nconst Context = S.TaggedUnion({\n personal: { installationId: S.NullOr(S.String) },\n team: { installationId: S.NullOr(S.String), teamId: S.String },\n});\nexport type Context = typeof Context.Type;\nexport const contextCodec = ProviderContext.codec(\"vercel.v1\", Context);\n\n/** Describes Vercel's caller-created personal access-token method. */\nexport function tokenMethod(\n capabilities: ProviderAuth.TokenValidation[\"capabilities\"],\n): Extract<ProviderAuth.Manifest[\"methods\"][number], { readonly _tag: \"token\" }> {\n return {\n _tag: \"token\",\n capabilities: [...capabilities],\n instructionsUrl: \"https://vercel.com/account/settings/tokens\",\n };\n}\n\nexport interface IntegrationMethodOptions {\n readonly capabilities: ProviderAuth.TokenValidation[\"capabilities\"];\n readonly slug: string;\n}\n\n/** Describes Vercel's provider-specific integration installation flow. */\nexport function integrationMethod(\n options: IntegrationMethodOptions,\n): ProviderAuth.IntegrationMethod {\n return {\n _tag: \"integration\",\n capabilities: [...options.capabilities],\n installUrl: `https://vercel.com/integrations/${encodeURIComponent(options.slug)}/new`,\n tokenEndpoint: \"https://api.vercel.com/oauth/access_token\",\n };\n}\n\n/** Creates the Vercel token and integration authorization manifest. */\nexport function manifest(options: IntegrationMethodOptions): ProviderAuth.Manifest {\n return {\n methods: [tokenMethod(options.capabilities), integrationMethod(options)],\n providerId: \"vercel\",\n };\n}\n\nexport interface ExchangeCodeOptions {\n readonly baseUrl?: string;\n readonly clientId: string;\n readonly clientSecret: Secret.Value;\n readonly code: Secret.Value;\n readonly fetch?: Client.Fetch;\n readonly redirectUri: string;\n}\n\nexport interface IntegrationCredential {\n readonly accessToken: Secret.Value;\n readonly context: Client.AccountContext;\n readonly installationId: string | null;\n readonly userId: string;\n}\n\n/** Exchanges Vercel's one-time integration code and preserves its account context. */\nexport const exchangeCode = Effect.fn(\"VercelAuth.exchangeCode\")((options: ExchangeCodeOptions) =>\n Effect.gen(function* () {\n const fetch = options.fetch ?? globalThis.fetch;\n const baseUrl = (options.baseUrl ?? \"https://api.vercel.com\").replace(/\\/$/, \"\");\n const body = new URLSearchParams({\n client_id: options.clientId,\n client_secret: options.clientSecret.expose(),\n code: options.code.expose(),\n redirect_uri: options.redirectUri,\n });\n const response = yield* Effect.tryPromise({\n try: () =>\n fetch(`${baseUrl}/oauth/access_token`, {\n body,\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n method: \"POST\",\n }),\n catch: () => failure(\"exchangeCode\", \"Vercel token exchange failed\", \"transport\"),\n });\n const input = yield* Effect.tryPromise({\n try: () => response.json() as Promise<unknown>,\n catch: () =>\n failure(\n \"exchangeCode\",\n response.ok\n ? \"Vercel returned a non-JSON token response\"\n : `Vercel token exchange failed with HTTP ${response.status}`,\n response.ok ? \"response\" : response.status === 401 ? \"authentication\" : \"request\",\n response.status,\n ),\n });\n if (!response.ok) {\n const detail = S.decodeUnknownOption(Protocol.ErrorEnvelope)(input);\n return yield* Effect.fail(\n failure(\n \"exchangeCode\",\n detail._tag === \"Some\"\n ? detail.value.error.message\n : `Vercel token exchange failed with HTTP ${response.status}`,\n response.status === 401 ? \"authentication\" : \"request\",\n response.status,\n detail._tag === \"Some\" ? detail.value.error.code : undefined,\n ),\n );\n }\n const token = yield* S.decodeUnknownEffect(Protocol.IntegrationToken)(input).pipe(\n Effect.mapError((cause) =>\n failure(\n \"exchangeCode\",\n `Vercel token response did not match its API contract: ${cause.message}`,\n \"response\",\n response.status,\n ),\n ),\n );\n return {\n accessToken: Secret.make(token.access_token),\n context:\n token.team_id === null\n ? ({ _tag: \"personal\" } as const)\n : ({ _tag: \"team\", teamId: token.team_id } as const),\n installationId: token.installation_id ?? null,\n userId: token.user_id,\n };\n }),\n);\n\nexport interface TokenConnectionOptions extends Omit<Client.Options, \"token\"> {\n readonly token: Secret.Value;\n}\n\n/** Creates a provider-independent token connection method backed by Vercel validation. */\nexport function tokenConnectionMethod(\n options: TokenConnectionOptions,\n): Extract<Connection.Method, { readonly _tag: \"Token\" }> {\n const requiredCapabilities = [...options.capabilities];\n return Connection.Method.Token({\n authenticate: Effect.fn(\"VercelAuth.authenticateToken\")(function* (token) {\n const validated = yield* Client.make({ ...options, token }).validateToken();\n const observedAt = new Date(yield* Clock.currentTimeMillis);\n return {\n capabilityEvidence: validated.capabilities.map((capability) => ({\n capability,\n evidence: ProviderAuthorization.Evidence.Introspected({ observedAt }),\n })),\n credential: { accessToken: token, refreshToken: null, tokenType: \"bearer\" },\n expiresAt: validated.expiresAt,\n providerAccountId: validated.accountId,\n providerContext: yield* contextCodec.encode(\n options.context._tag === \"team\"\n ? { _tag: \"team\", installationId: null, teamId: options.context.teamId }\n : { _tag: \"personal\", installationId: null },\n ),\n scopes: [...validated.scopes],\n } satisfies Connection.Authentication;\n }),\n providerId: \"vercel\",\n requiredCapabilities,\n token: options.token,\n });\n}\n\n/** Converts a completed Vercel Integration exchange into canonical connection authentication. */\nexport const integrationAuthentication = Effect.fn(\"VercelAuth.integrationAuthentication\")(\n function* (\n options: ExchangeCodeOptions & {\n readonly capabilities: ReadonlyArray<ProviderAuthorization.Capability>;\n },\n ) {\n const exchanged = yield* exchangeCode(options);\n const observedAt = new Date(yield* Clock.currentTimeMillis);\n return {\n capabilityEvidence: options.capabilities.map((capability) => ({\n capability,\n evidence: ProviderAuthorization.Evidence.Introspected({ observedAt }),\n })),\n credential: {\n accessToken: exchanged.accessToken,\n refreshToken: null,\n tokenType: \"bearer\",\n },\n expiresAt: null,\n providerAccountId:\n exchanged.context._tag === \"team\" ? exchanged.context.teamId : exchanged.userId,\n providerContext: yield* contextCodec.encode(\n exchanged.context._tag === \"team\"\n ? {\n _tag: \"team\",\n installationId: exchanged.installationId,\n teamId: exchanged.context.teamId,\n }\n : { _tag: \"personal\", installationId: exchanged.installationId },\n ),\n scopes: [],\n } satisfies Connection.Authentication;\n },\n);\n\nexport interface IntegrationFlowOptions\n extends Omit<ExchangeCodeOptions, \"code\">, IntegrationMethodOptions {}\n\n/** Creates Vercel Integration's implementation of the common interactive connection capability. */\nexport function integrationFlow(options: IntegrationFlowOptions): Connection.InteractiveFlow {\n const method = integrationMethod(options);\n const Payload = S.fromJsonString(S.Struct({ state: S.String }));\n return {\n complete: Effect.fn(\"VercelAuth.integrationFlow.complete\")(function* (payload, callbackUrl) {\n const continuation = yield* S.decodeUnknownEffect(Payload)(payload.expose()).pipe(\n Effect.mapError(\n () =>\n new Connection.Error({\n category: \"authorization\",\n message: \"Vercel Integration continuation payload is invalid\",\n operation: \"VercelAuth.integrationFlow.complete\",\n retry: \"after-user-action\",\n }),\n ),\n );\n const code = callbackUrl.searchParams.get(\"code\");\n if (callbackUrl.searchParams.get(\"state\") !== continuation.state || code === null) {\n return yield* new Connection.Error({\n category: \"authorization\",\n message: \"Vercel Integration callback does not match its continuation\",\n operation: \"VercelAuth.integrationFlow.complete\",\n retry: \"after-user-action\",\n });\n }\n return yield* integrationAuthentication({\n ...(options.baseUrl === undefined ? {} : { baseUrl: options.baseUrl }),\n capabilities: options.capabilities,\n clientId: options.clientId,\n clientSecret: options.clientSecret,\n code: Secret.make(code),\n ...(options.fetch === undefined ? {} : { fetch: options.fetch }),\n redirectUri: options.redirectUri,\n });\n }),\n method: \"integration\",\n providerId: \"vercel\",\n requiredCapabilities: [...options.capabilities],\n start: (continuationId) => {\n const authorizationUrl = new URL(method.installUrl);\n authorizationUrl.searchParams.set(\"source\", \"external\");\n authorizationUrl.searchParams.set(\"state\", continuationId);\n return Effect.succeed({\n authorizationUrl,\n payload: Secret.make(JSON.stringify({ state: continuationId })),\n });\n },\n };\n}\n\nfunction failure(\n operation: string,\n message: string,\n reason: DnsProvider.ErrorReason,\n status?: number,\n code?: string,\n): DnsProvider.Error {\n return new DnsProvider.Error({\n ...(code === undefined ? {} : { code }),\n message,\n operation,\n providerId: \"vercel\",\n reason,\n ...(status === undefined ? {} : { status }),\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { M as Service, k as Error$2 } from "./dns-record-BLeqo56C.mjs";
|
|
3
|
-
import { Clock, Crypto, Data, Effect, Schema } from "effect";
|
|
4
|
-
//#region src/auth/connect.ts
|
|
5
|
-
const Method = Data.taggedEnum();
|
|
6
|
-
const StartResult = Data.taggedEnum();
|
|
7
|
-
var Error$1 = class extends Schema.TaggedError()("ConnectionError", {
|
|
8
|
-
category: Schema.Literals([
|
|
9
|
-
"authorization",
|
|
10
|
-
"provider",
|
|
11
|
-
"validation"
|
|
12
|
-
]),
|
|
13
|
-
message: Schema.String,
|
|
14
|
-
operation: Schema.String,
|
|
15
|
-
retry: Schema.Literals([
|
|
16
|
-
"never",
|
|
17
|
-
"after-user-action",
|
|
18
|
-
"safe",
|
|
19
|
-
"unknown"
|
|
20
|
-
])
|
|
21
|
-
}) {};
|
|
22
|
-
const mergeGrant = (current, requested) => {
|
|
23
|
-
if (current === void 0) return requested;
|
|
24
|
-
if (current._tag === "account" || requested._tag === "account") return { _tag: "account" };
|
|
25
|
-
return {
|
|
26
|
-
_tag: "domains",
|
|
27
|
-
domains: [.../* @__PURE__ */ new Set([...current.domains, ...requested.domains])]
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
const persist = Effect.fn("Connection.persist")(function* (input) {
|
|
31
|
-
const repository = yield* Service;
|
|
32
|
-
const crypto = yield* Crypto.Crypto;
|
|
33
|
-
const now = new Date(yield* Clock.currentTimeMillis);
|
|
34
|
-
const missingCapability = input.requiredCapabilities.find((capability) => !input.authentication.capabilityEvidence.some((item) => item.capability === capability));
|
|
35
|
-
if (missingCapability !== void 0) return yield* new Error$1({
|
|
36
|
-
category: "authorization",
|
|
37
|
-
message: `Provider authorization lacks evidence for ${missingCapability}`,
|
|
38
|
-
operation: "Connection.persist",
|
|
39
|
-
retry: "after-user-action"
|
|
40
|
-
});
|
|
41
|
-
const existing = yield* repository.findByProviderAccount(input.providerId, input.authentication.providerAccountId);
|
|
42
|
-
const authorizationId = existing?.authorization.id ?? (yield* crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new Error$1({
|
|
43
|
-
category: "validation",
|
|
44
|
-
message: cause.message,
|
|
45
|
-
operation: "Connection.persist",
|
|
46
|
-
retry: "safe"
|
|
47
|
-
}))));
|
|
48
|
-
const existingBinding = existing?.bindings.find((binding) => binding.ownerId === input.ownerId);
|
|
49
|
-
const binding = {
|
|
50
|
-
authorizationId,
|
|
51
|
-
createdAt: existingBinding?.createdAt ?? now,
|
|
52
|
-
grant: mergeGrant(existingBinding?.grant, input.grant),
|
|
53
|
-
id: existingBinding?.id ?? (yield* crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new Error$1({
|
|
54
|
-
category: "validation",
|
|
55
|
-
message: cause.message,
|
|
56
|
-
operation: "Connection.persist",
|
|
57
|
-
retry: "safe"
|
|
58
|
-
})))),
|
|
59
|
-
ownerId: input.ownerId
|
|
60
|
-
};
|
|
61
|
-
const aggregate = {
|
|
62
|
-
authorization: {
|
|
63
|
-
authorizedById: input.authorizedById,
|
|
64
|
-
capabilityEvidence: [...input.authentication.capabilityEvidence],
|
|
65
|
-
createdAt: existing?.authorization.createdAt ?? now,
|
|
66
|
-
expiresAt: input.authentication.expiresAt,
|
|
67
|
-
id: authorizationId,
|
|
68
|
-
method: input.method,
|
|
69
|
-
providerAccountId: input.authentication.providerAccountId,
|
|
70
|
-
providerContext: input.authentication.providerContext,
|
|
71
|
-
providerId: input.providerId,
|
|
72
|
-
requiredCapabilities: [...input.requiredCapabilities],
|
|
73
|
-
revocation: { _tag: "Active" },
|
|
74
|
-
scopes: [...input.authentication.scopes]
|
|
75
|
-
},
|
|
76
|
-
bindings: [...existing?.bindings.filter((candidate) => candidate.id !== binding.id) ?? [], binding],
|
|
77
|
-
credential: input.authentication.credential
|
|
78
|
-
};
|
|
79
|
-
return yield* repository.connect(aggregate);
|
|
80
|
-
});
|
|
81
|
-
const start = Effect.fn("Connection.start")(function* (input) {
|
|
82
|
-
if (input.method._tag === "Interactive") {
|
|
83
|
-
const crypto = yield* Crypto.Crypto;
|
|
84
|
-
const now = yield* Clock.currentTimeMillis;
|
|
85
|
-
const continuationId = yield* crypto.randomUUIDv4.pipe(Effect.mapError((cause) => new Error$1({
|
|
86
|
-
category: "validation",
|
|
87
|
-
message: cause.message,
|
|
88
|
-
operation: "Connection.start",
|
|
89
|
-
retry: "safe"
|
|
90
|
-
})));
|
|
91
|
-
const started = yield* input.method.flow.start(continuationId);
|
|
92
|
-
yield* input.method.continuations.put({
|
|
93
|
-
authorizedById: input.authorizedById,
|
|
94
|
-
expiresAt: new Date(now + (input.method.ttlMs ?? 6e5)),
|
|
95
|
-
grant: input.grant,
|
|
96
|
-
id: continuationId,
|
|
97
|
-
method: input.method.flow.method,
|
|
98
|
-
ownerId: input.ownerId,
|
|
99
|
-
payload: started.payload,
|
|
100
|
-
providerId: input.method.flow.providerId,
|
|
101
|
-
requiredCapabilities: [...input.method.flow.requiredCapabilities]
|
|
102
|
-
});
|
|
103
|
-
return StartResult.Redirect({
|
|
104
|
-
authorizationUrl: started.authorizationUrl,
|
|
105
|
-
continuationId
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
const authentication = yield* input.method.authenticate(input.method.token);
|
|
109
|
-
const aggregate = yield* persist({
|
|
110
|
-
authentication,
|
|
111
|
-
authorizedById: input.authorizedById,
|
|
112
|
-
grant: input.grant,
|
|
113
|
-
method: "token",
|
|
114
|
-
ownerId: input.ownerId,
|
|
115
|
-
providerId: input.method.providerId,
|
|
116
|
-
requiredCapabilities: input.method.requiredCapabilities
|
|
117
|
-
});
|
|
118
|
-
return StartResult.Connected({ aggregate });
|
|
119
|
-
});
|
|
120
|
-
const complete = Effect.fn("Connection.complete")(function* (input) {
|
|
121
|
-
const continuation = yield* input.continuations.consume(input.continuationId, new Date(yield* Clock.currentTimeMillis));
|
|
122
|
-
if (continuation === null) return yield* new Error$1({
|
|
123
|
-
category: "authorization",
|
|
124
|
-
message: "Connection continuation is expired, unknown, or already consumed",
|
|
125
|
-
operation: "Connection.complete",
|
|
126
|
-
retry: "after-user-action"
|
|
127
|
-
});
|
|
128
|
-
if (continuation.providerId !== input.flow.providerId || continuation.method !== input.flow.method) return yield* new Error$1({
|
|
129
|
-
category: "authorization",
|
|
130
|
-
message: "Connection continuation does not match the provider flow",
|
|
131
|
-
operation: "Connection.complete",
|
|
132
|
-
retry: "never"
|
|
133
|
-
});
|
|
134
|
-
const authentication = yield* input.flow.complete(continuation.payload, input.callbackUrl);
|
|
135
|
-
return yield* persist({
|
|
136
|
-
authentication,
|
|
137
|
-
authorizedById: continuation.authorizedById,
|
|
138
|
-
grant: continuation.grant,
|
|
139
|
-
method: continuation.method,
|
|
140
|
-
ownerId: continuation.ownerId,
|
|
141
|
-
providerId: continuation.providerId,
|
|
142
|
-
requiredCapabilities: continuation.requiredCapabilities
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
/** Extends one owner binding without repeating provider authentication. */
|
|
146
|
-
const extend = Effect.fn("Connection.extend")(function* (input) {
|
|
147
|
-
const repository = yield* Service;
|
|
148
|
-
const aggregate = yield* repository.getByConnectionId(input.connectionId);
|
|
149
|
-
const binding = aggregate?.bindings.find(({ id }) => id === input.connectionId);
|
|
150
|
-
if (aggregate === null || binding === void 0 || binding.ownerId !== input.ownerId) return yield* new Error$1({
|
|
151
|
-
category: "authorization",
|
|
152
|
-
message: "Connection does not belong to this owner",
|
|
153
|
-
operation: "Connection.extend",
|
|
154
|
-
retry: "never"
|
|
155
|
-
});
|
|
156
|
-
if (aggregate.authorization.revocation._tag !== "Active") return yield* new Error$1({
|
|
157
|
-
category: "authorization",
|
|
158
|
-
message: "Provider authorization is awaiting revocation",
|
|
159
|
-
operation: "Connection.extend",
|
|
160
|
-
retry: "after-user-action"
|
|
161
|
-
});
|
|
162
|
-
const now = new Date(yield* Clock.currentTimeMillis);
|
|
163
|
-
if (aggregate.authorization.expiresAt !== null && (Number.isNaN(aggregate.authorization.expiresAt.getTime()) || aggregate.authorization.expiresAt <= now)) return yield* new Error$1({
|
|
164
|
-
category: "authorization",
|
|
165
|
-
message: "Provider authorization has expired",
|
|
166
|
-
operation: "Connection.extend",
|
|
167
|
-
retry: "after-user-action"
|
|
168
|
-
});
|
|
169
|
-
return yield* repository.bind(aggregate.authorization.id, {
|
|
170
|
-
...binding,
|
|
171
|
-
grant: mergeGrant(binding.grant, input.grant)
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
//#endregion
|
|
175
|
-
//#region src/auth/secret.ts
|
|
176
|
-
var secret_exports = /* @__PURE__ */ __exportAll({
|
|
177
|
-
Value: () => Value,
|
|
178
|
-
make: () => make
|
|
179
|
-
});
|
|
180
|
-
/** A deliberately non-serializable credential value. */
|
|
181
|
-
var Value = class Value {
|
|
182
|
-
#value;
|
|
183
|
-
constructor(value) {
|
|
184
|
-
this.#value = value;
|
|
185
|
-
}
|
|
186
|
-
static from(value) {
|
|
187
|
-
if (value.length === 0) throw new Error("Secret values cannot be empty");
|
|
188
|
-
return new Value(value);
|
|
189
|
-
}
|
|
190
|
-
expose() {
|
|
191
|
-
return this.#value;
|
|
192
|
-
}
|
|
193
|
-
toJSON() {
|
|
194
|
-
return "[REDACTED]";
|
|
195
|
-
}
|
|
196
|
-
toString() {
|
|
197
|
-
return "[REDACTED]";
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
const make = Value.from;
|
|
201
|
-
//#endregion
|
|
202
|
-
//#region src/auth/provider-context.ts
|
|
203
|
-
var provider_context_exports = /* @__PURE__ */ __exportAll({
|
|
204
|
-
Envelope: () => Envelope,
|
|
205
|
-
codec: () => codec,
|
|
206
|
-
decode: () => decode$1,
|
|
207
|
-
encode: () => encode$1
|
|
208
|
-
});
|
|
209
|
-
/** A provider-owned, versioned, non-secret context value persisted by the host. */
|
|
210
|
-
const Envelope = Schema.Struct({
|
|
211
|
-
value: Schema.Json,
|
|
212
|
-
version: Schema.String
|
|
213
|
-
});
|
|
214
|
-
/** Build an adapter-owned context codec from a schema and stable version identifier. */
|
|
215
|
-
function codec(version, schema) {
|
|
216
|
-
return {
|
|
217
|
-
decode: Effect.fn("ProviderContext.decode")((envelope) => envelope.version !== version ? Effect.fail(new Error$2({ message: `Unsupported provider context version: ${envelope.version}` })) : Schema.decodeUnknownEffect(schema)(envelope.value).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message })))),
|
|
218
|
-
encode: Effect.fn("ProviderContext.encode")((value) => Schema.encodeEffect(schema)(value).pipe(Effect.flatMap((encoded) => Schema.decodeUnknownEffect(Schema.Json)(encoded)), Effect.map((encoded) => ({
|
|
219
|
-
value: encoded,
|
|
220
|
-
version
|
|
221
|
-
})), Effect.mapError((cause) => new Error$2({ message: cause.message })))),
|
|
222
|
-
version
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
const decode$1 = Effect.fn("ProviderContext.Envelope.decode")((input) => Schema.decodeUnknownEffect(Envelope)(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
|
|
226
|
-
const encode$1 = Schema.encodeSync(Envelope);
|
|
227
|
-
//#endregion
|
|
228
|
-
//#region src/auth/authorization.ts
|
|
229
|
-
var authorization_exports = /* @__PURE__ */ __exportAll({
|
|
230
|
-
Capability: () => Capability,
|
|
231
|
-
CapabilityEvidence: () => CapabilityEvidence,
|
|
232
|
-
Evidence: () => Evidence,
|
|
233
|
-
EvidenceSchema: () => EvidenceSchema,
|
|
234
|
-
Revocation: () => Revocation,
|
|
235
|
-
Schema: () => Schema$1,
|
|
236
|
-
decode: () => decode,
|
|
237
|
-
encode: () => encode,
|
|
238
|
-
evidenceFor: () => evidenceFor,
|
|
239
|
-
validate: () => validate
|
|
240
|
-
});
|
|
241
|
-
const Capability = Schema.Literals(["dns:read", "dns:write"]);
|
|
242
|
-
const Evidence = Data.taggedEnum();
|
|
243
|
-
const EvidenceSchema = Schema.TaggedUnion({
|
|
244
|
-
Declared: {},
|
|
245
|
-
Exercised: { observedAt: Schema.DateFromString },
|
|
246
|
-
Introspected: { observedAt: Schema.DateFromString }
|
|
247
|
-
});
|
|
248
|
-
const CapabilityEvidence = Schema.Struct({
|
|
249
|
-
capability: Capability,
|
|
250
|
-
evidence: EvidenceSchema
|
|
251
|
-
});
|
|
252
|
-
const Revocation = Schema.TaggedUnion({
|
|
253
|
-
Active: {},
|
|
254
|
-
Pending: { requestedAt: Schema.DateFromString }
|
|
255
|
-
});
|
|
256
|
-
/** A provider credential authorization shared by one or more owner connections. */
|
|
257
|
-
const Schema$1 = Schema.Struct({
|
|
258
|
-
authorizedById: Schema.String,
|
|
259
|
-
capabilityEvidence: Schema.Array(CapabilityEvidence),
|
|
260
|
-
createdAt: Schema.DateFromString,
|
|
261
|
-
expiresAt: Schema.NullOr(Schema.DateFromString),
|
|
262
|
-
id: Schema.String,
|
|
263
|
-
method: Schema.Literals([
|
|
264
|
-
"integration",
|
|
265
|
-
"oauth2",
|
|
266
|
-
"token"
|
|
267
|
-
]),
|
|
268
|
-
providerAccountId: Schema.String,
|
|
269
|
-
providerContext: Envelope,
|
|
270
|
-
providerId: Schema.String,
|
|
271
|
-
requiredCapabilities: Schema.Array(Capability),
|
|
272
|
-
revocation: Revocation,
|
|
273
|
-
scopes: Schema.Array(Schema.String)
|
|
274
|
-
});
|
|
275
|
-
const decode = Effect.fn("ProviderAuthorization.decode")((input) => Schema.decodeUnknownEffect(Schema$1)(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
|
|
276
|
-
const validate = Effect.fn("ProviderAuthorization.validate")((input) => Schema.decodeUnknownEffect(Schema.toType(Schema$1))(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
|
|
277
|
-
const encode = Schema.encodeSync(Schema$1);
|
|
278
|
-
function evidenceFor(authorization, capability) {
|
|
279
|
-
return authorization.capabilityEvidence.find((item) => item.capability === capability)?.evidence;
|
|
280
|
-
}
|
|
281
|
-
//#endregion
|
|
282
|
-
export { StartResult as _, Schema$1 as a, start as b, encode as c, provider_context_exports as d, Value as f, Method as g, Error$1 as h, EvidenceSchema as i, evidenceFor as l, secret_exports as m, CapabilityEvidence as n, authorization_exports as o, make as p, Evidence as r, decode as s, Capability as t, codec as u, complete as v, extend as y };
|
|
283
|
-
|
|
284
|
-
//# sourceMappingURL=authorization-OeaSR47S.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authorization-OeaSR47S.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\nexport interface ExtendInput {\n readonly connectionId: string;\n readonly grant: Binding.Grant;\n readonly ownerId: string;\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\n/** Extends one owner binding without repeating provider authentication. */\nexport const extend = Effect.fn(\"Connection.extend\")(function* (input: ExtendInput) {\n const repository = yield* Repository.Service;\n const aggregate = yield* repository.getByConnectionId(input.connectionId);\n const binding = aggregate?.bindings.find(({ id }) => id === input.connectionId);\n if (aggregate === null || binding === undefined || binding.ownerId !== input.ownerId) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Connection does not belong to this owner\",\n operation: \"Connection.extend\",\n retry: \"never\",\n });\n }\n if (aggregate.authorization.revocation._tag !== \"Active\") {\n return yield* new Error({\n category: \"authorization\",\n message: \"Provider authorization is awaiting revocation\",\n operation: \"Connection.extend\",\n retry: \"after-user-action\",\n });\n }\n const now = new Date(yield* Clock.currentTimeMillis);\n if (\n aggregate.authorization.expiresAt !== null &&\n (Number.isNaN(aggregate.authorization.expiresAt.getTime()) ||\n aggregate.authorization.expiresAt <= now)\n ) {\n return yield* new Error({\n category: \"authorization\",\n message: \"Provider authorization has expired\",\n operation: \"Connection.extend\",\n retry: \"after-user-action\",\n });\n }\n return yield* repository.bind(aggregate.authorization.id, {\n ...binding,\n grant: mergeGrant(binding.grant, input.grant),\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,57 +0,0 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import { Crypto, Effect, Layer, PlatformError, Schema } from "effect";
|
|
3
|
-
//#region src/plan/canonical-json.ts
|
|
4
|
-
var canonical_json_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
-
CryptoError: () => CryptoError,
|
|
6
|
-
sha256Encoded: () => sha256Encoded,
|
|
7
|
-
sha256Json: () => sha256Json,
|
|
8
|
-
sha256Text: () => sha256Text,
|
|
9
|
-
stringify: () => stringify,
|
|
10
|
-
webCryptoLayer: () => webCryptoLayer
|
|
11
|
-
});
|
|
12
|
-
var CryptoError = class extends Schema.TaggedError()("CryptoError", { message: Schema.String }) {};
|
|
13
|
-
/** Deterministic JSON serialization for already schema-encoded protocol values. */
|
|
14
|
-
function stringify(value) {
|
|
15
|
-
if (value === null || typeof value !== "object") {
|
|
16
|
-
const encoded = JSON.stringify(value);
|
|
17
|
-
if (encoded === void 0) throw new TypeError("Value is not representable as JSON");
|
|
18
|
-
return encoded;
|
|
19
|
-
}
|
|
20
|
-
if (isJsonArray(value)) return `[${value.map(stringify).join(",")}]`;
|
|
21
|
-
return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, entry]) => `${JSON.stringify(key)}:${stringify(entry)}`).join(",")}}`;
|
|
22
|
-
}
|
|
23
|
-
function isJsonArray(value) {
|
|
24
|
-
return Array.isArray(value);
|
|
25
|
-
}
|
|
26
|
-
const sha256Text = Effect.fn("Digest.sha256Text")(function* (value) {
|
|
27
|
-
return [...yield* (yield* Crypto.Crypto).digest("SHA-256", new TextEncoder().encode(value)).pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })))].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
28
|
-
});
|
|
29
|
-
const sha256Json = Effect.fn("Digest.sha256Json")((value) => Effect.try({
|
|
30
|
-
try: () => stringify(value),
|
|
31
|
-
catch: (cause) => new CryptoError({ message: cause instanceof Error ? cause.message : String(cause) })
|
|
32
|
-
}).pipe(Effect.flatMap(sha256Text)));
|
|
33
|
-
function sha256EncodedProgram(schema, value) {
|
|
34
|
-
return Schema.encodeEffect(schema)(value).pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })), Effect.flatMap(Schema.decodeUnknownEffect(Schema.Json)), Effect.mapError((cause) => new CryptoError({ message: cause.message })), Effect.flatMap(sha256Json));
|
|
35
|
-
}
|
|
36
|
-
const sha256Encoded = Effect.fn("Digest.sha256Encoded")(sha256EncodedProgram);
|
|
37
|
-
/** Portable Web Crypto implementation for hosts that want a ready-made Layer. */
|
|
38
|
-
const webCryptoLayer = Layer.succeed(Crypto.Crypto, Crypto.make({
|
|
39
|
-
randomBytes: (size) => crypto.getRandomValues(new Uint8Array(size)),
|
|
40
|
-
digest: (algorithm, data) => Effect.tryPromise({
|
|
41
|
-
try: async () => {
|
|
42
|
-
const bytes = new Uint8Array(data.byteLength);
|
|
43
|
-
bytes.set(data);
|
|
44
|
-
return new Uint8Array(await crypto.subtle.digest(algorithm, bytes.buffer));
|
|
45
|
-
},
|
|
46
|
-
catch: (cause) => PlatformError.systemError({
|
|
47
|
-
_tag: "Unknown",
|
|
48
|
-
module: "WebCrypto",
|
|
49
|
-
method: "digest",
|
|
50
|
-
cause
|
|
51
|
-
})
|
|
52
|
-
})
|
|
53
|
-
}));
|
|
54
|
-
//#endregion
|
|
55
|
-
export { webCryptoLayer as i, sha256Encoded as n, stringify as r, canonical_json_exports as t };
|
|
56
|
-
|
|
57
|
-
//# sourceMappingURL=canonical-json-CpvqGMcr.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canonical-json-CpvqGMcr.mjs","names":[],"sources":["../src/plan/canonical-json.ts"],"sourcesContent":["import { Crypto, Effect, Layer, PlatformError, Schema } from \"effect\";\n\nexport class CryptoError extends Schema.TaggedError<CryptoError>()(\"CryptoError\", {\n message: Schema.String,\n}) {}\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | ReadonlyArray<Json>\n | { readonly [key: string]: Json };\n\n/** Deterministic JSON serialization for already schema-encoded protocol values. */\nexport function stringify(value: Json): string {\n if (value === null || typeof value !== \"object\") {\n const encoded = JSON.stringify(value);\n if (encoded === undefined) throw new TypeError(\"Value is not representable as JSON\");\n return encoded;\n }\n if (isJsonArray(value)) return `[${value.map(stringify).join(\",\")}]`;\n return `{${Object.entries(value)\n .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([key, entry]) => `${JSON.stringify(key)}:${stringify(entry)}`)\n .join(\",\")}}`;\n}\n\nfunction isJsonArray(value: Json): value is ReadonlyArray<Json> {\n return Array.isArray(value);\n}\n\nexport const sha256Text = Effect.fn(\"Digest.sha256Text\")(function* (value: string) {\n const cryptoService = yield* Crypto.Crypto;\n const digest = yield* cryptoService\n .digest(\"SHA-256\", new TextEncoder().encode(value))\n .pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })));\n return [...digest].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n});\n\nexport const sha256Json = Effect.fn(\"Digest.sha256Json\")((value: Json) =>\n Effect.try({\n try: () => stringify(value),\n catch: (cause) =>\n new CryptoError({ message: cause instanceof Error ? cause.message : String(cause) }),\n }).pipe(Effect.flatMap(sha256Text)),\n);\n\nfunction sha256EncodedProgram<S extends Schema.Constraint>(\n schema: S,\n value: S[\"Type\"],\n): Effect.Effect<string, CryptoError, Crypto.Crypto | S[\"EncodingServices\"]> {\n return Schema.encodeEffect(schema)(value).pipe(\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n Effect.flatMap(Schema.decodeUnknownEffect(Schema.Json)),\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n Effect.flatMap(sha256Json),\n );\n}\n\nexport const sha256Encoded = Effect.fn(\"Digest.sha256Encoded\")(sha256EncodedProgram);\n\n/** Portable Web Crypto implementation for hosts that want a ready-made Layer. */\nexport const webCryptoLayer: Layer.Layer<Crypto.Crypto> = Layer.succeed(\n Crypto.Crypto,\n Crypto.make({\n randomBytes: (size) => crypto.getRandomValues(new Uint8Array(size)),\n digest: (algorithm, data) =>\n Effect.tryPromise({\n try: async () => {\n const bytes = new Uint8Array(data.byteLength);\n bytes.set(data);\n return new Uint8Array(await crypto.subtle.digest(algorithm, bytes.buffer));\n },\n catch: (cause) =>\n PlatformError.systemError({\n _tag: \"Unknown\",\n module: \"WebCrypto\",\n method: \"digest\",\n cause,\n }),\n }),\n }),\n);\n"],"mappings":";;;;;;;;;;;AAEA,IAAa,cAAb,cAAiC,OAAO,YAAyB,CAAC,CAAC,eAAe,EAChF,SAAS,OAAO,OAClB,CAAC,CAAC,CAAC,CAAC;;AAWJ,SAAgB,UAAU,OAAqB;CAC7C,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EAC/C,MAAM,UAAU,KAAK,UAAU,KAAK;EACpC,IAAI,YAAY,KAAA,GAAW,MAAM,IAAI,UAAU,oCAAoC;EACnF,OAAO;CACT;CACA,IAAI,YAAY,KAAK,GAAG,OAAO,IAAI,MAAM,IAAI,SAAS,CAAC,CAAC,KAAK,GAAG,EAAE;CAClE,OAAO,IAAI,OAAO,QAAQ,KAAK,CAAC,CAC7B,MAAM,CAAC,OAAO,CAAC,WAAY,OAAO,QAAQ,KAAK,OAAO,QAAQ,IAAI,CAAE,CAAC,CACrE,KAAK,CAAC,KAAK,WAAW,GAAG,KAAK,UAAU,GAAG,EAAE,GAAG,UAAU,KAAK,GAAG,CAAC,CACnE,KAAK,GAAG,EAAE;AACf;AAEA,SAAS,YAAY,OAA2C;CAC9D,OAAO,MAAM,QAAQ,KAAK;AAC5B;AAEA,MAAa,aAAa,OAAO,GAAG,mBAAmB,CAAC,CAAC,WAAW,OAAe;CAKjF,OAAO,CAAC,GAAG,QAHW,OADO,OAAO,OAAA,CAEjC,OAAO,WAAW,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAClD,KAAK,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAAC,CAC9D,CAAC,CAAC,KAAK,SAAS,KAAK,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;AAC9E,CAAC;AAED,MAAa,aAAa,OAAO,GAAG,mBAAmB,CAAC,EAAE,UACxD,OAAO,IAAI;CACT,WAAW,UAAU,KAAK;CAC1B,QAAQ,UACN,IAAI,YAAY,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC;AACvF,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,UAAU,CAAC,CACpC;AAEA,SAAS,qBACP,QACA,OAC2E;CAC3E,OAAO,OAAO,aAAa,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACxC,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,GACtE,OAAO,QAAQ,OAAO,oBAAoB,OAAO,IAAI,CAAC,GACtD,OAAO,UAAU,UAAU,IAAI,YAAY,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,GACtE,OAAO,QAAQ,UAAU,CAC3B;AACF;AAEA,MAAa,gBAAgB,OAAO,GAAG,sBAAsB,CAAC,CAAC,oBAAoB;;AAGnF,MAAa,iBAA6C,MAAM,QAC9D,OAAO,QACP,OAAO,KAAK;CACV,cAAc,SAAS,OAAO,gBAAgB,IAAI,WAAW,IAAI,CAAC;CAClE,SAAS,WAAW,SAClB,OAAO,WAAW;EAChB,KAAK,YAAY;GACf,MAAM,QAAQ,IAAI,WAAW,KAAK,UAAU;GAC5C,MAAM,IAAI,IAAI;GACd,OAAO,IAAI,WAAW,MAAM,OAAO,OAAO,OAAO,WAAW,MAAM,MAAM,CAAC;EAC3E;EACA,QAAQ,UACN,cAAc,YAAY;GACxB,MAAM;GACN,QAAQ;GACR,QAAQ;GACR;EACF,CAAC;CACL,CAAC;AACL,CAAC,CACH"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Q as AsyncOAuthSubjectResolver, ct as Value, ot as TokenValidation, ut as AsyncInterface } from "./zone-discovery-BPnH3sLU.mjs";
|
|
2
|
-
import { _ as Zone, a as SubjectResolverOptions, d as tokenMethod$1, f as Account, g as Options, h as ListZonesInput, i as OAuthMethodOptions, l as manifest$1, n as CredentialTarget, o as TokenConnectionOptions, p as Fetch, r as OAuthFlowOptions, s as TokenValidatorOptions, u as oauthMethod$1 } from "./index-BHWRTThN.mjs";
|
|
3
|
-
import { a as Source, n as Method, t as InteractiveFlow } from "./connection-BfkloPZy.mjs";
|
|
4
|
-
declare namespace cloudflare_auth_d_exports {
|
|
5
|
-
export { CredentialTarget, OAuthFlowOptions, OAuthMethodOptions, SubjectResolverOptions, TokenValidatorOptions, manifest, oauthFlow, oauthMethod, subjectResolver, tokenConnectionMethod, tokenMethod, tokenValidator };
|
|
6
|
-
}
|
|
7
|
-
declare const manifest: typeof manifest$1;
|
|
8
|
-
declare const oauthMethod: typeof oauthMethod$1;
|
|
9
|
-
declare const tokenMethod: typeof tokenMethod$1;
|
|
10
|
-
declare function subjectResolver(options: SubjectResolverOptions): AsyncOAuthSubjectResolver;
|
|
11
|
-
/** Creates Cloudflare's OAuth implementation for the Promise connection facade. */
|
|
12
|
-
declare function oauthFlow(options: OAuthFlowOptions): InteractiveFlow;
|
|
13
|
-
/** Creates a Cloudflare token method for the Promise connection facade. */
|
|
14
|
-
declare function tokenConnectionMethod(options: TokenConnectionOptions): Extract<Method, {
|
|
15
|
-
readonly _tag: "Token";
|
|
16
|
-
}>;
|
|
17
|
-
declare function tokenValidator(options: TokenValidatorOptions): (token: Value) => Promise<TokenValidation>;
|
|
18
|
-
declare namespace cloudflare_d_exports {
|
|
19
|
-
export { Account, cloudflare_auth_d_exports as Auth, Fetch, Interface, ListZonesInput, Options, Zone, discovery, make };
|
|
20
|
-
}
|
|
21
|
-
interface Interface extends AsyncInterface {
|
|
22
|
-
readonly listAccounts: () => Promise<ReadonlyArray<Account>>;
|
|
23
|
-
readonly listZones: (input?: ListZonesInput) => Promise<ReadonlyArray<Zone>>;
|
|
24
|
-
readonly validateToken: () => Promise<TokenValidation>;
|
|
25
|
-
}
|
|
26
|
-
/** Creates a Promise-compatible facade over the Effect-native Cloudflare client. */
|
|
27
|
-
declare function make(options: Options): Interface;
|
|
28
|
-
/** Creates the optional Cloudflare discovery source for Promise consumers. */
|
|
29
|
-
declare function discovery(options: Options): Source;
|
|
30
|
-
//#endregion
|
|
31
|
-
export { cloudflare_auth_d_exports as a, make as i, cloudflare_d_exports as n, discovery as r, Interface as t };
|
|
32
|
-
//# sourceMappingURL=cloudflare-BrZPU9li.d.mts.map
|