domainkit 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +213 -41
  2. package/dist/Approval.mjs +34 -0
  3. package/dist/Approval.mjs.map +1 -0
  4. package/dist/Cleanup.mjs +97 -0
  5. package/dist/Cleanup.mjs.map +1 -0
  6. package/dist/Cloudflare.mjs +225 -0
  7. package/dist/Cloudflare.mjs.map +1 -0
  8. package/dist/Connect.mjs +463 -0
  9. package/dist/Connect.mjs.map +1 -0
  10. package/dist/Custody.mjs +64 -0
  11. package/dist/Custody.mjs.map +1 -0
  12. package/dist/DnsRecord.mjs +213 -0
  13. package/dist/DnsRecord.mjs.map +1 -0
  14. package/dist/DomainKit.mjs +34 -0
  15. package/dist/DomainKit.mjs.map +1 -0
  16. package/dist/DomainName.mjs +100 -0
  17. package/dist/DomainName.mjs.map +1 -0
  18. package/dist/Plan.mjs +102 -0
  19. package/dist/Plan.mjs.map +1 -0
  20. package/dist/Principal.mjs +23 -0
  21. package/dist/Principal.mjs.map +1 -0
  22. package/dist/Provider.mjs +130 -0
  23. package/dist/Provider.mjs.map +1 -0
  24. package/dist/Providers.mjs +40 -0
  25. package/dist/Providers.mjs.map +1 -0
  26. package/dist/Provision.mjs +93 -0
  27. package/dist/Provision.mjs.map +1 -0
  28. package/dist/Reason.mjs +162 -0
  29. package/dist/Reason.mjs.map +1 -0
  30. package/dist/Receipt.mjs +71 -0
  31. package/dist/Receipt.mjs.map +1 -0
  32. package/dist/Resolver.mjs +75 -0
  33. package/dist/Resolver.mjs.map +1 -0
  34. package/dist/Server.mjs +516 -0
  35. package/dist/Server.mjs.map +1 -0
  36. package/dist/Storage.mjs +236 -0
  37. package/dist/Storage.mjs.map +1 -0
  38. package/dist/Testing.mjs +226 -0
  39. package/dist/Testing.mjs.map +1 -0
  40. package/dist/Transport.mjs +187 -0
  41. package/dist/Transport.mjs.map +1 -0
  42. package/dist/Vercel.mjs +116 -0
  43. package/dist/Vercel.mjs.map +1 -0
  44. package/dist/Verify.mjs +292 -0
  45. package/dist/Verify.mjs.map +1 -0
  46. package/dist/{rolldown-runtime-D7D4PA-g.mjs → _virtual/_rolldown/runtime.mjs} +1 -1
  47. package/dist/entry/client.mjs +2 -0
  48. package/dist/entry/server.mjs +2 -0
  49. package/dist/entry/testing.mjs +3 -0
  50. package/dist/index.mjs +33 -462
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/internal/aes.mjs +61 -0
  53. package/dist/internal/aes.mjs.map +1 -0
  54. package/dist/internal/attempts.mjs +284 -0
  55. package/dist/internal/attempts.mjs.map +1 -0
  56. package/dist/internal/cloudflare/client.mjs +100 -0
  57. package/dist/internal/cloudflare/client.mjs.map +1 -0
  58. package/dist/internal/cloudflare/protocol.mjs +59 -0
  59. package/dist/internal/cloudflare/protocol.mjs.map +1 -0
  60. package/dist/internal/cloudflare/records.mjs +156 -0
  61. package/dist/internal/cloudflare/records.mjs.map +1 -0
  62. package/dist/internal/config.mjs +13 -0
  63. package/dist/internal/config.mjs.map +1 -0
  64. package/dist/internal/conformance/provider.mjs +207 -0
  65. package/dist/internal/conformance/provider.mjs.map +1 -0
  66. package/dist/internal/conformance/storage.mjs +428 -0
  67. package/dist/internal/conformance/storage.mjs.map +1 -0
  68. package/dist/internal/digest.mjs +25 -0
  69. package/dist/internal/digest.mjs.map +1 -0
  70. package/dist/internal/doh.mjs +153 -0
  71. package/dist/internal/doh.mjs.map +1 -0
  72. package/dist/internal/error.mjs +69 -0
  73. package/dist/internal/error.mjs.map +1 -0
  74. package/dist/internal/http.mjs +90 -0
  75. package/dist/internal/http.mjs.map +1 -0
  76. package/dist/internal/ids.mjs +8 -0
  77. package/dist/internal/ids.mjs.map +1 -0
  78. package/dist/internal/oauth.mjs +113 -0
  79. package/dist/internal/oauth.mjs.map +1 -0
  80. package/dist/internal/planner.mjs +88 -0
  81. package/dist/internal/planner.mjs.map +1 -0
  82. package/dist/internal/provider-async.mjs +83 -0
  83. package/dist/internal/provider-async.mjs.map +1 -0
  84. package/dist/internal/storage-memory.mjs +302 -0
  85. package/dist/internal/storage-memory.mjs.map +1 -0
  86. package/dist/internal/vercel/client.mjs +122 -0
  87. package/dist/internal/vercel/client.mjs.map +1 -0
  88. package/dist/internal/vercel/protocol.mjs +80 -0
  89. package/dist/internal/vercel/protocol.mjs.map +1 -0
  90. package/dist/internal/vercel/records.mjs +151 -0
  91. package/dist/internal/vercel/records.mjs.map +1 -0
  92. package/dist/package.mjs +6 -0
  93. package/dist/package.mjs.map +1 -0
  94. package/dist/types/Approval.d.ts +26 -0
  95. package/dist/types/Cleanup.d.ts +41 -0
  96. package/dist/types/Cloudflare.d.ts +36 -0
  97. package/dist/types/Connect.d.ts +506 -0
  98. package/dist/types/Custody.d.ts +38 -0
  99. package/dist/types/DnsRecord.d.ts +158 -0
  100. package/dist/types/DomainKit.d.ts +31 -0
  101. package/dist/types/DomainName.d.ts +27 -0
  102. package/dist/types/Plan.d.ts +76 -0
  103. package/dist/types/Principal.d.ts +18 -0
  104. package/dist/types/Provider.d.ts +248 -0
  105. package/dist/types/Providers.d.ts +16 -0
  106. package/dist/types/Provision.d.ts +75 -0
  107. package/dist/types/Reason.d.ts +118 -0
  108. package/dist/types/Receipt.d.ts +55 -0
  109. package/dist/types/Resolver.d.ts +135 -0
  110. package/dist/types/Server.d.ts +6523 -0
  111. package/dist/types/Storage.d.ts +314 -0
  112. package/dist/types/Testing.d.ts +84 -0
  113. package/dist/types/Transport.d.ts +124 -0
  114. package/dist/types/Vercel.d.ts +25 -0
  115. package/dist/types/Verify.d.ts +109 -0
  116. package/dist/types/entry/client.d.ts +2 -0
  117. package/dist/types/entry/server.d.ts +2 -0
  118. package/dist/types/entry/testing.d.ts +3 -0
  119. package/dist/types/index.d.ts +21 -0
  120. package/dist/types/internal/aes.d.ts +8 -0
  121. package/dist/types/internal/attempts.d.ts +40 -0
  122. package/dist/types/internal/cloudflare/client.d.ts +23 -0
  123. package/dist/types/internal/cloudflare/protocol.d.ts +71 -0
  124. package/dist/types/internal/cloudflare/records.d.ts +8 -0
  125. package/dist/types/internal/config.d.ts +4 -0
  126. package/dist/types/internal/conformance/provider.d.ts +12 -0
  127. package/dist/types/internal/conformance/storage.d.ts +14 -0
  128. package/dist/types/internal/digest.d.ts +10 -0
  129. package/dist/types/internal/doh.d.ts +19 -0
  130. package/dist/types/internal/error.d.ts +24 -0
  131. package/dist/types/internal/http.d.ts +27 -0
  132. package/dist/types/internal/ids.d.ts +3 -0
  133. package/dist/types/internal/oauth.d.ts +58 -0
  134. package/dist/types/internal/planner.d.ts +22 -0
  135. package/dist/types/internal/provider-async.d.ts +78 -0
  136. package/dist/types/internal/storage-memory.d.ts +2 -0
  137. package/dist/types/internal/vercel/client.d.ts +29 -0
  138. package/dist/types/internal/vercel/protocol.d.ts +124 -0
  139. package/dist/types/internal/vercel/records.d.ts +7 -0
  140. package/package.json +88 -12
  141. package/dist/canonical-json-CQYKsZw7.mjs +0 -310
  142. package/dist/canonical-json-CQYKsZw7.mjs.map +0 -1
  143. package/dist/connect-D-X8T9W8.d.mts +0 -1597
  144. package/dist/connect-oI8hcMxc.mjs +0 -185
  145. package/dist/connect-oI8hcMxc.mjs.map +0 -1
  146. package/dist/connection-Dp6ZdSo8.d.mts +0 -186
  147. package/dist/connection-api-lqG1nBtD.d.mts +0 -26
  148. package/dist/index.d.mts +0 -1551
  149. package/dist/managed-dns-connections-C3A_GBaz.mjs +0 -99
  150. package/dist/managed-dns-connections-C3A_GBaz.mjs.map +0 -1
  151. package/dist/promise.d.mts +0 -378
  152. package/dist/promise.mjs +0 -598
  153. package/dist/promise.mjs.map +0 -1
  154. package/dist/resolver-BeGz1ukw.mjs +0 -921
  155. package/dist/resolver-BeGz1ukw.mjs.map +0 -1
  156. package/dist/resolver-xoSwyXDJ.d.mts +0 -3734
  157. package/dist/server.d.mts +0 -128
  158. package/dist/server.mjs +0 -319
  159. package/dist/server.mjs.map +0 -1
  160. package/dist/testing.d.mts +0 -62
  161. package/dist/testing.mjs +0 -507
  162. package/dist/testing.mjs.map +0 -1
  163. package/dist/verify-DvGPb5C9.mjs +0 -2402
  164. package/dist/verify-DvGPb5C9.mjs.map +0 -1
  165. package/dist/verify-FpunAcM7.d.mts +0 -1335
