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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domainkit",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Build reviewable DNS plans for custom domains in TypeScript",
5
5
  "keywords": [
6
6
  "custom-domains",
@@ -30,25 +30,101 @@
30
30
  "sideEffects": false,
31
31
  "exports": {
32
32
  ".": {
33
- "types": "./dist/index.d.mts",
33
+ "types": "./dist/types/index.d.ts",
34
34
  "import": "./dist/index.mjs"
35
35
  },
36
- "./promise": {
37
- "types": "./dist/promise.d.mts",
38
- "import": "./dist/promise.mjs"
36
+ "./client": {
37
+ "types": "./dist/types/entry/client.d.ts",
38
+ "import": "./dist/entry/client.mjs"
39
39
  },
40
40
  "./server": {
41
- "types": "./dist/server.d.mts",
42
- "import": "./dist/server.mjs"
41
+ "types": "./dist/types/entry/server.d.ts",
42
+ "import": "./dist/entry/server.mjs"
43
43
  },
44
44
  "./testing": {
45
- "types": "./dist/testing.d.mts",
46
- "import": "./dist/testing.mjs"
45
+ "types": "./dist/types/entry/testing.d.ts",
46
+ "import": "./dist/entry/testing.mjs"
47
+ },
48
+ "./Approval": {
49
+ "types": "./dist/types/Approval.d.ts",
50
+ "import": "./dist/Approval.mjs"
51
+ },
52
+ "./Cleanup": {
53
+ "types": "./dist/types/Cleanup.d.ts",
54
+ "import": "./dist/Cleanup.mjs"
55
+ },
56
+ "./Cloudflare": {
57
+ "types": "./dist/types/Cloudflare.d.ts",
58
+ "import": "./dist/Cloudflare.mjs"
59
+ },
60
+ "./Connect": {
61
+ "types": "./dist/types/Connect.d.ts",
62
+ "import": "./dist/Connect.mjs"
63
+ },
64
+ "./Custody": {
65
+ "types": "./dist/types/Custody.d.ts",
66
+ "import": "./dist/Custody.mjs"
67
+ },
68
+ "./DnsRecord": {
69
+ "types": "./dist/types/DnsRecord.d.ts",
70
+ "import": "./dist/DnsRecord.mjs"
71
+ },
72
+ "./DomainKit": {
73
+ "types": "./dist/types/DomainKit.d.ts",
74
+ "import": "./dist/DomainKit.mjs"
75
+ },
76
+ "./DomainName": {
77
+ "types": "./dist/types/DomainName.d.ts",
78
+ "import": "./dist/DomainName.mjs"
79
+ },
80
+ "./Plan": {
81
+ "types": "./dist/types/Plan.d.ts",
82
+ "import": "./dist/Plan.mjs"
83
+ },
84
+ "./Principal": {
85
+ "types": "./dist/types/Principal.d.ts",
86
+ "import": "./dist/Principal.mjs"
87
+ },
88
+ "./Provider": {
89
+ "types": "./dist/types/Provider.d.ts",
90
+ "import": "./dist/Provider.mjs"
91
+ },
92
+ "./Providers": {
93
+ "types": "./dist/types/Providers.d.ts",
94
+ "import": "./dist/Providers.mjs"
95
+ },
96
+ "./Provision": {
97
+ "types": "./dist/types/Provision.d.ts",
98
+ "import": "./dist/Provision.mjs"
99
+ },
100
+ "./Reason": {
101
+ "types": "./dist/types/Reason.d.ts",
102
+ "import": "./dist/Reason.mjs"
103
+ },
104
+ "./Receipt": {
105
+ "types": "./dist/types/Receipt.d.ts",
106
+ "import": "./dist/Receipt.mjs"
107
+ },
108
+ "./Resolver": {
109
+ "types": "./dist/types/Resolver.d.ts",
110
+ "import": "./dist/Resolver.mjs"
111
+ },
112
+ "./Storage": {
113
+ "types": "./dist/types/Storage.d.ts",
114
+ "import": "./dist/Storage.mjs"
115
+ },
116
+ "./Vercel": {
117
+ "types": "./dist/types/Vercel.d.ts",
118
+ "import": "./dist/Vercel.mjs"
119
+ },
120
+ "./Verify": {
121
+ "types": "./dist/types/Verify.d.ts",
122
+ "import": "./dist/Verify.mjs"
47
123
  },
48
124
  "./package.json": "./package.json"
49
125
  },
50
126
  "scripts": {
51
- "build": "tsdown",
127
+ "build": "tsdown && tsc -p tsconfig.build.json",
52
128
  "clean": "rm -rf dist coverage",
53
129
  "release:check": "bun run typecheck && bun run test && bun run build && bun run typecheck:examples && bun run test:artifact",
54
130
  "test": "vitest run --exclude tests/artifact/**/*.test.ts",
@@ -56,10 +132,10 @@
56
132
  "test:consumers": "vitest run tests/artifact/packed-consumers.test.ts",
57
133
  "test:live:cloudflare": "bun tests/live/cloudflare.ts",
58
134
  "test:live:vercel": "bun tests/live/vercel.ts",
59
- "test:providers": "vitest run tests/providers",
60
135
  "test:watch": "vitest",
61
136
  "typecheck": "tsc --noEmit",
62
- "typecheck:examples": "tsc --project tsconfig.examples.json"
137
+ "typecheck:examples": "tsc --project tsconfig.examples.json",
138
+ "test:providers": "vitest run tests/providers"
63
139
  },
64
140
  "dependencies": {
65
141
  "@leichtgewicht/dns-packet": "6.0.3",
@@ -1,310 +0,0 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { Context, Crypto, Data, Effect, Layer, PlatformError, Schema, SchemaIssue, SchemaTransformation } from "effect";
3
- //#region src/invalid-input.ts
4
- var invalid_input_exports = /* @__PURE__ */ __exportAll({ Error: () => Error$2 });
5
- var Error$2 = class extends Schema.TaggedError()("InvalidInputError", { message: Schema.String }) {};
6
- //#endregion
7
- //#region src/domain/domain-name.ts
8
- var domain_name_exports = /* @__PURE__ */ __exportAll({
9
- Schema: () => Schema$2,
10
- decode: () => decode$3,
11
- parse: () => parse
12
- });
13
- const labelPattern = /^[a-z0-9_](?:[a-z0-9_-]{0,61}[a-z0-9_])?$/;
14
- const Type = Schema.String.check(Schema.makeFilter((value) => value.length <= 253 && value.includes(".") && value.split(".").every((label) => labelPattern.test(label)) ? void 0 : "Expected a fully qualified DNS name", { identifier: "DomainName" })).pipe(Schema.brand("DomainName"));
15
- /** Decodes user and wire strings into canonical domain names. */
16
- const Schema$2 = Schema.String.pipe(Schema.decodeTo(Type, SchemaTransformation.transformOrFail({
17
- decode: (input, options) => Effect.try({
18
- try: () => normalize(input),
19
- catch: (cause) => new SchemaIssue.InvalidValue({ message: cause instanceof Error ? cause.message : String(cause) }, input, options)
20
- }),
21
- encode: (domain) => Effect.succeed(domain)
22
- })));
23
- const decode$3 = Effect.fn("DomainName.decode")((input) => Schema.decodeUnknownEffect(Schema$2)(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
24
- function parse(input) {
25
- try {
26
- return Schema.decodeUnknownSync(Schema$2)(input);
27
- } catch (cause) {
28
- throw new Error$2({ message: cause instanceof Error ? cause.message : String(cause) });
29
- }
30
- }
31
- function normalize(input) {
32
- return input.trim().replace(/\.+$/, "").split(".").map((label) => {
33
- if (label.includes("_") || [...label].every((character) => character.charCodeAt(0) <= 127)) return label.toLowerCase();
34
- const normalized = new URL(`http://${label}.example`).hostname.split(".")[0];
35
- if (normalized === void 0) throw new Error("Domain label could not be normalized");
36
- return normalized.toLowerCase();
37
- }).join(".");
38
- }
39
- //#endregion
40
- //#region src/auth/connection.ts
41
- /** A provider account and authoritative zone selected for one domain attachment. */
42
- const ProviderTargetEvidence = Schema.Struct({
43
- /** The account display name observed during discovery, when the provider exposes one. */
44
- accountName: Schema.optionalKey(Schema.String),
45
- /** Nameserver and provider-state evidence observed during discovery. */
46
- nameservers: Schema.Array(Schema$2),
47
- status: Schema.String,
48
- /** Provider-specific authoritative-zone type, such as Cloudflare's `full` or Vercel's `external`. */
49
- zoneType: Schema.String
50
- });
51
- const ProviderTarget = Schema.Struct({
52
- accountId: Schema.String,
53
- accountKind: Schema.NullOr(Schema.Literals([
54
- "account",
55
- "personal",
56
- "team"
57
- ])),
58
- evidence: Schema.optionalKey(ProviderTargetEvidence),
59
- zoneId: Schema.String,
60
- zoneName: Schema$2
61
- });
62
- /** The lifecycle state visible to a host for an organization connection. */
63
- const ConnectionStatus = Schema.Literals([
64
- "active",
65
- "expired",
66
- "revocation-pending"
67
- ]);
68
- /** An organization-scoped provider connection. */
69
- const ProviderConnection = Schema.Struct({
70
- createdAt: Schema.DateFromString,
71
- id: Schema.String,
72
- method: Schema.Literals([
73
- "integration",
74
- "oauth2",
75
- "token"
76
- ]),
77
- ownerId: Schema.String,
78
- providerId: Schema.String,
79
- status: ConnectionStatus
80
- });
81
- /** An exact provider target attached to one organization domain. */
82
- const DomainAttachment = Schema.Struct({
83
- connectionId: Schema.String,
84
- createdAt: Schema.DateFromString,
85
- domain: Schema$2,
86
- id: Schema.String,
87
- target: ProviderTarget
88
- });
89
- /** Internal connection row; the authorization id is intentionally not part of the public shape. */
90
- const StoredConnection = Schema.Struct({
91
- authorizationId: Schema.String,
92
- createdAt: Schema.DateFromString,
93
- id: Schema.String,
94
- method: Schema.Literals([
95
- "integration",
96
- "oauth2",
97
- "token"
98
- ]),
99
- ownerId: Schema.String,
100
- providerId: Schema.String
101
- });
102
- var AuthorizationError = class extends Schema.TaggedError()("AuthorizationError", {
103
- category: Schema.Literal("authorization"),
104
- message: Schema.String,
105
- operation: Schema.String,
106
- retry: Schema.Literals([
107
- "never",
108
- "after-user-action",
109
- "safe",
110
- "unknown"
111
- ])
112
- }) {};
113
- const authorizationError = (message, operation) => new AuthorizationError({
114
- category: "authorization",
115
- message,
116
- operation,
117
- retry: "after-user-action"
118
- });
119
- /** Decode a public connection snapshot returned by a host. */
120
- const decode$2 = Effect.fn("ProviderConnection.decode")((input) => Schema.decodeUnknownEffect(ProviderConnection)(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
121
- const validate$1 = Effect.fn("ProviderConnection.validate")((input) => Schema.decodeUnknownEffect(Schema.toType(ProviderConnection))(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
122
- const encode$2 = Schema.encodeSync(ProviderConnection);
123
- /** Derive a public connection projection from its private authorization state. */
124
- function project(connection, authorization, credential, now = /* @__PURE__ */ new Date()) {
125
- const status = authorization.revocation._tag === "Pending" ? "revocation-pending" : credential.refreshToken === null && credential.expiresAt !== null && (Number.isNaN(credential.expiresAt.valueOf()) || credential.expiresAt <= now) ? "expired" : "active";
126
- return {
127
- createdAt: connection.createdAt,
128
- id: connection.id,
129
- method: connection.method,
130
- ownerId: connection.ownerId,
131
- providerId: connection.providerId,
132
- status
133
- };
134
- }
135
- /** Assert that an exact attachment is usable for one DNS operation. */
136
- function assertAttachment(input) {
137
- const credentialStatus = "status" in input.connection ? input.connection.status : input.credential === void 0 ? null : project(input.connection, input.authorization, input.credential, input.now).status;
138
- if (input.connection.providerId !== input.providerId || input.authorization.providerId !== input.providerId || input.authorization.revocation._tag !== "Active" || input.attachment.connectionId !== input.connection.id || credentialStatus !== "active") throw authorizationError("Domain attachment is not active for this provider", "Connection.assertAttachment");
139
- if (!input.authorization.requiredCapabilities.includes(input.capability)) throw authorizationError(`Provider authorization lacks the ${input.capability} capability`, "Connection.assertAttachment");
140
- if (!input.authorization.capabilityEvidence.some((item) => item.capability === input.capability)) throw authorizationError(`Provider authorization has no evidence for the ${input.capability} capability`, "Connection.assertAttachment");
141
- let domain;
142
- try {
143
- domain = parse(input.domain);
144
- } catch (cause) {
145
- if (cause instanceof Error$2) throw cause;
146
- throw new Error$2({ message: cause instanceof Error ? cause.message : String(cause) });
147
- }
148
- if (input.attachment.domain !== domain && !domain.endsWith(`.${input.attachment.domain}`)) throw authorizationError("Domain attachment does not match the requested domain", "Connection.assertAttachment");
149
- return domain;
150
- }
151
- //#endregion
152
- //#region src/auth/provider-context.ts
153
- var provider_context_exports = /* @__PURE__ */ __exportAll({
154
- Envelope: () => Envelope,
155
- codec: () => codec,
156
- decode: () => decode$1,
157
- encode: () => encode$1
158
- });
159
- /** A provider-owned, versioned, non-secret context value persisted by the host. */
160
- const Envelope = Schema.Struct({
161
- value: Schema.Json,
162
- version: Schema.String
163
- });
164
- /** Build an adapter-owned context codec from a schema and stable version identifier. */
165
- function codec(version, schema) {
166
- return {
167
- 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 })))),
168
- encode: Effect.fn("ProviderContext.encode")((value) => Schema.encodeEffect(schema)(value).pipe(Effect.flatMap((encoded) => Schema.decodeUnknownEffect(Schema.Json)(encoded)), Effect.map((encoded) => ({
169
- value: encoded,
170
- version
171
- })), Effect.mapError((cause) => new Error$2({ message: cause.message })))),
172
- version
173
- };
174
- }
175
- const decode$1 = Effect.fn("ProviderContext.Envelope.decode")((input) => Schema.decodeUnknownEffect(Envelope)(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
176
- const encode$1 = Schema.encodeSync(Envelope);
177
- //#endregion
178
- //#region src/auth/authorization.ts
179
- var authorization_exports = /* @__PURE__ */ __exportAll({
180
- Capability: () => Capability,
181
- CapabilityEvidence: () => CapabilityEvidence,
182
- Evidence: () => Evidence,
183
- EvidenceSchema: () => EvidenceSchema,
184
- Revocation: () => Revocation,
185
- Schema: () => Schema$1,
186
- decode: () => decode,
187
- encode: () => encode,
188
- evidenceFor: () => evidenceFor,
189
- validate: () => validate
190
- });
191
- const Capability = Schema.Literals(["dns:read", "dns:write"]);
192
- const Evidence = Data.taggedEnum();
193
- const EvidenceSchema = Schema.TaggedUnion({
194
- Declared: {},
195
- Exercised: { observedAt: Schema.DateFromString },
196
- Introspected: { observedAt: Schema.DateFromString }
197
- });
198
- const CapabilityEvidence = Schema.Struct({
199
- capability: Capability,
200
- evidence: EvidenceSchema
201
- });
202
- const RevocationSchema = Schema.TaggedUnion({
203
- Active: {},
204
- Pending: { requestedAt: Schema.DateFromString }
205
- });
206
- /** Revocation state schema and callable constructors for trusted lifecycle values. */
207
- const Revocation = {
208
- Schema: RevocationSchema,
209
- Active: () => RevocationSchema.cases.Active.make({}),
210
- Pending: (input) => RevocationSchema.cases.Pending.make(input)
211
- };
212
- /** A provider credential authorization shared by one or more organization connections. */
213
- const Schema$1 = Schema.Struct({
214
- authorizedById: Schema.String,
215
- capabilityEvidence: Schema.Array(CapabilityEvidence),
216
- createdAt: Schema.DateFromString,
217
- id: Schema.String,
218
- method: Schema.Literals([
219
- "integration",
220
- "oauth2",
221
- "token"
222
- ]),
223
- providerContext: Envelope,
224
- providerId: Schema.String,
225
- requiredCapabilities: Schema.Array(Capability),
226
- revocation: Revocation.Schema,
227
- scopes: Schema.Array(Schema.String)
228
- });
229
- const decode = Effect.fn("ProviderAuthorization.decode")((input) => Schema.decodeUnknownEffect(Schema$1)(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
230
- const validate = Effect.fn("ProviderAuthorization.validate")((input) => Schema.decodeUnknownEffect(Schema.toType(Schema$1))(input).pipe(Effect.mapError((cause) => new Error$2({ message: cause.message }))));
231
- const encode = Schema.encodeSync(Schema$1);
232
- function evidenceFor(authorization, capability) {
233
- return authorization.capabilityEvidence.find((item) => item.capability === capability)?.evidence;
234
- }
235
- //#endregion
236
- //#region src/auth/lifecycle-repository.ts
237
- /** Serializable durable state. Credential material is deliberately sealed separately. */
238
- const AggregateSchema = Schema.Struct({
239
- authorization: Schema$1,
240
- connections: Schema.Array(StoredConnection),
241
- attachments: Schema.Array(DomainAttachment)
242
- });
243
- var Error$1 = class extends Schema.TaggedError()("ManagedDnsLifecycleError", {
244
- category: Schema.Literal("storage"),
245
- message: Schema.String,
246
- operation: Schema.String,
247
- retry: Schema.Literals([
248
- "never",
249
- "after-user-action",
250
- "safe",
251
- "unknown"
252
- ])
253
- }) {};
254
- var Service = class extends Context.Service()("@domainkit/ManagedDnsConnections") {};
255
- //#endregion
256
- //#region src/plan/canonical-json.ts
257
- var canonical_json_exports = /* @__PURE__ */ __exportAll({
258
- CryptoError: () => CryptoError,
259
- sha256Encoded: () => sha256Encoded,
260
- sha256Json: () => sha256Json,
261
- sha256Text: () => sha256Text,
262
- stringify: () => stringify,
263
- webCryptoLayer: () => webCryptoLayer
264
- });
265
- var CryptoError = class extends Schema.TaggedError()("CryptoError", { message: Schema.String }) {};
266
- /** Deterministic JSON serialization for already schema-encoded protocol values. */
267
- function stringify(value) {
268
- if (value === null || typeof value !== "object") {
269
- const encoded = JSON.stringify(value);
270
- if (encoded === void 0) throw new TypeError("Value is not representable as JSON");
271
- return encoded;
272
- }
273
- if (isJsonArray(value)) return `[${value.map(stringify).join(",")}]`;
274
- return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, entry]) => `${JSON.stringify(key)}:${stringify(entry)}`).join(",")}}`;
275
- }
276
- function isJsonArray(value) {
277
- return Array.isArray(value);
278
- }
279
- const sha256Text = Effect.fn("Digest.sha256Text")(function* (value) {
280
- 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("");
281
- });
282
- const sha256Json = Effect.fn("Digest.sha256Json")((value) => Effect.try({
283
- try: () => stringify(value),
284
- catch: (cause) => new CryptoError({ message: cause instanceof Error ? cause.message : String(cause) })
285
- }).pipe(Effect.flatMap(sha256Text)));
286
- function sha256EncodedProgram(schema, value) {
287
- 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));
288
- }
289
- const sha256Encoded = Effect.fn("Digest.sha256Encoded")(sha256EncodedProgram);
290
- /** Portable Web Crypto implementation for hosts that want a ready-made Layer. */
291
- const webCryptoLayer = Layer.succeed(Crypto.Crypto, Crypto.make({
292
- randomBytes: (size) => crypto.getRandomValues(new Uint8Array(size)),
293
- digest: (algorithm, data) => Effect.tryPromise({
294
- try: async () => {
295
- const bytes = new Uint8Array(data.byteLength);
296
- bytes.set(data);
297
- return new Uint8Array(await crypto.subtle.digest(algorithm, bytes.buffer));
298
- },
299
- catch: (cause) => PlatformError.systemError({
300
- _tag: "Unknown",
301
- module: "WebCrypto",
302
- method: "digest",
303
- cause
304
- })
305
- })
306
- }));
307
- //#endregion
308
- export { Error$2 as A, encode$2 as C, decode$3 as D, Schema$2 as E, domain_name_exports as O, decode$2 as S, validate$1 as T, ProviderTarget as _, AggregateSchema as a, assertAttachment as b, Evidence as c, codec as d, provider_context_exports as f, ProviderConnection as g, DomainAttachment as h, webCryptoLayer as i, invalid_input_exports as j, parse as k, Revocation as l, ConnectionStatus as m, sha256Encoded as n, Error$1 as o, AuthorizationError as p, stringify as r, Service as s, canonical_json_exports as t, authorization_exports as u, ProviderTargetEvidence as v, project as w, authorizationError as x, StoredConnection as y };
309
-
310
- //# sourceMappingURL=canonical-json-CQYKsZw7.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"canonical-json-CQYKsZw7.mjs","names":["Error","S","Schema","decode","InvalidInputError","S","DomainName.Schema","decode","InvalidInputError","validate","encode","DomainName.parse","InvalidInputError","decode","encode","S","Schema","ProviderContext.Envelope","InvalidInputError","ProviderAuthorization.Schema","Connection.StoredConnection","Connection.DomainAttachment","Error"],"sources":["../src/invalid-input.ts","../src/domain/domain-name.ts","../src/auth/connection.ts","../src/auth/provider-context.ts","../src/auth/authorization.ts","../src/auth/lifecycle-repository.ts","../src/plan/canonical-json.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nexport class Error extends Schema.TaggedError<Error>()(\"InvalidInputError\", {\n message: Schema.String,\n}) {}\n","import { Effect, Schema as S, SchemaIssue, SchemaTransformation } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\nconst labelPattern = /^[a-z0-9_](?:[a-z0-9_-]{0,61}[a-z0-9_])?$/;\n\nconst Type = S.String.check(\n S.makeFilter<string>(\n (value) =>\n value.length <= 253 &&\n value.includes(\".\") &&\n value.split(\".\").every((label) => labelPattern.test(label))\n ? undefined\n : \"Expected a fully qualified DNS name\",\n { identifier: \"DomainName\" },\n ),\n).pipe(S.brand(\"DomainName\"));\n\n/** A lower-case, fully qualified DNS name without a trailing dot. */\nexport type DomainName = typeof Type.Type;\n\n/** Decodes user and wire strings into canonical domain names. */\nexport const Schema = S.String.pipe(\n S.decodeTo(\n Type,\n SchemaTransformation.transformOrFail({\n decode: (input, options) =>\n Effect.try({\n try: () => normalize(input),\n catch: (cause) =>\n new SchemaIssue.InvalidValue(\n { message: cause instanceof Error ? cause.message : String(cause) },\n input,\n options,\n ),\n }),\n encode: (domain) => Effect.succeed(domain),\n }),\n ),\n);\n\nexport const decode = Effect.fn(\"DomainName.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport function parse(input: unknown): DomainName {\n try {\n return S.decodeUnknownSync(Schema)(input);\n } catch (cause) {\n throw new InvalidInputError({\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n}\n\nfunction normalize(input: string): string {\n const labels = input\n .trim()\n .replace(/\\.+$/, \"\")\n .split(\".\")\n .map((label) => {\n if (label.includes(\"_\") || [...label].every((character) => character.charCodeAt(0) <= 127)) {\n return label.toLowerCase();\n }\n const hostname = new URL(`http://${label}.example`).hostname;\n const normalized = hostname.split(\".\")[0];\n if (normalized === undefined) throw new Error(\"Domain label could not be normalized\");\n return normalized.toLowerCase();\n });\n return labels.join(\".\");\n}\n","import { Effect, Schema as S } from \"effect\";\n\nimport * as DomainName from \"../domain/domain-name.ts\";\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport type { OAuthMethod } from \"./manifest.ts\";\nimport type * as ProviderAuthorization from \"./authorization.ts\";\nimport type { Value as Secret } from \"./secret.ts\";\n\n/** A provider account and authoritative zone selected for one domain attachment. */\nexport const ProviderTargetEvidence = S.Struct({\n /** The account display name observed during discovery, when the provider exposes one. */\n accountName: S.optionalKey(S.String),\n /** Nameserver and provider-state evidence observed during discovery. */\n nameservers: S.Array(DomainName.Schema),\n status: S.String,\n /** Provider-specific authoritative-zone type, such as Cloudflare's `full` or Vercel's `external`. */\n zoneType: S.String,\n});\nexport interface ProviderTargetEvidence extends S.Schema.Type<typeof ProviderTargetEvidence> {}\n\nexport const ProviderTarget = S.Struct({\n accountId: S.String,\n accountKind: S.NullOr(S.Literals([\"account\", \"personal\", \"team\"])),\n evidence: S.optionalKey(ProviderTargetEvidence),\n zoneId: S.String,\n zoneName: DomainName.Schema,\n});\nexport interface ProviderTarget extends S.Schema.Type<typeof ProviderTarget> {}\n\n/** The lifecycle state visible to a host for an organization connection. */\nexport const ConnectionStatus = S.Literals([\"active\", \"expired\", \"revocation-pending\"]);\nexport type ConnectionStatus = typeof ConnectionStatus.Type;\n\n/** An organization-scoped provider connection. */\nexport const ProviderConnection = S.Struct({\n createdAt: S.DateFromString,\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n ownerId: S.String,\n providerId: S.String,\n status: ConnectionStatus,\n});\nexport interface ProviderConnection extends S.Schema.Type<typeof ProviderConnection> {}\n\n/** An exact provider target attached to one organization domain. */\nexport const DomainAttachment = S.Struct({\n connectionId: S.String,\n createdAt: S.DateFromString,\n domain: DomainName.Schema,\n id: S.String,\n target: ProviderTarget,\n});\nexport interface DomainAttachment extends S.Schema.Type<typeof DomainAttachment> {}\n\n/** Internal connection row; the authorization id is intentionally not part of the public shape. */\nexport const StoredConnection = S.Struct({\n authorizationId: S.String,\n createdAt: S.DateFromString,\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n ownerId: S.String,\n providerId: S.String,\n});\nexport interface StoredConnection extends S.Schema.Type<typeof StoredConnection> {}\n\n/** Internal credential material retained by the host's persistence implementation. */\nexport interface StoredCredential {\n readonly accessToken: Secret;\n readonly expiresAt: Date | null;\n readonly refreshToken: Secret | null;\n readonly tokenType: string;\n}\n\n/** The provider context carried through an interactive connection continuation. */\nexport interface OAuthContinuation {\n readonly clientId: string;\n readonly codeVerifier: Secret;\n readonly expiresAt: Date;\n readonly authorizationId?: string;\n readonly method: OAuthMethod;\n readonly ownerId: string;\n readonly redirectUri: string;\n readonly stateHash: string;\n readonly authorizedById: string;\n}\n\nexport class AuthorizationError extends S.TaggedError<AuthorizationError>()(\"AuthorizationError\", {\n category: S.Literal(\"authorization\"),\n message: S.String,\n operation: S.String,\n retry: S.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\nexport const authorizationError = (message: string, operation: string): AuthorizationError =>\n new AuthorizationError({\n category: \"authorization\",\n message,\n operation,\n retry: \"after-user-action\",\n });\n\n/** Decode a public connection snapshot returned by a host. */\nexport const decode = Effect.fn(\"ProviderConnection.decode\")((input: unknown) =>\n S.decodeUnknownEffect(ProviderConnection)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const validate = Effect.fn(\"ProviderConnection.validate\")((input: unknown) =>\n S.decodeUnknownEffect(S.toType(ProviderConnection))(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = S.encodeSync(ProviderConnection);\n\n/** Derive a public connection projection from its private authorization state. */\nexport function project(\n connection: StoredConnection,\n authorization: ProviderAuthorization.ProviderAuthorization,\n credential: StoredCredential,\n now = new Date(),\n): ProviderConnection {\n const status: ConnectionStatus =\n authorization.revocation._tag === \"Pending\"\n ? \"revocation-pending\"\n : credential.refreshToken === null &&\n credential.expiresAt !== null &&\n (Number.isNaN(credential.expiresAt.valueOf()) || credential.expiresAt <= now)\n ? \"expired\"\n : \"active\";\n return {\n createdAt: connection.createdAt,\n id: connection.id,\n method: connection.method,\n ownerId: connection.ownerId,\n providerId: connection.providerId,\n status,\n };\n}\n\n/** Assert that an exact attachment is usable for one DNS operation. */\nexport function assertAttachment(input: {\n readonly attachment: DomainAttachment;\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly capability: ProviderAuthorization.Capability;\n readonly connection: StoredConnection | ProviderConnection;\n readonly credential?: StoredCredential;\n readonly domain: string;\n readonly now?: Date;\n readonly providerId: string;\n}): DomainName.DomainName {\n const credentialStatus =\n \"status\" in input.connection\n ? input.connection.status\n : input.credential === undefined\n ? null\n : project(input.connection, input.authorization, input.credential, input.now).status;\n if (\n input.connection.providerId !== input.providerId ||\n input.authorization.providerId !== input.providerId ||\n input.authorization.revocation._tag !== \"Active\" ||\n input.attachment.connectionId !== input.connection.id ||\n credentialStatus !== \"active\"\n ) {\n throw authorizationError(\n \"Domain attachment is not active for this provider\",\n \"Connection.assertAttachment\",\n );\n }\n if (!input.authorization.requiredCapabilities.includes(input.capability)) {\n throw authorizationError(\n `Provider authorization lacks the ${input.capability} capability`,\n \"Connection.assertAttachment\",\n );\n }\n if (\n !input.authorization.capabilityEvidence.some((item) => item.capability === input.capability)\n ) {\n throw authorizationError(\n `Provider authorization has no evidence for the ${input.capability} capability`,\n \"Connection.assertAttachment\",\n );\n }\n let domain: DomainName.DomainName;\n try {\n domain = DomainName.parse(input.domain);\n } catch (cause) {\n if (cause instanceof InvalidInputError) throw cause;\n throw new InvalidInputError({\n message: cause instanceof Error ? cause.message : String(cause),\n });\n }\n if (input.attachment.domain !== domain && !domain.endsWith(`.${input.attachment.domain}`)) {\n throw authorizationError(\n \"Domain attachment does not match the requested domain\",\n \"Connection.assertAttachment\",\n );\n }\n return domain;\n}\n","import { Effect, Schema } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\n\n/** A provider-owned, versioned, non-secret context value persisted by the host. */\nexport const Envelope = Schema.Struct({\n value: Schema.Json,\n version: Schema.String,\n});\nexport interface Envelope extends Schema.Schema.Type<typeof Envelope> {}\n\nexport interface Codec<A> {\n readonly decode: (envelope: Envelope) => Effect.Effect<A, InvalidInputError>;\n readonly encode: (value: A) => Effect.Effect<Envelope, InvalidInputError>;\n readonly version: string;\n}\n\n/** Build an adapter-owned context codec from a schema and stable version identifier. */\nexport function codec<A, I>(version: string, schema: Schema.Codec<A, I>): Codec<A> {\n return {\n decode: Effect.fn(\"ProviderContext.decode\")((envelope) =>\n envelope.version !== version\n ? Effect.fail(\n new InvalidInputError({\n message: `Unsupported provider context version: ${envelope.version}`,\n }),\n )\n : Schema.decodeUnknownEffect(schema)(envelope.value).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n ),\n encode: Effect.fn(\"ProviderContext.encode\")((value) =>\n Schema.encodeEffect(schema)(value).pipe(\n Effect.flatMap((encoded) => Schema.decodeUnknownEffect(Schema.Json)(encoded)),\n Effect.map((encoded) => ({ value: encoded, version })),\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n ),\n version,\n };\n}\n\nexport const decode = Effect.fn(\"ProviderContext.Envelope.decode\")((input: unknown) =>\n Schema.decodeUnknownEffect(Envelope)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = Schema.encodeSync(Envelope);\n","import { Data, Effect, Schema as S } from \"effect\";\n\nimport { Error as InvalidInputError } from \"../invalid-input.ts\";\nimport * as ProviderContext from \"./provider-context.ts\";\n\nexport const Capability = S.Literals([\"dns:read\", \"dns:write\"]);\nexport type Capability = typeof Capability.Type;\n\nexport type Evidence = Data.TaggedEnum<{\n Declared: {};\n Exercised: { readonly observedAt: Date };\n Introspected: { readonly observedAt: Date };\n}>;\nexport const Evidence = Data.taggedEnum<Evidence>();\n\nexport const EvidenceSchema = S.TaggedUnion({\n Declared: {},\n Exercised: { observedAt: S.DateFromString },\n Introspected: { observedAt: S.DateFromString },\n});\n\nexport const CapabilityEvidence = S.Struct({\n capability: Capability,\n evidence: EvidenceSchema,\n});\nexport interface CapabilityEvidence extends S.Schema.Type<typeof CapabilityEvidence> {}\n\nconst RevocationSchema = S.TaggedUnion({\n Active: {},\n Pending: { requestedAt: S.DateFromString },\n});\n/** Revocation state schema and callable constructors for trusted lifecycle values. */\nexport const Revocation = {\n Schema: RevocationSchema,\n Active: () => RevocationSchema.cases.Active.make({}),\n Pending: (input: Parameters<typeof RevocationSchema.cases.Pending.make>[0]) =>\n RevocationSchema.cases.Pending.make(input),\n};\nexport type Revocation = typeof RevocationSchema.Type;\n\n/** A provider credential authorization shared by one or more organization connections. */\nexport const Schema = S.Struct({\n authorizedById: S.String,\n capabilityEvidence: S.Array(CapabilityEvidence),\n createdAt: S.DateFromString,\n id: S.String,\n method: S.Literals([\"integration\", \"oauth2\", \"token\"]),\n providerContext: ProviderContext.Envelope,\n providerId: S.String,\n requiredCapabilities: S.Array(Capability),\n revocation: Revocation.Schema,\n scopes: S.Array(S.String),\n});\nexport interface ProviderAuthorization extends S.Schema.Type<typeof Schema> {}\n\nexport const decode = Effect.fn(\"ProviderAuthorization.decode\")((input: unknown) =>\n S.decodeUnknownEffect(Schema)(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const validate = Effect.fn(\"ProviderAuthorization.validate\")((input: unknown) =>\n S.decodeUnknownEffect(S.toType(Schema))(input).pipe(\n Effect.mapError((cause) => new InvalidInputError({ message: cause.message })),\n ),\n);\n\nexport const encode = S.encodeSync(Schema);\n\nexport function evidenceFor(\n authorization: ProviderAuthorization,\n capability: Capability,\n): Evidence | undefined {\n return authorization.capabilityEvidence.find((item) => item.capability === capability)?.evidence;\n}\n","import { Context, Effect, Schema } from \"effect\";\n\nimport * as ProviderAuthorization from \"./authorization.ts\";\nimport * as Connection from \"./connection.ts\";\n\n/** Private aggregate owned by the managed-DNS persistence capability. */\nexport interface Aggregate {\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connections: ReadonlyArray<Connection.StoredConnection>;\n readonly attachments: ReadonlyArray<Connection.DomainAttachment>;\n readonly credential: Connection.StoredCredential;\n}\n\n/** Serializable durable state. Credential material is deliberately sealed separately. */\nexport const AggregateSchema = Schema.Struct({\n authorization: ProviderAuthorization.Schema,\n connections: Schema.Array(Connection.StoredConnection),\n attachments: Schema.Array(Connection.DomainAttachment),\n});\n\nexport interface ConnectInput {\n readonly authorization: ProviderAuthorization.ProviderAuthorization;\n readonly connection: Connection.StoredConnection;\n readonly credential: Connection.StoredCredential;\n /** The authorization id observed before building a reuse update, if any. */\n readonly expectedAuthorizationId?: string;\n /** The owner connection id observed before building a reuse update, if any. */\n readonly expectedConnectionId?: string;\n}\n\nexport interface AttachmentResult {\n readonly attachment: Connection.DomainAttachment;\n readonly connection: Connection.ProviderConnection;\n}\n\nexport interface DetachResult {\n readonly attachment: Connection.DomainAttachment;\n readonly connection: Connection.ProviderConnection;\n readonly remainingAttachments: number;\n}\n\nexport interface DisconnectResult {\n readonly connection: Connection.ProviderConnection;\n readonly remainingConnections: number;\n readonly revokedAuthorization: boolean;\n}\n\nexport class Error extends Schema.TaggedError<Error>()(\"ManagedDnsLifecycleError\", {\n category: Schema.Literal(\"storage\"),\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\n/**\n * Persistence capability for the managed-DNS model.\n *\n * Implementations own the atomic aggregate containing one provider credential authorization,\n * organization connections, and exact domain attachments. Provider authorization is deliberately\n * an implementation detail of the capability; public callers operate on the projections returned\n * by the connection and attachment methods.\n */\nexport interface Interface {\n readonly attach: (input: {\n readonly attachment: Connection.DomainAttachment;\n readonly connectionId: string;\n readonly ownerId: string;\n }) => Effect.Effect<AttachmentResult, Error>;\n readonly connect: (input: ConnectInput) => Effect.Effect<Aggregate, Error>;\n readonly detach: (input: {\n readonly attachmentId: string;\n readonly ownerId: string;\n }) => Effect.Effect<DetachResult, Error>;\n readonly disconnect: <E>(input: {\n readonly connectionId: string;\n readonly ownerId: string;\n readonly revoke: (\n authorization: ProviderAuthorization.ProviderAuthorization,\n ) => Effect.Effect<void, E>;\n }) => Effect.Effect<DisconnectResult, Error | E>;\n readonly findConnection: (\n ownerId: string,\n authorizationId: string,\n ) => Effect.Effect<Connection.StoredConnection | null, Error>;\n readonly get: (authorizationId: string) => Effect.Effect<Aggregate | null, Error>;\n readonly getAttachment: (\n attachmentId: string,\n ) => Effect.Effect<Connection.DomainAttachment | null, Error>;\n readonly getByConnectionId: (connectionId: string) => Effect.Effect<Aggregate | null, Error>;\n readonly listAttachments: (\n connectionId: string,\n ownerId: string,\n ) => Effect.Effect<ReadonlyArray<Connection.DomainAttachment>, Error>;\n readonly promoteEvidence: (\n authorizationId: string,\n evidence: ReadonlyArray<ProviderAuthorization.CapabilityEvidence>,\n ) => Effect.Effect<Aggregate, Error>;\n readonly recover: <E>(input: {\n readonly authorizationId: string;\n readonly revoke: (\n authorization: ProviderAuthorization.ProviderAuthorization,\n ) => Effect.Effect<void, E>;\n }) => Effect.Effect<DisconnectResult, Error | E>;\n readonly rotate: (\n authorizationId: string,\n credential: Connection.StoredCredential,\n ) => Effect.Effect<Aggregate, Error>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\n \"@domainkit/ManagedDnsConnections\",\n) {}\n","import { Crypto, Effect, Layer, PlatformError, Schema } from \"effect\";\n\nexport class CryptoError extends Schema.TaggedError<CryptoError>()(\"CryptoError\", {\n message: Schema.String,\n}) {}\n\nexport type Json =\n | null\n | boolean\n | number\n | string\n | ReadonlyArray<Json>\n | { readonly [key: string]: Json };\n\n/** Deterministic JSON serialization for already schema-encoded protocol values. */\nexport function stringify(value: Json): string {\n if (value === null || typeof value !== \"object\") {\n const encoded = JSON.stringify(value);\n if (encoded === undefined) throw new TypeError(\"Value is not representable as JSON\");\n return encoded;\n }\n if (isJsonArray(value)) return `[${value.map(stringify).join(\",\")}]`;\n return `{${Object.entries(value)\n .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))\n .map(([key, entry]) => `${JSON.stringify(key)}:${stringify(entry)}`)\n .join(\",\")}}`;\n}\n\nfunction isJsonArray(value: Json): value is ReadonlyArray<Json> {\n return Array.isArray(value);\n}\n\nexport const sha256Text = Effect.fn(\"Digest.sha256Text\")(function* (value: string) {\n const cryptoService = yield* Crypto.Crypto;\n const digest = yield* cryptoService\n .digest(\"SHA-256\", new TextEncoder().encode(value))\n .pipe(Effect.mapError((cause) => new CryptoError({ message: cause.message })));\n return [...digest].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n});\n\nexport const sha256Json = Effect.fn(\"Digest.sha256Json\")((value: Json) =>\n Effect.try({\n try: () => stringify(value),\n catch: (cause) =>\n new CryptoError({ message: cause instanceof Error ? cause.message : String(cause) }),\n }).pipe(Effect.flatMap(sha256Text)),\n);\n\nfunction sha256EncodedProgram<S extends Schema.Constraint>(\n schema: S,\n value: S[\"Type\"],\n): Effect.Effect<string, CryptoError, Crypto.Crypto | S[\"EncodingServices\"]> {\n return Schema.encodeEffect(schema)(value).pipe(\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n Effect.flatMap(Schema.decodeUnknownEffect(Schema.Json)),\n Effect.mapError((cause) => new CryptoError({ message: cause.message })),\n Effect.flatMap(sha256Json),\n );\n}\n\nexport const sha256Encoded = Effect.fn(\"Digest.sha256Encoded\")(sha256EncodedProgram);\n\n/** Portable Web Crypto implementation for hosts that want a ready-made Layer. */\nexport const webCryptoLayer: Layer.Layer<Crypto.Crypto> = Layer.succeed(\n Crypto.Crypto,\n Crypto.make({\n randomBytes: (size) => crypto.getRandomValues(new Uint8Array(size)),\n digest: (algorithm, data) =>\n Effect.tryPromise({\n try: async () => {\n const bytes = new Uint8Array(data.byteLength);\n bytes.set(data);\n return new Uint8Array(await crypto.subtle.digest(algorithm, bytes.buffer));\n },\n catch: (cause) =>\n PlatformError.systemError({\n _tag: \"Unknown\",\n module: \"WebCrypto\",\n method: \"digest\",\n cause,\n }),\n }),\n }),\n);\n"],"mappings":";;;;AAEA,IAAaA,UAAb,cAA2B,OAAO,YAAmB,CAAC,CAAC,qBAAqB,EAC1E,SAAS,OAAO,OAClB,CAAC,CAAC,CAAC,CAAC;;;;;;;;ACAJ,MAAM,eAAe;AAErB,MAAM,OAAOC,OAAE,OAAO,MACpBA,OAAE,YACC,UACC,MAAM,UAAU,OAChB,MAAM,SAAS,GAAG,KAClB,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,UAAU,aAAa,KAAK,KAAK,CAAC,IACtD,KAAA,IACA,uCACN,EAAE,YAAY,aAAa,CAC7B,CACF,CAAC,CAAC,KAAKA,OAAE,MAAM,YAAY,CAAC;;AAM5B,MAAaC,WAASD,OAAE,OAAO,KAC7BA,OAAE,SACA,MACA,qBAAqB,gBAAgB;CACnC,SAAS,OAAO,YACd,OAAO,IAAI;EACT,WAAW,UAAU,KAAK;EAC1B,QAAQ,UACN,IAAI,YAAY,aACd,EAAE,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GAClE,OACA,OACF;CACJ,CAAC;CACH,SAAS,WAAW,OAAO,QAAQ,MAAM;AAC3C,CAAC,CACH,CACF;AAEA,MAAaE,WAAS,OAAO,GAAG,mBAAmB,CAAC,EAAE,UACpDF,OAAE,oBAAoBC,QAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACnC,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,SAAgB,MAAM,OAA4B;CAChD,IAAI;EACF,OAAOH,OAAE,kBAAkBC,QAAM,CAAC,CAAC,KAAK;CAC1C,SAAS,OAAO;EACd,MAAM,IAAIE,QAAkB,EAC1B,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAChE,CAAC;CACH;AACF;AAEA,SAAS,UAAU,OAAuB;CAcxC,OAbe,MACZ,KAAK,CAAC,CACN,QAAQ,QAAQ,EAAE,CAAC,CACnB,MAAM,GAAG,CAAC,CACV,KAAK,UAAU;EACd,IAAI,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,cAAc,UAAU,WAAW,CAAC,KAAK,GAAG,GACvF,OAAO,MAAM,YAAY;EAG3B,MAAM,aADW,IAAI,IAAI,UAAU,MAAM,SAAS,CAAC,CAAC,SACxB,MAAM,GAAG,CAAC,CAAC;EACvC,IAAI,eAAe,KAAA,GAAW,MAAM,IAAI,MAAM,sCAAsC;EACpF,OAAO,WAAW,YAAY;CAChC,CACU,CAAC,CAAC,KAAK,GAAG;AACxB;;;;AC/DA,MAAa,yBAAyBC,OAAE,OAAO;;CAE7C,aAAaA,OAAE,YAAYA,OAAE,MAAM;;CAEnC,aAAaA,OAAE,MAAMC,QAAiB;CACtC,QAAQD,OAAE;;CAEV,UAAUA,OAAE;AACd,CAAC;AAGD,MAAa,iBAAiBA,OAAE,OAAO;CACrC,WAAWA,OAAE;CACb,aAAaA,OAAE,OAAOA,OAAE,SAAS;EAAC;EAAW;EAAY;CAAM,CAAC,CAAC;CACjE,UAAUA,OAAE,YAAY,sBAAsB;CAC9C,QAAQA,OAAE;CACV,UAAUC;AACZ,CAAC;;AAID,MAAa,mBAAmBD,OAAE,SAAS;CAAC;CAAU;CAAW;AAAoB,CAAC;;AAItF,MAAa,qBAAqBA,OAAE,OAAO;CACzC,WAAWA,OAAE;CACb,IAAIA,OAAE;CACN,QAAQA,OAAE,SAAS;EAAC;EAAe;EAAU;CAAO,CAAC;CACrD,SAASA,OAAE;CACX,YAAYA,OAAE;CACd,QAAQ;AACV,CAAC;;AAID,MAAa,mBAAmBA,OAAE,OAAO;CACvC,cAAcA,OAAE;CAChB,WAAWA,OAAE;CACb,QAAQC;CACR,IAAID,OAAE;CACN,QAAQ;AACV,CAAC;;AAID,MAAa,mBAAmBA,OAAE,OAAO;CACvC,iBAAiBA,OAAE;CACnB,WAAWA,OAAE;CACb,IAAIA,OAAE;CACN,QAAQA,OAAE,SAAS;EAAC;EAAe;EAAU;CAAO,CAAC;CACrD,SAASA,OAAE;CACX,YAAYA,OAAE;AAChB,CAAC;AAwBD,IAAa,qBAAb,cAAwCA,OAAE,YAAgC,CAAC,CAAC,sBAAsB;CAChG,UAAUA,OAAE,QAAQ,eAAe;CACnC,SAASA,OAAE;CACX,WAAWA,OAAE;CACb,OAAOA,OAAE,SAAS;EAAC;EAAS;EAAqB;EAAQ;CAAS,CAAC;AACrE,CAAC,CAAC,CAAC,CAAC;AAEJ,MAAa,sBAAsB,SAAiB,cAClD,IAAI,mBAAmB;CACrB,UAAU;CACV;CACA;CACA,OAAO;AACT,CAAC;;AAGH,MAAaE,WAAS,OAAO,GAAG,2BAA2B,CAAC,EAAE,UAC5DF,OAAE,oBAAoB,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,KAC/C,OAAO,UAAU,UAAU,IAAIG,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaC,aAAW,OAAO,GAAG,6BAA6B,CAAC,EAAE,UAChEJ,OAAE,oBAAoBA,OAAE,OAAO,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KACzD,OAAO,UAAU,UAAU,IAAIG,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaE,WAASL,OAAE,WAAW,kBAAkB;;AAGrD,SAAgB,QACd,YACA,eACA,YACA,sBAAM,IAAI,KAAK,GACK;CACpB,MAAM,SACJ,cAAc,WAAW,SAAS,YAC9B,uBACA,WAAW,iBAAiB,QAC1B,WAAW,cAAc,SACxB,OAAO,MAAM,WAAW,UAAU,QAAQ,CAAC,KAAK,WAAW,aAAa,OACzE,YACA;CACR,OAAO;EACL,WAAW,WAAW;EACtB,IAAI,WAAW;EACf,QAAQ,WAAW;EACnB,SAAS,WAAW;EACpB,YAAY,WAAW;EACvB;CACF;AACF;;AAGA,SAAgB,iBAAiB,OASP;CACxB,MAAM,mBACJ,YAAY,MAAM,aACd,MAAM,WAAW,SACjB,MAAM,eAAe,KAAA,IACnB,OACA,QAAQ,MAAM,YAAY,MAAM,eAAe,MAAM,YAAY,MAAM,GAAG,CAAC,CAAC;CACpF,IACE,MAAM,WAAW,eAAe,MAAM,cACtC,MAAM,cAAc,eAAe,MAAM,cACzC,MAAM,cAAc,WAAW,SAAS,YACxC,MAAM,WAAW,iBAAiB,MAAM,WAAW,MACnD,qBAAqB,UAErB,MAAM,mBACJ,qDACA,6BACF;CAEF,IAAI,CAAC,MAAM,cAAc,qBAAqB,SAAS,MAAM,UAAU,GACrE,MAAM,mBACJ,oCAAoC,MAAM,WAAW,cACrD,6BACF;CAEF,IACE,CAAC,MAAM,cAAc,mBAAmB,MAAM,SAAS,KAAK,eAAe,MAAM,UAAU,GAE3F,MAAM,mBACJ,kDAAkD,MAAM,WAAW,cACnE,6BACF;CAEF,IAAI;CACJ,IAAI;EACF,SAASM,MAAiB,MAAM,MAAM;CACxC,SAAS,OAAO;EACd,IAAI,iBAAiBH,SAAmB,MAAM;EAC9C,MAAM,IAAIA,QAAkB,EAC1B,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAChE,CAAC;CACH;CACA,IAAI,MAAM,WAAW,WAAW,UAAU,CAAC,OAAO,SAAS,IAAI,MAAM,WAAW,QAAQ,GACtF,MAAM,mBACJ,yDACA,6BACF;CAEF,OAAO;AACT;;;;;;;;;;ACnMA,MAAa,WAAW,OAAO,OAAO;CACpC,OAAO,OAAO;CACd,SAAS,OAAO;AAClB,CAAC;;AAUD,SAAgB,MAAY,SAAiB,QAAsC;CACjF,OAAO;EACL,QAAQ,OAAO,GAAG,wBAAwB,CAAC,EAAE,aAC3C,SAAS,YAAY,UACjB,OAAO,KACL,IAAII,QAAkB,EACpB,SAAS,yCAAyC,SAAS,UAC7D,CAAC,CACH,IACA,OAAO,oBAAoB,MAAM,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,KACjD,OAAO,UAAU,UAAU,IAAIA,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACN;EACA,QAAQ,OAAO,GAAG,wBAAwB,CAAC,EAAE,UAC3C,OAAO,aAAa,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACjC,OAAO,SAAS,YAAY,OAAO,oBAAoB,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,GAC5E,OAAO,KAAK,aAAa;GAAE,OAAO;GAAS;EAAQ,EAAE,GACrD,OAAO,UAAU,UAAU,IAAIA,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;EACA;CACF;AACF;AAEA,MAAaC,WAAS,OAAO,GAAG,iCAAiC,CAAC,EAAE,UAClE,OAAO,oBAAoB,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAC1C,OAAO,UAAU,UAAU,IAAID,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAaE,WAAS,OAAO,WAAW,QAAQ;;;;;;;;;;;;;;;AC3ChD,MAAa,aAAaC,OAAE,SAAS,CAAC,YAAY,WAAW,CAAC;AAQ9D,MAAa,WAAW,KAAK,WAAqB;AAElD,MAAa,iBAAiBA,OAAE,YAAY;CAC1C,UAAU,CAAC;CACX,WAAW,EAAE,YAAYA,OAAE,eAAe;CAC1C,cAAc,EAAE,YAAYA,OAAE,eAAe;AAC/C,CAAC;AAED,MAAa,qBAAqBA,OAAE,OAAO;CACzC,YAAY;CACZ,UAAU;AACZ,CAAC;AAGD,MAAM,mBAAmBA,OAAE,YAAY;CACrC,QAAQ,CAAC;CACT,SAAS,EAAE,aAAaA,OAAE,eAAe;AAC3C,CAAC;;AAED,MAAa,aAAa;CACxB,QAAQ;CACR,cAAc,iBAAiB,MAAM,OAAO,KAAK,CAAC,CAAC;CACnD,UAAU,UACR,iBAAiB,MAAM,QAAQ,KAAK,KAAK;AAC7C;;AAIA,MAAaC,WAASD,OAAE,OAAO;CAC7B,gBAAgBA,OAAE;CAClB,oBAAoBA,OAAE,MAAM,kBAAkB;CAC9C,WAAWA,OAAE;CACb,IAAIA,OAAE;CACN,QAAQA,OAAE,SAAS;EAAC;EAAe;EAAU;CAAO,CAAC;CACrD,iBAAiBE;CACjB,YAAYF,OAAE;CACd,sBAAsBA,OAAE,MAAM,UAAU;CACxC,YAAY,WAAW;CACvB,QAAQA,OAAE,MAAMA,OAAE,MAAM;AAC1B,CAAC;AAGD,MAAa,SAAS,OAAO,GAAG,8BAA8B,CAAC,EAAE,UAC/DA,OAAE,oBAAoBC,QAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACnC,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAa,WAAW,OAAO,GAAG,gCAAgC,CAAC,EAAE,UACnEH,OAAE,oBAAoBA,OAAE,OAAOC,QAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAC7C,OAAO,UAAU,UAAU,IAAIE,QAAkB,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAC9E,CACF;AAEA,MAAa,SAASH,OAAE,WAAWC,QAAM;AAEzC,SAAgB,YACd,eACA,YACsB;CACtB,OAAO,cAAc,mBAAmB,MAAM,SAAS,KAAK,eAAe,UAAU,CAAC,EAAE;AAC1F;;;;AC5DA,MAAa,kBAAkB,OAAO,OAAO;CAC3C,eAAeG;CACf,aAAa,OAAO,MAAMC,gBAA2B;CACrD,aAAa,OAAO,MAAMC,gBAA2B;AACvD,CAAC;AA6BD,IAAaC,UAAb,cAA2B,OAAO,YAAmB,CAAC,CAAC,4BAA4B;CACjF,UAAU,OAAO,QAAQ,SAAS;CAClC,SAAS,OAAO;CAChB,WAAW,OAAO;CAClB,OAAO,OAAO,SAAS;EAAC;EAAS;EAAqB;EAAQ;CAAS,CAAC;AAC1E,CAAC,CAAC,CAAC,CAAC;AAyDJ,IAAa,UAAb,cAA6B,QAAQ,QAA4B,CAAC,CAChE,kCACF,CAAC,CAAC,CAAC;;;;;;;;;;;AC7GH,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"}