@@ -0,0 +1,2 @@
1
+ /** domainkit/server */
2
+ export * as Server from "../Server.ts";
@@ -0,0 +1,3 @@
1
+ /** domainkit/testing */
2
+ export { VERSION } from "../index.ts";
3
+ export * as Testing from "../Testing.ts";
@@ -0,0 +1,21 @@
1
+ /** The current package version from the package manifest. */
2
+ export declare const VERSION: string;
3
+ export * as Approval from "./Approval.ts";
4
+ export * as Cleanup from "./Cleanup.ts";
5
+ export * as Cloudflare from "./Cloudflare.ts";
6
+ export * as Connect from "./Connect.ts";
7
+ export * as Custody from "./Custody.ts";
8
+ export * as DnsRecord from "./DnsRecord.ts";
9
+ export * as DomainKit from "./DomainKit.ts";
10
+ export * as DomainName from "./DomainName.ts";
11
+ export * as Plan from "./Plan.ts";
12
+ export * as Principal from "./Principal.ts";
13
+ export * as Provider from "./Provider.ts";
14
+ export * as Providers from "./Providers.ts";
15
+ export * as Provision from "./Provision.ts";
16
+ export * as Reason from "./Reason.ts";
17
+ export * as Receipt from "./Receipt.ts";
18
+ export * as Resolver from "./Resolver.ts";
19
+ export * as Storage from "./Storage.ts";
20
+ export * as Vercel from "./Vercel.ts";
21
+ export * as Verify from "./Verify.ts";
@@ -0,0 +1,8 @@
1
+ import { Effect, Redacted } from "effect";
2
+ import * as Errors from "./error.ts";
3
+ /** Accepts a 32-byte key as base64, base64url, or hex. */
4
+ export declare const decodeKey: (encoded: string) => Uint8Array<ArrayBuffer> | null;
5
+ export declare const importKey: (raw: Uint8Array<ArrayBuffer>) => Effect.Effect<CryptoKey, Errors.DomainKitError>;
6
+ export declare const seal: (key: CryptoKey, plaintext: Redacted.Redacted<string>) => Effect.Effect<string, Errors.DomainKitError>;
7
+ export declare const open: (key: CryptoKey, envelope: string) => Effect.Effect<Redacted.Redacted<string>, Errors.DomainKitError>;
8
+ export declare const generateKey: () => string;
@@ -0,0 +1,40 @@
1
+ import { Effect } from "effect";
2
+ import * as Approval from "../Approval.ts";
3
+ import * as Connect from "../Connect.ts";
4
+ import * as DnsRecord from "../DnsRecord.ts";
5
+ import * as Errors from "./error.ts";
6
+ import * as Plan from "../Plan.ts";
7
+ import * as Principal from "../Principal.ts";
8
+ import type * as Provider from "../Provider.ts";
9
+ import * as Receipt from "../Receipt.ts";
10
+ import * as Storage from "../Storage.ts";
11
+ type Fx<A> = Effect.Effect<A, Errors.DomainKitError, Principal.Service>;
12
+ export interface ApproveOptions {
13
+ readonly operationIds?: ReadonlyArray<Plan.OperationId>;
14
+ readonly allowPartial?: boolean;
15
+ }
16
+ export interface PolicyShape {
17
+ readonly planTtlMs: number;
18
+ readonly applyLeaseMs: number;
19
+ }
20
+ /** Every requirement must sit at or below the attached domain; other tenants share the zone. */
21
+ export declare const assertWithin: (attachment: Storage.Attachment, records: ReadonlyArray<DnsRecord.Model>) => Effect.Effect<void, Errors.DomainKitError>;
22
+ /** Shared plan -> approve -> apply machinery for provisioning and cleanup attempts. */
23
+ export declare const make: (storage: Storage.Interface, connect: Connect.Interface, kind: Plan.Kind) => {
24
+ record: (input: {
25
+ readonly attachment: Storage.Attachment;
26
+ readonly target: Provider.Target;
27
+ readonly operations: ReadonlyArray<Plan.Operation>;
28
+ readonly ttlMs: number;
29
+ readonly sourceReceiptId: Receipt.ReceiptId | null;
30
+ }) => Fx<Plan.Model>;
31
+ approve: (plan: Plan.Model | Plan.PlanId, options?: ApproveOptions) => Fx<Approval.Model>;
32
+ reject: (plan: Plan.Model | Plan.PlanId, options?: {
33
+ readonly reason?: string;
34
+ }) => Fx<Storage.Attempt>;
35
+ apply: (approval: Approval.Model | Approval.ApprovalId, policy: PolicyShape) => Fx<Receipt.Model>;
36
+ attemptOf: (plan: Plan.Model | Plan.PlanId) => Fx<Storage.Attempt>;
37
+ };
38
+ /** Read one receipt-proven record back; anything but an exact match is a conflict. */
39
+ export declare const cleanupOperation: (dns: Provider.Dns, zone: string, id: Plan.OperationId, record: DnsRecord.Model, providerRecordId: string) => Effect.Effect<Plan.Delete | Plan.Conflict, Errors.DomainKitError>;
40
+ export {};
@@ -0,0 +1,23 @@
1
+ import { DateTime, Effect } from "effect";
2
+ import * as Errors from "../error.ts";
3
+ import type * as Provider from "../../Provider.ts";
4
+ import { type Fetch } from "../http.ts";
5
+ import * as Protocol from "./protocol.ts";
6
+ export declare const provider = "cloudflare";
7
+ export interface Options {
8
+ readonly token: string;
9
+ readonly fetch: Fetch;
10
+ readonly baseUrl: string;
11
+ }
12
+ type Fx<A> = Effect.Effect<A, Errors.DomainKitError>;
13
+ /** Every zone the credential can see, across accounts; internal zones cannot host records. */
14
+ export declare const listZones: (options: Options, accountId?: string) => Fx<ReadonlyArray<Protocol.Zone>>;
15
+ /** Token expiry from the verify endpoint; `null` when the token never expires or verification is unavailable. */
16
+ /** Token status and expiry from a verify endpoint; an inactive token is `Unauthenticated`. */
17
+ export declare const verifyToken: (options: Options, path: string) => Fx<DateTime.Utc | null>;
18
+ export declare const tokenExpiry: (options: Options, accountId: string | null) => Fx<{
19
+ readonly expiresAt: DateTime.Utc | null;
20
+ readonly kind: "user" | "account";
21
+ }>;
22
+ export declare const dns: (options: Options, zoneId: string) => Provider.Dns;
23
+ export {};
@@ -0,0 +1,71 @@
1
+ import { Schema as S } from "effect";
2
+ export declare const ErrorDetail: S.Struct<{
3
+ readonly code: S.Number;
4
+ readonly message: S.String;
5
+ }>;
6
+ export declare const ResultInfo: S.Struct<{
7
+ readonly count: S.optionalKey<S.Number>;
8
+ readonly page: S.optionalKey<S.Number>;
9
+ readonly per_page: S.optionalKey<S.Number>;
10
+ readonly total_count: S.optionalKey<S.Number>;
11
+ readonly total_pages: S.optionalKey<S.Number>;
12
+ }>;
13
+ export declare const BaseEnvelope: S.Struct<{
14
+ readonly errors: S.$Array<S.Struct<{
15
+ readonly code: S.Number;
16
+ readonly message: S.String;
17
+ }>>;
18
+ readonly messages: S.optionalKey<S.$Array<S.Struct<{
19
+ readonly code: S.optionalKey<S.Number>;
20
+ readonly message: S.String;
21
+ }>>>;
22
+ readonly success: S.Boolean;
23
+ }>;
24
+ export declare const Account: S.Struct<{
25
+ readonly id: S.String;
26
+ readonly name: S.String;
27
+ }>;
28
+ export type Account = typeof Account.Type;
29
+ export declare const Zone: S.Struct<{
30
+ readonly account: S.Struct<{
31
+ readonly id: S.String;
32
+ readonly name: S.String;
33
+ }>;
34
+ readonly id: S.String;
35
+ readonly name: S.String;
36
+ readonly name_servers: S.optionalKey<S.$Array<S.String>>;
37
+ readonly status: S.optionalKey<S.String>;
38
+ readonly type: S.optionalKey<S.String>;
39
+ }>;
40
+ export type Zone = typeof Zone.Type;
41
+ export declare const Record: S.Struct<{
42
+ readonly content: S.optionalKey<S.String>;
43
+ readonly data: S.optionalKey<S.Unknown>;
44
+ readonly id: S.String;
45
+ readonly name: S.String;
46
+ readonly priority: S.optionalKey<S.Number>;
47
+ readonly proxied: S.optionalKey<S.Boolean>;
48
+ readonly ttl: S.Number;
49
+ readonly type: S.String;
50
+ }>;
51
+ export type Record = typeof Record.Type;
52
+ export declare const Token: S.Struct<{
53
+ readonly expires_on: S.optionalKey<S.NullOr<S.String>>;
54
+ readonly id: S.String;
55
+ readonly status: S.String;
56
+ }>;
57
+ export declare const Envelope: S.Struct<{
58
+ readonly errors: S.$Array<S.Struct<{
59
+ readonly code: S.Number;
60
+ readonly message: S.String;
61
+ }>>;
62
+ readonly result: S.Unknown;
63
+ readonly result_info: S.optionalKey<S.Struct<{
64
+ readonly count: S.optionalKey<S.Number>;
65
+ readonly page: S.optionalKey<S.Number>;
66
+ readonly per_page: S.optionalKey<S.Number>;
67
+ readonly total_count: S.optionalKey<S.Number>;
68
+ readonly total_pages: S.optionalKey<S.Number>;
69
+ }>>;
70
+ readonly success: S.Boolean;
71
+ }>;
@@ -0,0 +1,8 @@
1
+ import { Effect } from "effect";
2
+ import * as DnsRecord from "../../DnsRecord.ts";
3
+ import type * as Provider from "../../Provider.ts";
4
+ import type * as Protocol from "./protocol.ts";
5
+ /** Records DomainKit cannot model, or cannot parse, come back opaque so plans never touch them. */
6
+ export declare const decode: (record: Protocol.Record) => Effect.Effect<Provider.ObservedRecord>;
7
+ export declare const encode: (record: DnsRecord.Model) => Record<string, unknown>;
8
+ export declare const isWithinZone: (name: string, zone: string) => boolean;
@@ -0,0 +1,4 @@
1
+ import { Config, Effect } from "effect";
2
+ import * as Errors from "./error.ts";
3
+ /** Accept a literal or a `Config`; config failures surface as `InvalidInput` on `field`. */
4
+ export declare const resolve: <A>(value: A | Config.Config<A>, field: string) => Effect.Effect<A, Errors.DomainKitError>;
@@ -0,0 +1,12 @@
1
+ import { Effect } from "effect";
2
+ import * as Errors from "../error.ts";
3
+ import * as Provider from "../../Provider.ts";
4
+ export declare const cases: readonly ["create-readback-cleanup", "exact-noop", "conflict", "stale-plan", "partial-apply-cleanup"];
5
+ export type Case = (typeof cases)[number];
6
+ /**
7
+ * Runs create/readback/cleanup, exact-noop, conflict, stale-plan, and partial-apply against a
8
+ * real provider definition, through the same Provision and Cleanup services hosts use.
9
+ */
10
+ export declare const provider: (definition: Provider.Definition, credential: Provider.Credential, zone: string, options?: {
11
+ readonly prefix?: string;
12
+ }) => Effect.Effect<void, Errors.DomainKitError>;
@@ -0,0 +1,14 @@
1
+ import { Effect, Layer } from "effect";
2
+ import * as Storage from "../../Storage.ts";
3
+ export interface Case {
4
+ readonly name: string;
5
+ readonly run: Effect.Effect<void, unknown>;
6
+ }
7
+ export interface Options {
8
+ /** Register each case with a test runner, e.g. vitest's `it`. */
9
+ readonly it?: (name: string, run: () => Promise<void>) => void;
10
+ }
11
+ /** Every invariant a `Storage` implementation must hold. Each case runs against a fresh layer. */
12
+ export declare const cases: (layer: Layer.Layer<Storage.Service, unknown>) => ReadonlyArray<Case>;
13
+ /** Registers every case with `options.it` when given; always returns the cases. */
14
+ export declare const storage: (layer: Layer.Layer<Storage.Service, unknown>, options?: Options) => ReadonlyArray<Case>;
@@ -0,0 +1,10 @@
1
+ import { Effect, Schema } from "effect";
2
+ import * as Errors from "./error.ts";
3
+ export type Json = null | boolean | number | string | ReadonlyArray<Json> | {
4
+ readonly [key: string]: Json;
5
+ };
6
+ /** Deterministic JSON serialization for already schema-encoded protocol values. */
7
+ export declare function stringify(value: unknown): string;
8
+ export declare const sha256Hex: (value: string) => Effect.Effect<string, Errors.DomainKitError>;
9
+ /** Digest of the canonical JSON encoding of `value` under `schema`. */
10
+ export declare const sha256Encoded: <S extends Schema.ConstraintEncoder<unknown>>(schema: S, value: S["Type"]) => Effect.Effect<string, Errors.DomainKitError>;
@@ -0,0 +1,19 @@
1
+ import { Effect } from "effect";
2
+ import * as DnsRecord from "../DnsRecord.ts";
3
+ import * as Errors from "./error.ts";
4
+ import type { Fetch } from "./http.ts";
5
+ export interface Answer {
6
+ readonly records: ReadonlyArray<DnsRecord.Observed>;
7
+ readonly negative: boolean;
8
+ readonly ttl: number | null;
9
+ }
10
+ /** One RFC 8484 wire-format query; the caller applies the timeout. */
11
+ export declare const query: (input: {
12
+ readonly resolver: string;
13
+ readonly url: string;
14
+ readonly fetch: Fetch;
15
+ readonly name: string;
16
+ readonly type: DnsRecord.Type;
17
+ /** Host-supplied abort, combined with the fiber's own interruption signal. */
18
+ readonly signal?: AbortSignal | undefined;
19
+ }) => Effect.Effect<Answer, Errors.DomainKitError>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The one error every DomainKit operation fails with, published as `DomainKit.Error`. Hosts match
3
+ * on `reason`; `category`, `isRetryable`, and `httpStatus` derive from it. Modelled on `SqlError`
4
+ * and `HttpClientError` in Effect.
5
+ */
6
+ import { Effect, Schema } from "effect";
7
+ import * as Reason from "../Reason.ts";
8
+ export type Category = "request" | "auth" | "plan" | "provider" | "storage" | "internal";
9
+ declare const DomainKitError_base: Schema.Class<DomainKitError, Schema.TaggedStruct<"DomainKitError", {
10
+ readonly reason: Schema.suspend<Schema.Union<readonly [typeof Reason.InvalidInput, typeof Reason.Unauthenticated, typeof Reason.Forbidden, typeof Reason.NotFound, typeof Reason.Conflict, typeof Reason.Stale, typeof Reason.Expired, typeof Reason.Busy, typeof Reason.ProviderRejected, typeof Reason.ProviderUnavailable, typeof Reason.ProviderConflict, typeof Reason.Unsupported, typeof Reason.Reconnect, typeof Reason.StorageFailed, typeof Reason.CryptoFailed, typeof Reason.ResolverFailed]>>;
11
+ }>, import("effect/Cause").YieldableError>;
12
+ export declare class DomainKitError extends DomainKitError_base {
13
+ get category(): Category;
14
+ get isRetryable(): boolean;
15
+ /** The HTTP status `domainkit/server` answers with; hosts mapping their own routes use the same table. */
16
+ get httpStatus(): number;
17
+ get message(): string;
18
+ }
19
+ export declare const isDomainKitError: (input: unknown) => input is DomainKitError;
20
+ /** `Effect.fail(new DomainKitError({ reason }))` shorthand used across the package. */
21
+ export declare const fail: <R extends Reason.Model>(reason: R) => Effect.Effect<never, DomainKitError>;
22
+ /** Decode with any schema, failing with reason `InvalidInput` and the schema's message. */
23
+ export declare const decode: <S extends Schema.ConstraintDecoder<unknown>>(schema: S, input: unknown, field?: string) => Effect.Effect<S["Type"], DomainKitError>;
24
+ export {};
@@ -0,0 +1,27 @@
1
+ import { Effect } from "effect";
2
+ import * as Errors from "./error.ts";
3
+ import * as Reason from "../Reason.ts";
4
+ export type Fetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
5
+ export interface Reply {
6
+ readonly status: number;
7
+ readonly ok: boolean;
8
+ readonly headers: Headers;
9
+ /** Parsed JSON, or `null` for an empty body. */
10
+ readonly body: unknown;
11
+ }
12
+ /** One provider HTTP round trip: transport failures and non-JSON replies are already classified. */
13
+ export declare const requestJson: (input: {
14
+ readonly fetch: Fetch;
15
+ readonly provider: string;
16
+ readonly url: URL | string;
17
+ readonly init?: RequestInit;
18
+ }) => Effect.Effect<Reply, Errors.DomainKitError>;
19
+ /** Host-supplied request headers, given as a value or as a thunk that may await a fresh token. */
20
+ export declare const headersFrom: (source: HeadersInit | (() => HeadersInit | Promise<HeadersInit>) | undefined) => Effect.Effect<Headers, Errors.DomainKitError>;
21
+ /**
22
+ * Map an HTTP failure to a reason: 401 -> Unauthenticated, 403 -> Forbidden, 409 or a provider
23
+ * conflict code -> ProviderConflict, 429/5xx -> ProviderUnavailable, else ProviderRejected.
24
+ */
25
+ export declare const classify: (provider: string, status: number, headers: Headers, message: string, code?: string) => Reason.Model;
26
+ export declare const rejected: (provider: string, message: string, code?: string) => Errors.DomainKitError;
27
+ export declare const bearer: (token: string, init?: RequestInit) => RequestInit;
@@ -0,0 +1,3 @@
1
+ import { Effect } from "effect";
2
+ /** A fresh, prefixed, URL-safe identifier (`prefix_<uuid>`). */
3
+ export declare const fresh: (prefix: string) => Effect.Effect<string>;
@@ -0,0 +1,58 @@
1
+ import { DateTime, Effect, Redacted } from "effect";
2
+ import * as Errors from "./error.ts";
3
+ import type { Fetch } from "./http.ts";
4
+ export interface Server {
5
+ readonly issuer: string;
6
+ readonly authorization_endpoint: string;
7
+ readonly token_endpoint: string;
8
+ readonly revocation_endpoint?: string;
9
+ }
10
+ export type ClientAuth = "client_secret_basic" | "client_secret_post" | "none";
11
+ export interface Client {
12
+ readonly clientId: string;
13
+ readonly clientSecret: Redacted.Redacted<string> | null;
14
+ readonly clientAuth: ClientAuth;
15
+ }
16
+ /** A PKCE pair: the verifier stays in the continuation, the challenge goes to the provider. */
17
+ export declare const pkce: () => Effect.Effect<{
18
+ readonly codeVerifier: string;
19
+ readonly codeChallenge: string;
20
+ }, Errors.DomainKitError>;
21
+ export declare const authorizationUrl: (input: {
22
+ readonly server: Server;
23
+ readonly clientId: string;
24
+ readonly scopes: ReadonlyArray<string>;
25
+ readonly state: string;
26
+ readonly callbackUrl: string;
27
+ readonly codeChallenge: string;
28
+ }) => string;
29
+ export interface Tokens {
30
+ readonly accessToken: string;
31
+ readonly refreshToken: string | null;
32
+ readonly expiresAt: DateTime.Utc | null;
33
+ readonly scope: string | null;
34
+ }
35
+ export declare const exchangeCode: (input: {
36
+ readonly provider: string;
37
+ readonly server: Server;
38
+ readonly client: Client;
39
+ readonly code: string;
40
+ readonly state: string;
41
+ readonly callbackUrl: string;
42
+ readonly codeVerifier: string;
43
+ readonly fetch?: Fetch;
44
+ }) => Effect.Effect<Tokens, Errors.DomainKitError>;
45
+ export declare const refresh: (input: {
46
+ readonly provider: string;
47
+ readonly server: Server;
48
+ readonly client: Client;
49
+ readonly refreshToken: string;
50
+ readonly fetch?: Fetch;
51
+ }) => Effect.Effect<Tokens, Errors.DomainKitError>;
52
+ export declare const revoke: (input: {
53
+ readonly provider: string;
54
+ readonly server: Server;
55
+ readonly client: Client;
56
+ readonly token: string;
57
+ readonly fetch?: Fetch;
58
+ }) => Effect.Effect<void, Errors.DomainKitError>;
@@ -0,0 +1,22 @@
1
+ import { Effect, Schema } from "effect";
2
+ import * as DnsRecord from "../DnsRecord.ts";
3
+ import * as Errors from "./error.ts";
4
+ import * as Plan from "../Plan.ts";
5
+ declare const Unsigned: Schema.Struct<{
6
+ readonly version: Schema.Literal<"domainkit.plan.v2">;
7
+ readonly kind: Schema.Literals<readonly ["provisioning", "cleanup"]>;
8
+ readonly domain: Schema.String;
9
+ readonly zone: Schema.String;
10
+ readonly provider: Schema.String;
11
+ readonly attachmentId: Schema.String;
12
+ readonly operations: Schema.$Array<Schema.Union<readonly [typeof Plan.Create, typeof Plan.Noop, typeof Plan.Conflict, typeof Plan.Delete]>>;
13
+ }>;
14
+ export type Unsigned = typeof Unsigned.Type;
15
+ export declare const operationId: (record: DnsRecord.Model) => Effect.Effect<Plan.OperationId, Errors.DomainKitError>;
16
+ /** The digest covers every operation but not requirement labels, which are display metadata. */
17
+ export declare const digest: (unsigned: Unsigned) => Effect.Effect<Plan.Digest, Errors.DomainKitError>;
18
+ /** Additive, fail-closed reconciliation of requirements against what the provider holds. */
19
+ export declare const reconcile: (requirements: ReadonlyArray<DnsRecord.Model>, existing: ReadonlyArray<DnsRecord.Observed>) => Effect.Effect<ReadonlyArray<Plan.Create | Plan.Noop | Plan.Conflict>, Errors.DomainKitError>;
20
+ /** Requirements a plan was built from, for re-planning at apply time. */
21
+ export declare const requirements: (plan: Plan.Model) => ReadonlyArray<DnsRecord.Model>;
22
+ export {};
@@ -0,0 +1,78 @@
1
+ import { type Schema } from "effect";
2
+ import type * as DnsRecord from "../DnsRecord.ts";
3
+ import * as Provider from "../Provider.ts";
4
+ import type { Capability } from "../Storage.ts";
5
+ /** Plain-object credential for Promise-shaped providers; `secret` is the raw string. */
6
+ export interface AsyncCredential {
7
+ readonly secret: string;
8
+ readonly context: unknown;
9
+ }
10
+ export interface AsyncIssuedCredential extends AsyncCredential {
11
+ readonly expiresAt: Date | null;
12
+ }
13
+ export interface AsyncDns {
14
+ readonly list: (zone: string) => Promise<ReadonlyArray<Provider.ObservedRecord>>;
15
+ readonly create: (zone: string, record: DnsRecord.Model) => Promise<{
16
+ readonly providerRecordId: string;
17
+ }>;
18
+ readonly get: (zone: string, providerRecordId: string) => Promise<DnsRecord.Observed | null>;
19
+ readonly delete: (zone: string, providerRecordId: string) => Promise<void>;
20
+ }
21
+ export interface AsyncSession {
22
+ readonly listTargets: () => Promise<ReadonlyArray<Provider.Target>>;
23
+ readonly resolveTarget: (domain: string) => Promise<Provider.Resolution>;
24
+ readonly dns: (target: Provider.Target) => AsyncDns;
25
+ readonly capabilities: () => Promise<ReadonlyArray<Capability>>;
26
+ }
27
+ export interface AsyncTokenAuth {
28
+ readonly label: string;
29
+ readonly docsUrl?: string;
30
+ readonly requiredCapabilities: ReadonlyArray<Capability>;
31
+ readonly fields: Schema.Struct<Provider.TokenFieldSchemas>;
32
+ /** Decoded field values with secrets unwrapped to strings. */
33
+ readonly authenticate: (values: Readonly<Record<string, string | undefined>>) => Promise<AsyncIssuedCredential>;
34
+ }
35
+ export interface AsyncOAuthAuth {
36
+ readonly label: string;
37
+ readonly scopes: ReadonlyArray<string>;
38
+ readonly start: (input: {
39
+ readonly state: string;
40
+ readonly callbackUrl: string;
41
+ readonly codeChallenge: string;
42
+ }) => Promise<{
43
+ readonly authorizationUrl: string;
44
+ }>;
45
+ readonly complete: (input: Provider.CallbackInput & {
46
+ readonly codeVerifier: string;
47
+ }) => Promise<AsyncIssuedCredential>;
48
+ readonly refresh: (credential: AsyncCredential) => Promise<AsyncIssuedCredential>;
49
+ readonly revoke?: (credential: AsyncCredential) => Promise<void>;
50
+ }
51
+ export interface AsyncIntegrationAuth {
52
+ readonly label: string;
53
+ readonly start: (input: {
54
+ readonly state: string;
55
+ readonly callbackUrl: string;
56
+ }) => Promise<{
57
+ readonly authorizationUrl: string;
58
+ }>;
59
+ readonly complete: (input: Provider.CallbackInput) => Promise<AsyncIssuedCredential>;
60
+ readonly refresh?: (credential: AsyncCredential) => Promise<AsyncIssuedCredential>;
61
+ readonly revoke?: (credential: AsyncCredential) => Promise<void>;
62
+ }
63
+ /** `Provider.Definition` with every operation returning a Promise. */
64
+ export interface AsyncDefinition<Context = unknown> {
65
+ readonly id: string;
66
+ readonly name: string;
67
+ readonly auth: {
68
+ readonly token?: AsyncTokenAuth;
69
+ readonly oauth?: AsyncOAuthAuth;
70
+ readonly integration?: AsyncIntegrationAuth;
71
+ };
72
+ readonly context: Schema.Codec<Context, unknown, never, never>;
73
+ readonly contextVersion: string;
74
+ readonly migrateContext?: (envelope: Provider.Envelope) => Promise<Context>;
75
+ readonly session: (credential: AsyncCredential) => AsyncSession;
76
+ }
77
+ /** Adapt a Promise-shaped provider; rejections become `DomainKit.Error` (a thrown one passes through). */
78
+ export declare const fromAsync: <Context>(definition: AsyncDefinition<Context>) => Provider.Definition<Context>;
@@ -0,0 +1,2 @@
1
+ import * as Storage from "../Storage.ts";
2
+ export declare function makeMemory(options?: Storage.MemoryOptions): Storage.Interface;
@@ -0,0 +1,29 @@
1
+ import { Effect } from "effect";
2
+ import * as Errors from "../error.ts";
3
+ import type * as Provider from "../../Provider.ts";
4
+ import { type Fetch } from "../http.ts";
5
+ import * as Protocol from "./protocol.ts";
6
+ export declare const provider = "vercel";
7
+ export interface Options {
8
+ readonly token: string;
9
+ readonly fetch: Fetch;
10
+ readonly baseUrl: string;
11
+ }
12
+ type Fx<A> = Effect.Effect<A, Errors.DomainKitError>;
13
+ export declare const user: (options: Options) => Effect.Effect<{
14
+ readonly id: string;
15
+ readonly name: string | null;
16
+ readonly username: string;
17
+ }, Errors.DomainKitError, never>;
18
+ export declare const teams: (options: Options) => Fx<ReadonlyArray<typeof Protocol.Team.Type>>;
19
+ /** Domains with Vercel-hosted DNS for one account (`teamId` null means the personal account). */
20
+ export declare const zones: (options: Options, teamId: string | null) => Fx<ReadonlyArray<Protocol.Domain>>;
21
+ export declare const exchangeCode: (input: {
22
+ readonly options: Options;
23
+ readonly clientId: string;
24
+ readonly clientSecret: string;
25
+ readonly code: string;
26
+ readonly callbackUrl: string;
27
+ }) => Fx<typeof Protocol.IntegrationToken.Type>;
28
+ export declare const dns: (options: Options, teamId: string | null) => Provider.Dns;
29
+ export {};
@@ -0,0 +1,124 @@
1
+ import { Schema as S } from "effect";
2
+ export declare const Pagination: S.Struct<{
3
+ readonly count: S.Number;
4
+ readonly next: S.NullOr<S.Number>;
5
+ readonly prev: S.NullOr<S.Number>;
6
+ }>;
7
+ export declare const ErrorDetail: S.Struct<{
8
+ readonly code: S.String;
9
+ readonly message: S.String;
10
+ readonly limit: S.optionalKey<S.Struct<{
11
+ readonly remaining: S.Number;
12
+ readonly reset: S.optionalKey<S.Number>;
13
+ readonly resetMs: S.optionalKey<S.Number>;
14
+ readonly total: S.Number;
15
+ }>>;
16
+ }>;
17
+ export declare const ErrorEnvelope: S.Struct<{
18
+ readonly error: S.Struct<{
19
+ readonly code: S.String;
20
+ readonly message: S.String;
21
+ readonly limit: S.optionalKey<S.Struct<{
22
+ readonly remaining: S.Number;
23
+ readonly reset: S.optionalKey<S.Number>;
24
+ readonly resetMs: S.optionalKey<S.Number>;
25
+ readonly total: S.Number;
26
+ }>>;
27
+ }>;
28
+ }>;
29
+ export declare const User: S.Struct<{
30
+ readonly id: S.String;
31
+ readonly name: S.NullOr<S.String>;
32
+ readonly username: S.String;
33
+ }>;
34
+ export declare const UserEnvelope: S.Struct<{
35
+ readonly user: S.Struct<{
36
+ readonly id: S.String;
37
+ readonly name: S.NullOr<S.String>;
38
+ readonly username: S.String;
39
+ }>;
40
+ }>;
41
+ export declare const Team: S.Struct<{
42
+ readonly id: S.String;
43
+ readonly name: S.NullOr<S.String>;
44
+ readonly slug: S.String;
45
+ }>;
46
+ export declare const TeamListEnvelope: S.Struct<{
47
+ readonly pagination: S.Struct<{
48
+ readonly count: S.Number;
49
+ readonly next: S.NullOr<S.Number>;
50
+ readonly prev: S.NullOr<S.Number>;
51
+ }>;
52
+ readonly teams: S.$Array<S.Struct<{
53
+ readonly id: S.String;
54
+ readonly name: S.NullOr<S.String>;
55
+ readonly slug: S.String;
56
+ }>>;
57
+ }>;
58
+ export declare const Domain: S.Struct<{
59
+ readonly id: S.String;
60
+ readonly intendedNameservers: S.$Array<S.String>;
61
+ readonly name: S.String;
62
+ readonly nameservers: S.$Array<S.String>;
63
+ readonly serviceType: S.Literals<readonly ["zeit.world", "external", "na"]>;
64
+ readonly teamId: S.NullOr<S.String>;
65
+ readonly userId: S.String;
66
+ readonly verified: S.Boolean;
67
+ readonly zone: S.optionalKey<S.Boolean>;
68
+ }>;
69
+ export type Domain = typeof Domain.Type;
70
+ export declare const DomainListEnvelope: S.Struct<{
71
+ readonly domains: S.$Array<S.Struct<{
72
+ readonly id: S.String;
73
+ readonly intendedNameservers: S.$Array<S.String>;
74
+ readonly name: S.String;
75
+ readonly nameservers: S.$Array<S.String>;
76
+ readonly serviceType: S.Literals<readonly ["zeit.world", "external", "na"]>;
77
+ readonly teamId: S.NullOr<S.String>;
78
+ readonly userId: S.String;
79
+ readonly verified: S.Boolean;
80
+ readonly zone: S.optionalKey<S.Boolean>;
81
+ }>>;
82
+ readonly pagination: S.Struct<{
83
+ readonly count: S.Number;
84
+ readonly next: S.NullOr<S.Number>;
85
+ readonly prev: S.NullOr<S.Number>;
86
+ }>;
87
+ }>;
88
+ export declare const Record: S.Struct<{
89
+ readonly id: S.String;
90
+ readonly mxPriority: S.optionalKey<S.Number>;
91
+ readonly name: S.String;
92
+ readonly priority: S.optionalKey<S.Number>;
93
+ readonly ttl: S.optionalKey<S.Number>;
94
+ readonly type: S.String;
95
+ readonly value: S.String;
96
+ }>;
97
+ export type Record = typeof Record.Type;
98
+ export declare const RecordListEnvelope: S.Struct<{
99
+ readonly pagination: S.optionalKey<S.Struct<{
100
+ readonly count: S.Number;
101
+ readonly next: S.NullOr<S.Number>;
102
+ readonly prev: S.NullOr<S.Number>;
103
+ }>>;
104
+ readonly records: S.$Array<S.Struct<{
105
+ readonly id: S.String;
106
+ readonly mxPriority: S.optionalKey<S.Number>;
107
+ readonly name: S.String;
108
+ readonly priority: S.optionalKey<S.Number>;
109
+ readonly ttl: S.optionalKey<S.Number>;
110
+ readonly type: S.String;
111
+ readonly value: S.String;
112
+ }>>;
113
+ }>;
114
+ export declare const CreateRecordEnvelope: S.Struct<{
115
+ readonly uid: S.String;
116
+ readonly updated: S.optionalKey<S.Number>;
117
+ }>;
118
+ export declare const IntegrationToken: S.Struct<{
119
+ readonly access_token: S.String;
120
+ readonly installation_id: S.optionalKey<S.String>;
121
+ readonly team_id: S.NullOr<S.String>;
122
+ readonly token_type: S.optionalKey<S.String>;
123
+ readonly user_id: S.String;
124
+ }>;
@@ -0,0 +1,7 @@
1
+ import { Effect } from "effect";
2
+ import * as DnsRecord from "../../DnsRecord.ts";
3
+ import type * as Provider from "../../Provider.ts";
4
+ import type * as Protocol from "./protocol.ts";
5
+ export declare const decode: (zone: string, record: Protocol.Record) => Effect.Effect<Provider.ObservedRecord>;
6
+ export declare const encode: (zone: string, record: DnsRecord.Model) => Effect.Effect<Record<string, unknown>, never>;
7
+ export declare const outsideZone: (zone: string, name: string) => import("../error.ts").DomainKitError;