@domainkit/capsuledb 0.0.0-tegami-trusted-publish-setup → 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arya Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction,
7
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
18
+ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,6 +1,11 @@
1
- # Placeholder package
2
-
3
- This empty package was published by [Tegami](https://tegami.fuma-nama.dev) to configure npm trusted publishing.
4
-
5
- The real package contents will be published via CI with OIDC.
6
-
1
+ # `@domainkit/capsuledb`
2
+
3
+ Optional PostgreSQL persistence for DomainKit's Effect-first managed-DNS authorization lifecycle.
4
+
5
+ The host owns and supplies the exact `SqlClient`, credential encryption, identity and tenant
6
+ policy, stable owner/domain bindings, audit, routes, and consent. The package exposes only semantic
7
+ Effect services. It does not export tables, rows, queries, an ORM adapter, or a Promise-first API.
8
+
9
+ This package is the published PostgreSQL persistence implementation for DomainKit. Its development
10
+ dependency pins the reviewed CapsuleDB Git SHA; that pin is excluded from the packed runtime
11
+ dependency graph.
@@ -0,0 +1,60 @@
1
+ import { Context, Effect, Schema } from "effect";
2
+ import { ManagedDnsConnections } from "domainkit";
3
+ import * as SqlClient from "effect/unstable/sql/SqlClient";
4
+ declare namespace custody_d_exports {
5
+ export { Credential, Error$1 as Error, Interface$1 as Interface, Service$1 as Service };
6
+ }
7
+ /** Secret token material; credential expiry remains ordinary lifecycle metadata. */
8
+ type Credential = Omit<ManagedDnsConnections.StoredCredential, "expiresAt">;
9
+ declare const Error_base$1: Schema.Class<Error$1, Schema.TaggedStruct<"CredentialCustodyError", {
10
+ readonly message: Schema.String;
11
+ readonly operation: Schema.String;
12
+ readonly retry: Schema.Literals<readonly ["never", "after-user-action", "safe", "unknown"]>;
13
+ }>, import("effect/Cause").YieldableError>;
14
+ declare class Error$1 extends Error_base$1 {}
15
+ interface Interface$1 {
16
+ readonly open: (ciphertext: string) => Effect.Effect<Credential, Error$1>;
17
+ readonly seal: (credential: Credential) => Effect.Effect<string, Error$1>;
18
+ }
19
+ declare const Service_base$1: Context.ServiceClass<Service$1, "@domainkit/capsuledb/CredentialCustody", Interface$1>;
20
+ /** Host-owned encryption boundary. DomainKit never receives keys or stores plaintext. */
21
+ declare class Service$1 extends Service_base$1 {}
22
+ declare namespace host_bindings_d_exports {
23
+ export { DomainReference, Error, Interface, OwnerReference, Service };
24
+ }
25
+ declare const Error_base: Schema.Class<Error, Schema.TaggedStruct<"HostBindingError", {
26
+ readonly message: Schema.String;
27
+ readonly operation: Schema.String;
28
+ readonly retry: Schema.Literals<readonly ["never", "after-user-action", "safe", "unknown"]>;
29
+ }>, import("effect/Cause").YieldableError>;
30
+ declare class Error extends Error_base {}
31
+ interface OwnerReference {
32
+ readonly ownerReference: string;
33
+ }
34
+ interface DomainReference extends OwnerReference {
35
+ readonly domainReference: string;
36
+ }
37
+ interface Interface {
38
+ /** Resolve a durable host owner reference without capturing request identity. */
39
+ readonly owner: (ownerId: string) => Effect.Effect<OwnerReference, Error>;
40
+ /** Resolve a host domain reference inside the caller's active transaction context. */
41
+ readonly domain: (input: {
42
+ readonly domain: string;
43
+ readonly ownerId: string;
44
+ }) => Effect.Effect<DomainReference, Error>;
45
+ /** Project an opaque stored owner reference back to DomainKit's semantic owner id. */
46
+ readonly ownerId: (ownerReference: string) => Effect.Effect<string, Error>;
47
+ }
48
+ declare const Service_base: Context.ServiceClass<Service, "@domainkit/capsuledb/HostBindings", Interface>;
49
+ /** Stateless host mapping for tenant/domain foreign-key references. */
50
+ declare class Service extends Service_base {}
51
+ //#endregion
52
+ //#region src/persistence.d.ts
53
+ /** PostgreSQL-only authorization lifecycle capsule. The host must prepare its registry at startup. */
54
+ declare const capsule: Effect.Effect<import("capsuledb").Capsule<ManagedDnsConnections.Service, never, Service$1 | Service | SqlClient.SqlClient>, import("capsuledb").InvalidDefinition | import("capsuledb").CapsuleDefinitionError, never>;
55
+ //#endregion
56
+ //#region src/index.d.ts
57
+ declare const VERSION: string;
58
+ //#endregion
59
+ export { custody_d_exports as CredentialCustody, host_bindings_d_exports as HostBindings, VERSION, capsule };
60
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,493 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { Context, Effect, Layer, Schema } from "effect";
3
+ import { makeCapsule, makeMigration, sqlMigrationBody } from "capsuledb";
4
+ import { Connection, ManagedDnsConnections } from "domainkit";
5
+ import * as SqlClient from "effect/unstable/sql/SqlClient";
6
+ import * as SqlError from "effect/unstable/sql/SqlError";
7
+ //#region package.json
8
+ var version = "0.1.1";
9
+ //#endregion
10
+ //#region src/custody.ts
11
+ var custody_exports = /* @__PURE__ */ __exportAll({
12
+ Error: () => Error$2,
13
+ Service: () => Service$1
14
+ });
15
+ var Error$2 = class extends Schema.TaggedError()("CredentialCustodyError", {
16
+ message: Schema.String,
17
+ operation: Schema.String,
18
+ retry: Schema.Literals([
19
+ "never",
20
+ "after-user-action",
21
+ "safe",
22
+ "unknown"
23
+ ])
24
+ }) {};
25
+ /** Host-owned encryption boundary. DomainKit never receives keys or stores plaintext. */
26
+ var Service$1 = class extends Context.Service()("@domainkit/capsuledb/CredentialCustody") {};
27
+ //#endregion
28
+ //#region src/host-bindings.ts
29
+ var host_bindings_exports = /* @__PURE__ */ __exportAll({
30
+ Error: () => Error$1,
31
+ Service: () => Service
32
+ });
33
+ var Error$1 = class extends Schema.TaggedError()("HostBindingError", {
34
+ message: Schema.String,
35
+ operation: Schema.String,
36
+ retry: Schema.Literals([
37
+ "never",
38
+ "after-user-action",
39
+ "safe",
40
+ "unknown"
41
+ ])
42
+ }) {};
43
+ /** Stateless host mapping for tenant/domain foreign-key references. */
44
+ var Service = class extends Context.Service()("@domainkit/capsuledb/HostBindings") {};
45
+ //#endregion
46
+ //#region src/persistence.ts
47
+ const AttachmentContext = Schema.Struct({
48
+ version: Schema.Literal("domainkit.attachment.v1"),
49
+ value: Schema.Struct({
50
+ accountKind: Schema.NullOr(Schema.Literals([
51
+ "account",
52
+ "personal",
53
+ "team"
54
+ ])),
55
+ domain: Schema.String,
56
+ evidence: Schema.optionalKey(Connection.ProviderTargetEvidence)
57
+ })
58
+ });
59
+ const storageError = (operation, message, retry = "unknown") => new ManagedDnsConnections.Error({
60
+ category: "storage",
61
+ message,
62
+ operation,
63
+ retry
64
+ });
65
+ const missing = (operation, message) => storageError(operation, message, "never");
66
+ const conflict = (operation, message) => storageError(operation, message, "after-user-action");
67
+ const sqlErrorMessage = (error) => error.reason.cause instanceof Error ? `${error.reason._tag}: ${error.reason.cause.message}` : `${error.reason._tag}: ${error.reason.message ?? String(error.reason.cause)}`;
68
+ const mapCapabilityError = (operation, error) => storageError(operation, error.message, error.retry);
69
+ const mapSql = (operation, effect) => Effect.matchEffect(effect, {
70
+ onFailure: (error) => {
71
+ const mapped = SqlError.isSqlError(error) ? storageError(operation, sqlErrorMessage(error), "unknown") : error;
72
+ return Effect.fail(mapped);
73
+ },
74
+ onSuccess: Effect.succeed
75
+ });
76
+ const sameAttachment = (left, right) => left.connectionId === right.connectionId && left.domain === right.domain && left.target.accountId === right.target.accountId && left.target.accountKind === right.target.accountKind && left.target.zoneId === right.target.zoneId && left.target.zoneName === right.target.zoneName;
77
+ const decodeAuthorization = Effect.fn("CapsuleManagedDnsConnections.decodeAuthorization")(function* (row) {
78
+ if (row.credential_ciphertext === null) return yield* Effect.fail(missing("decodeAuthorization", `Authorization ${row.id} has no credential ciphertext`));
79
+ return {
80
+ authorization: yield* Schema.decodeUnknownEffect(ManagedDnsConnections.Authorization.Schema)({
81
+ authorizedById: row.subject_id,
82
+ capabilityEvidence: row.capability_evidence,
83
+ createdAt: row.created_at.toISOString(),
84
+ id: row.id,
85
+ method: row.kind,
86
+ providerContext: row.provider_context,
87
+ providerId: row.provider_id,
88
+ requiredCapabilities: row.capabilities,
89
+ revocation: row.revocation,
90
+ scopes: row.scopes
91
+ }).pipe(Effect.mapError((error) => missing("decodeAuthorization", `Authorization ${row.id} is invalid: ${error.message}`))),
92
+ credentialCiphertext: row.credential_ciphertext,
93
+ credentialExpiresAt: row.expires_at
94
+ };
95
+ });
96
+ const decodeAttachment = Effect.fn("CapsuleManagedDnsConnections.decodeAttachment")(function* (row) {
97
+ const context = yield* Schema.decodeUnknownEffect(AttachmentContext)(row.provider_target_context).pipe(Effect.mapError((error) => missing("decodeAttachment", `Attachment ${row.id} context is invalid: ${error.message}`)));
98
+ return yield* Schema.decodeUnknownEffect(Connection.DomainAttachment)({
99
+ connectionId: row.connection_id,
100
+ createdAt: row.created_at.toISOString(),
101
+ domain: context.value.domain,
102
+ id: row.id,
103
+ target: {
104
+ accountId: row.provider_account_id,
105
+ accountKind: context.value.accountKind,
106
+ ...context.value.evidence === void 0 ? {} : { evidence: context.value.evidence },
107
+ zoneId: row.provider_zone_id,
108
+ zoneName: row.provider_zone_name
109
+ }
110
+ }).pipe(Effect.mapError((error) => missing("decodeAttachment", `Attachment ${row.id} is invalid: ${error.message}`)));
111
+ });
112
+ const encodeAuthorization = Effect.fn("CapsuleManagedDnsConnections.encodeAuthorization")(function* (authorization) {
113
+ return yield* Schema.encodeUnknownEffect(ManagedDnsConnections.Authorization.Schema)(authorization).pipe(Effect.mapError((error) => conflict("encodeAuthorization", `Authorization cannot be encoded: ${error.message}`)));
114
+ });
115
+ const loadAggregate = Effect.fn("CapsuleManagedDnsConnections.loadAggregate")(function* (sql, bindings, authorizationId, lock = "share") {
116
+ const lockClause = lock === "update" ? "FOR UPDATE" : "FOR SHARE";
117
+ const row = (yield* sql.unsafe(`SELECT id, provider_id, subject_id, kind, capabilities, capability_evidence, scopes,
118
+ provider_context, revocation, credential_ciphertext, expires_at, created_at
119
+ FROM domain_provider_authorizations WHERE id = $1 ${lockClause}`, [authorizationId]))[0];
120
+ if (row === void 0) return null;
121
+ const decoded = yield* decodeAuthorization(row);
122
+ const connectionRows = yield* sql`SELECT id, organization_id, authorization_id,
123
+ created_at FROM organization_domain_provider_connections
124
+ WHERE authorization_id = ${authorizationId} ORDER BY id`;
125
+ const connections = yield* Effect.forEach(connectionRows, (connection) => bindings.ownerId(connection.organization_id).pipe(Effect.mapError((error) => mapCapabilityError("loadAggregate", error)), Effect.map((ownerId) => ({
126
+ authorizationId: connection.authorization_id,
127
+ createdAt: connection.created_at,
128
+ id: connection.id,
129
+ method: decoded.authorization.method,
130
+ ownerId,
131
+ providerId: decoded.authorization.providerId
132
+ }))));
133
+ const attachmentRows = yield* sql`SELECT a.id, a.connection_id,
134
+ a.provider_account_id, a.provider_zone_id, a.provider_zone_name,
135
+ a.provider_target_context, a.created_at
136
+ FROM domain_provider_attachments a
137
+ JOIN organization_domain_provider_connections c ON c.id = a.connection_id
138
+ WHERE c.authorization_id = ${authorizationId} ORDER BY a.id`;
139
+ return {
140
+ attachments: yield* Effect.forEach(attachmentRows, decodeAttachment),
141
+ authorization: decoded.authorization,
142
+ connections,
143
+ credentialCiphertext: decoded.credentialCiphertext,
144
+ credentialExpiresAt: decoded.credentialExpiresAt
145
+ };
146
+ });
147
+ const authorizationIdForConnection = Effect.fn("CapsuleManagedDnsConnections.authorizationIdForConnection")(function* (sql, connectionId) {
148
+ return (yield* sql`SELECT authorization_id
149
+ FROM organization_domain_provider_connections WHERE id = ${connectionId}`)[0]?.authorization_id ?? null;
150
+ });
151
+ const authorizationIdForAttachment = Effect.fn("CapsuleManagedDnsConnections.authorizationIdForAttachment")(function* (sql, attachmentId) {
152
+ return (yield* sql`SELECT c.authorization_id
153
+ FROM domain_provider_attachments a
154
+ JOIN organization_domain_provider_connections c ON c.id = a.connection_id
155
+ WHERE a.id = ${attachmentId}`)[0]?.authorization_id ?? null;
156
+ });
157
+ const openAggregate = Effect.fn("CapsuleManagedDnsConnections.openAggregate")(function* (custody, aggregate) {
158
+ const credential = {
159
+ ...yield* custody.open(aggregate.credentialCiphertext).pipe(Effect.mapError((error) => mapCapabilityError("openCredential", error))),
160
+ expiresAt: aggregate.credentialExpiresAt
161
+ };
162
+ return {
163
+ attachments: aggregate.attachments,
164
+ authorization: aggregate.authorization,
165
+ connections: aggregate.connections,
166
+ credential
167
+ };
168
+ });
169
+ const projectConnection = Effect.fn("CapsuleManagedDnsConnections.projectConnection")(function* (custody, aggregate, connection, authorization = aggregate.authorization) {
170
+ const opened = yield* openAggregate(custody, aggregate);
171
+ return Connection.project(connection, authorization, opened.credential);
172
+ });
173
+ const writeAuthorization = Effect.fn("CapsuleManagedDnsConnections.writeAuthorization")(function* (sql, authorization, credentialCiphertext, credentialExpiresAt) {
174
+ const encoded = yield* encodeAuthorization(authorization);
175
+ yield* sql`INSERT INTO domain_provider_authorizations (
176
+ id, provider_id, account_id, subject_id, kind, capabilities, capability_evidence, scopes,
177
+ provider_context, revocation, credential_ciphertext, expires_at, created_at, updated_at
178
+ ) VALUES (
179
+ ${authorization.id}, ${authorization.providerId}, NULL, ${authorization.authorizedById},
180
+ ${authorization.method}, ${JSON.stringify(encoded.requiredCapabilities)}::jsonb,
181
+ ${JSON.stringify(encoded.capabilityEvidence)}::jsonb,
182
+ ${JSON.stringify(encoded.scopes)}::jsonb, ${JSON.stringify(encoded.providerContext)}::jsonb,
183
+ ${JSON.stringify(encoded.revocation)}::jsonb,
184
+ ${credentialCiphertext}, ${credentialExpiresAt}, ${authorization.createdAt}, NOW()
185
+ ) ON CONFLICT (id) DO UPDATE SET
186
+ provider_id = EXCLUDED.provider_id,
187
+ subject_id = EXCLUDED.subject_id,
188
+ kind = EXCLUDED.kind,
189
+ capabilities = EXCLUDED.capabilities,
190
+ capability_evidence = EXCLUDED.capability_evidence,
191
+ scopes = EXCLUDED.scopes,
192
+ provider_context = EXCLUDED.provider_context,
193
+ revocation = EXCLUDED.revocation,
194
+ credential_ciphertext = EXCLUDED.credential_ciphertext,
195
+ expires_at = EXCLUDED.expires_at,
196
+ updated_at = NOW()`;
197
+ });
198
+ const makeRepository = Effect.gen(function* () {
199
+ const sql = yield* SqlClient.SqlClient;
200
+ const custody = yield* Service$1;
201
+ const bindings = yield* Service;
202
+ const withRevocationLock = (operation, authorizationId, effect) => sql.withTransaction(Effect.gen(function* () {
203
+ if ((yield* sql`
204
+ SELECT pg_try_advisory_xact_lock(hashtextextended(${authorizationId}, 0)) AS acquired`)[0]?.acquired !== true) return yield* Effect.fail(storageError(operation, "Provider revocation is already in progress", "safe"));
205
+ return yield* effect;
206
+ }));
207
+ const getStored = (authorizationId, lock = "share") => loadAggregate(sql, bindings, authorizationId, lock);
208
+ const get = (authorizationId) => mapSql("get", sql.withTransaction(getStored(authorizationId)).pipe(Effect.flatMap((aggregate) => aggregate === null ? Effect.succeed(null) : openAggregate(custody, aggregate))));
209
+ const getByConnectionId = (connectionId) => mapSql("getByConnectionId", sql.withTransaction(Effect.gen(function* () {
210
+ const authorizationId = yield* authorizationIdForConnection(sql, connectionId);
211
+ if (authorizationId === null) return null;
212
+ const aggregate = yield* getStored(authorizationId);
213
+ if (aggregate === null || !aggregate.connections.some((connection) => connection.id === connectionId)) return null;
214
+ return aggregate;
215
+ })).pipe(Effect.flatMap((aggregate) => aggregate === null ? Effect.succeed(null) : openAggregate(custody, aggregate))));
216
+ return ManagedDnsConnections.Service.of({
217
+ attach: (input) => mapSql("attach", sql.withTransaction(Effect.gen(function* () {
218
+ const authorizationId = yield* authorizationIdForConnection(sql, input.connectionId);
219
+ if (authorizationId === null) return yield* Effect.fail(missing("attach", "Provider connection does not exist"));
220
+ const aggregate = yield* getStored(authorizationId, "update");
221
+ if (aggregate === null) return yield* Effect.fail(missing("attach", "Provider authorization does not exist"));
222
+ const connection = aggregate.connections.find((candidate) => candidate.id === input.connectionId && candidate.ownerId === input.ownerId);
223
+ if (connection === void 0) return yield* Effect.fail(missing("attach", "Provider connection does not belong to this owner"));
224
+ if (aggregate.authorization.revocation._tag === "Pending") return yield* Effect.fail(conflict("attach", "Provider authorization is awaiting revocation recovery"));
225
+ if (input.attachment.connectionId !== input.connectionId) return yield* Effect.fail(conflict("attach", "Domain attachment targets another connection"));
226
+ const existing = aggregate.attachments.find(({ id }) => id === input.attachment.id);
227
+ if (existing !== void 0) {
228
+ if (!sameAttachment(existing, input.attachment)) return yield* Effect.fail(conflict("attach", "Domain attachment id is already in use"));
229
+ return {
230
+ attachment: existing,
231
+ connection: yield* projectConnection(custody, aggregate, connection)
232
+ };
233
+ }
234
+ const reference = yield* bindings.domain({
235
+ domain: input.attachment.domain,
236
+ ownerId: input.ownerId
237
+ }).pipe(Effect.mapError((error) => mapCapabilityError("attach", error)));
238
+ const context = {
239
+ version: "domainkit.attachment.v1",
240
+ value: {
241
+ accountKind: input.attachment.target.accountKind,
242
+ domain: input.attachment.domain,
243
+ ...input.attachment.target.evidence === void 0 ? {} : { evidence: input.attachment.target.evidence }
244
+ }
245
+ };
246
+ yield* sql`INSERT INTO domain_provider_attachments (
247
+ id, organization_id, connection_id, domain_id, provider_account_id,
248
+ provider_zone_id, provider_zone_name, provider_target_context, created_at, updated_at
249
+ ) VALUES (
250
+ ${input.attachment.id}, ${reference.ownerReference}, ${input.connectionId},
251
+ ${reference.domainReference}, ${input.attachment.target.accountId},
252
+ ${input.attachment.target.zoneId}, ${input.attachment.target.zoneName},
253
+ ${JSON.stringify(context)}::jsonb,
254
+ ${input.attachment.createdAt}, NOW()
255
+ )`;
256
+ return {
257
+ attachment: input.attachment,
258
+ connection: yield* projectConnection(custody, aggregate, connection)
259
+ };
260
+ }))),
261
+ connect: (input) => custody.seal(input.credential).pipe(Effect.mapError((error) => mapCapabilityError("connect", error)), Effect.flatMap((credentialCiphertext) => mapSql("connect", sql.withTransaction(Effect.gen(function* () {
262
+ yield* sql`SELECT pg_advisory_xact_lock(hashtextextended(${input.authorization.id}, 0))`;
263
+ const current = yield* getStored(input.authorization.id, "update");
264
+ if (current?.authorization.revocation._tag === "Pending" || input.expectedAuthorizationId !== void 0 && current === null) return yield* Effect.fail(conflict("connect", current === null ? "Provider authorization no longer exists" : "Provider authorization is awaiting revocation recovery"));
265
+ if (input.authorization.id !== input.connection.authorizationId || input.authorization.providerId !== input.connection.providerId || input.authorization.method !== input.connection.method) return yield* Effect.fail(conflict("connect", "Connection does not match its authorization"));
266
+ const existingConnection = current?.connections.find(({ ownerId }) => ownerId === input.connection.ownerId);
267
+ if (input.expectedConnectionId !== void 0 && existingConnection?.id !== input.expectedConnectionId) return yield* Effect.fail(conflict("connect", "Organization connection changed during reconnect"));
268
+ yield* writeAuthorization(sql, input.authorization, credentialCiphertext, input.credential.expiresAt);
269
+ if (existingConnection === void 0) {
270
+ const reference = yield* bindings.owner(input.connection.ownerId).pipe(Effect.mapError((error) => mapCapabilityError("connect", error)));
271
+ yield* sql`INSERT INTO organization_domain_provider_connections (
272
+ id, organization_id, authorization_id, created_at, updated_at
273
+ ) VALUES (
274
+ ${input.connection.id}, ${reference.ownerReference},
275
+ ${input.authorization.id}, ${input.connection.createdAt}, NOW()
276
+ )`;
277
+ }
278
+ return (yield* getStored(input.authorization.id, "update")) ?? (yield* Effect.fail(missing("connect", "Authorization write vanished")));
279
+ })))), Effect.flatMap((aggregate) => openAggregate(custody, aggregate))),
280
+ detach: ({ attachmentId, ownerId }) => mapSql("detach", sql.withTransaction(Effect.gen(function* () {
281
+ const authorizationId = yield* authorizationIdForAttachment(sql, attachmentId);
282
+ if (authorizationId === null) return yield* Effect.fail(missing("detach", "Domain attachment does not exist"));
283
+ const aggregate = yield* getStored(authorizationId, "update");
284
+ const attachment = aggregate?.attachments.find(({ id }) => id === attachmentId);
285
+ if (aggregate === null || attachment === void 0) return yield* Effect.fail(missing("detach", "Domain attachment does not exist"));
286
+ const connection = aggregate.connections.find(({ id, ownerId: candidate }) => id === attachment.connectionId && candidate === ownerId);
287
+ if (connection === void 0) return yield* Effect.fail(missing("detach", "Domain attachment does not belong to this owner"));
288
+ yield* sql`DELETE FROM domain_provider_attachments WHERE id = ${attachmentId}`;
289
+ return {
290
+ attachment,
291
+ connection: yield* projectConnection(custody, aggregate, connection),
292
+ remainingAttachments: aggregate.attachments.filter(({ connectionId, id }) => connectionId === connection.id && id !== attachmentId).length
293
+ };
294
+ }))),
295
+ disconnect: ({ connectionId, ownerId, revoke }) => mapSql("disconnect", sql.withTransaction(Effect.gen(function* () {
296
+ const authorizationId = yield* authorizationIdForConnection(sql, connectionId);
297
+ if (authorizationId === null) return yield* Effect.fail(missing("disconnect", "Provider connection does not exist"));
298
+ const aggregate = yield* getStored(authorizationId, "update");
299
+ const connection = aggregate?.connections.find(({ id, ownerId: candidate }) => id === connectionId && candidate === ownerId);
300
+ if (aggregate === null || connection === void 0) return yield* Effect.fail(missing("disconnect", "Provider connection does not belong to this owner"));
301
+ if (aggregate.attachments.some(({ connectionId: id }) => id === connectionId)) return yield* Effect.fail(conflict("disconnect", "Detach all organization domains before disconnecting the provider"));
302
+ if (aggregate.connections.length > 1) {
303
+ yield* sql`DELETE FROM organization_domain_provider_connections
304
+ WHERE id = ${connectionId}`;
305
+ return {
306
+ _tag: "Disconnected",
307
+ connection: yield* projectConnection(custody, aggregate, connection),
308
+ remainingConnections: aggregate.connections.length - 1
309
+ };
310
+ }
311
+ if (aggregate.authorization.revocation._tag === "Pending") return yield* Effect.fail(conflict("disconnect", "Provider authorization is awaiting revocation recovery"));
312
+ const pending = {
313
+ ...aggregate.authorization,
314
+ revocation: {
315
+ _tag: "Pending",
316
+ requestedAt: /* @__PURE__ */ new Date()
317
+ }
318
+ };
319
+ yield* writeAuthorization(sql, pending, aggregate.credentialCiphertext, aggregate.credentialExpiresAt);
320
+ return {
321
+ _tag: "Prepared",
322
+ authorization: pending,
323
+ connection: yield* projectConnection(custody, aggregate, connection, pending)
324
+ };
325
+ })).pipe(Effect.flatMap((prepared) => {
326
+ if (prepared._tag === "Disconnected") {
327
+ const result = {
328
+ connection: prepared.connection,
329
+ remainingConnections: prepared.remainingConnections,
330
+ revokedAuthorization: false
331
+ };
332
+ return Effect.succeed(result);
333
+ }
334
+ const result = {
335
+ connection: prepared.connection,
336
+ remainingConnections: 0,
337
+ revokedAuthorization: true
338
+ };
339
+ return withRevocationLock("disconnect", prepared.authorization.id, getStored(prepared.authorization.id, "update").pipe(Effect.flatMap((current) => {
340
+ if (current?.authorization.revocation._tag !== "Pending") return Effect.fail(conflict("disconnect", "Revocation state changed before provider call"));
341
+ return revoke(current.authorization).pipe(Effect.andThen(Effect.gen(function* () {
342
+ if ((yield* getStored(prepared.authorization.id, "update"))?.authorization.revocation._tag !== "Pending") return yield* Effect.fail(conflict("disconnect", "Revocation state changed before completion"));
343
+ yield* sql`DELETE FROM domain_provider_attachments WHERE connection_id IN
344
+ (SELECT id FROM organization_domain_provider_connections
345
+ WHERE authorization_id = ${prepared.authorization.id})`;
346
+ yield* sql`DELETE FROM organization_domain_provider_connections
347
+ WHERE authorization_id = ${prepared.authorization.id}`;
348
+ yield* sql`DELETE FROM domain_provider_authorizations
349
+ WHERE id = ${prepared.authorization.id}`;
350
+ })), Effect.as(result));
351
+ })));
352
+ }))),
353
+ findConnection: (ownerId, authorizationId) => get(authorizationId).pipe(Effect.map((aggregate) => aggregate?.connections.find((connection) => connection.ownerId === ownerId) ?? null)),
354
+ get,
355
+ getAttachment: (attachmentId) => mapSql("getAttachment", sql.withTransaction(Effect.gen(function* () {
356
+ const authorizationId = yield* authorizationIdForAttachment(sql, attachmentId);
357
+ if (authorizationId === null) return null;
358
+ return (yield* getStored(authorizationId))?.attachments.find(({ id }) => id === attachmentId) ?? null;
359
+ }))),
360
+ getByConnectionId,
361
+ listAttachments: (connectionId, ownerId) => getByConnectionId(connectionId).pipe(Effect.flatMap((aggregate) => {
362
+ if (aggregate === null) return Effect.fail(missing("listAttachments", "Provider connection does not exist"));
363
+ if (!aggregate.connections.some((connection) => connection.id === connectionId && connection.ownerId === ownerId)) return Effect.fail(missing("listAttachments", "Provider connection does not belong to this owner"));
364
+ return Effect.succeed(aggregate.attachments.filter((attachment) => attachment.connectionId === connectionId));
365
+ })),
366
+ promoteEvidence: (authorizationId, evidence) => mapSql("promoteEvidence", sql.withTransaction(Effect.gen(function* () {
367
+ const aggregate = yield* getStored(authorizationId, "update");
368
+ if (aggregate === null) return yield* Effect.fail(missing("promoteEvidence", "Provider authorization does not exist"));
369
+ const byCapability = new Map(aggregate.authorization.capabilityEvidence.map((item) => [item.capability, item]));
370
+ for (const item of evidence) byCapability.set(item.capability, item);
371
+ yield* writeAuthorization(sql, {
372
+ ...aggregate.authorization,
373
+ capabilityEvidence: [...byCapability.values()]
374
+ }, aggregate.credentialCiphertext, aggregate.credentialExpiresAt);
375
+ return (yield* getStored(authorizationId, "update")) ?? (yield* Effect.fail(missing("promoteEvidence", "Authorization write vanished")));
376
+ }))).pipe(Effect.flatMap((aggregate) => openAggregate(custody, aggregate))),
377
+ recover: ({ authorizationId, revoke }) => mapSql("recover", withRevocationLock("recover", authorizationId, getStored(authorizationId, "update").pipe(Effect.flatMap((aggregate) => Effect.gen(function* () {
378
+ if (aggregate === null) return yield* Effect.fail(missing("recover", "Provider authorization does not exist"));
379
+ if (aggregate.authorization.revocation._tag !== "Pending") return yield* Effect.fail(missing("recover", "Provider authorization is not awaiting revocation"));
380
+ const connection = aggregate.connections[0];
381
+ if (connection === void 0) return yield* Effect.fail(missing("recover", "Pending authorization has no connection"));
382
+ const projected = yield* projectConnection(custody, aggregate, connection);
383
+ return yield* revoke(aggregate.authorization).pipe(Effect.andThen(Effect.gen(function* () {
384
+ if ((yield* getStored(authorizationId, "update"))?.authorization.revocation._tag !== "Pending") return yield* Effect.fail(conflict("recover", "Revocation state changed before completion"));
385
+ yield* sql`DELETE FROM domain_provider_attachments WHERE connection_id IN
386
+ (SELECT id FROM organization_domain_provider_connections
387
+ WHERE authorization_id = ${authorizationId})`;
388
+ yield* sql`DELETE FROM organization_domain_provider_connections
389
+ WHERE authorization_id = ${authorizationId}`;
390
+ yield* sql`DELETE FROM domain_provider_authorizations WHERE id = ${authorizationId}`;
391
+ })), Effect.as({
392
+ connection: projected,
393
+ remainingConnections: 0,
394
+ revokedAuthorization: true
395
+ }));
396
+ }))))),
397
+ rotate: (authorizationId, credential) => custody.seal(credential).pipe(Effect.mapError((error) => mapCapabilityError("rotate", error)), Effect.flatMap((credentialCiphertext) => mapSql("rotate", sql.withTransaction(Effect.gen(function* () {
398
+ const aggregate = yield* getStored(authorizationId, "update");
399
+ if (aggregate === null) return yield* Effect.fail(missing("rotate", "Provider authorization does not exist"));
400
+ yield* writeAuthorization(sql, aggregate.authorization, credentialCiphertext, credential.expiresAt);
401
+ return (yield* getStored(authorizationId, "update")) ?? (yield* Effect.fail(missing("rotate", "Authorization write vanished")));
402
+ })))), Effect.flatMap((aggregate) => openAggregate(custody, aggregate)))
403
+ });
404
+ });
405
+ const migration = makeMigration({
406
+ id: 1,
407
+ name: "adopt-authorization-lifecycle",
408
+ risk: "additive",
409
+ providers: { Postgres: sqlMigrationBody([
410
+ `CREATE TABLE IF NOT EXISTS domain_provider_authorizations (
411
+ id TEXT PRIMARY KEY NOT NULL,
412
+ provider_id TEXT NOT NULL,
413
+ account_id TEXT,
414
+ subject_id TEXT NOT NULL,
415
+ kind TEXT NOT NULL,
416
+ capabilities JSONB NOT NULL,
417
+ capability_evidence JSONB NOT NULL,
418
+ scopes JSONB NOT NULL,
419
+ provider_context JSONB NOT NULL,
420
+ revocation JSONB NOT NULL,
421
+ credential_ciphertext TEXT,
422
+ expires_at TIMESTAMPTZ,
423
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
424
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
425
+ )`,
426
+ `ALTER TABLE domain_provider_authorizations
427
+ DROP CONSTRAINT IF EXISTS uq_domain_provider_authorizations_provider_account`,
428
+ `ALTER TABLE domain_provider_authorizations ALTER COLUMN account_id DROP NOT NULL`,
429
+ `CREATE TABLE IF NOT EXISTS organization_domain_provider_connections (
430
+ id TEXT PRIMARY KEY NOT NULL,
431
+ organization_id TEXT NOT NULL,
432
+ authorization_id TEXT NOT NULL,
433
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
434
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
435
+ CONSTRAINT uq_organization_domain_provider_connections_org_authorization
436
+ UNIQUE (organization_id, authorization_id),
437
+ CONSTRAINT uq_organization_domain_provider_connections_id_org
438
+ UNIQUE (id, organization_id)
439
+ )`,
440
+ `CREATE INDEX IF NOT EXISTS idx_organization_domain_provider_connections_authorization
441
+ ON organization_domain_provider_connections (authorization_id)`,
442
+ `DO $$ BEGIN
443
+ IF to_regclass('domain_connections') IS NOT NULL THEN
444
+ INSERT INTO organization_domain_provider_connections (
445
+ id, organization_id, authorization_id, created_at, updated_at
446
+ ) SELECT id, organization_id, authorization_id, created_at, updated_at
447
+ FROM domain_connections ON CONFLICT DO NOTHING;
448
+ END IF;
449
+ END $$`,
450
+ `CREATE TABLE IF NOT EXISTS domain_provider_attachments (
451
+ id TEXT PRIMARY KEY NOT NULL,
452
+ organization_id TEXT NOT NULL,
453
+ connection_id TEXT NOT NULL,
454
+ domain_id TEXT NOT NULL,
455
+ provider_account_id TEXT NOT NULL,
456
+ provider_zone_id TEXT NOT NULL,
457
+ provider_zone_name TEXT NOT NULL,
458
+ provider_target_context JSONB NOT NULL,
459
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
460
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
461
+ CONSTRAINT uq_domain_provider_attachments_org_domain UNIQUE (organization_id, domain_id),
462
+ CONSTRAINT uq_domain_provider_attachments_connection_domain UNIQUE (connection_id, domain_id)
463
+ )`,
464
+ `CREATE INDEX IF NOT EXISTS idx_domain_provider_attachments_connection
465
+ ON domain_provider_attachments (connection_id)`,
466
+ `DO $$ BEGIN
467
+ IF EXISTS (SELECT 1 FROM domain_provider_authorizations WHERE credential_ciphertext IS NULL)
468
+ THEN RAISE EXCEPTION 'DomainKit adoption requires encrypted credential ciphertext';
469
+ END IF;
470
+ IF EXISTS (
471
+ SELECT 1 FROM domain_provider_attachments
472
+ WHERE provider_target_context #>> '{value,domain}' IS NULL
473
+ ) THEN RAISE EXCEPTION 'DomainKit adoption requires semantic attachment domains';
474
+ END IF;
475
+ END $$`
476
+ ]) }
477
+ });
478
+ /** PostgreSQL-only authorization lifecycle capsule. The host must prepare its registry at startup. */
479
+ const capsule = Effect.gen(function* () {
480
+ const definedMigration = yield* migration;
481
+ return yield* makeCapsule({
482
+ id: "domainkit.authorization-lifecycle",
483
+ migrations: [definedMigration],
484
+ layer: Layer.effect(ManagedDnsConnections.Service, makeRepository)
485
+ });
486
+ });
487
+ //#endregion
488
+ //#region src/index.ts
489
+ const VERSION = version;
490
+ //#endregion
491
+ export { custody_exports as CredentialCustody, host_bindings_exports as HostBindings, VERSION, capsule };
492
+
493
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["Error","Service","Error","CredentialCustody.Service","HostBindings.Service","packageJson.version"],"sources":["../package.json","../src/custody.ts","../src/host-bindings.ts","../src/persistence.ts","../src/index.ts"],"sourcesContent":["","import { Context, Effect, Schema } from \"effect\";\nimport type { ManagedDnsConnections } from \"domainkit\";\n\n/** Secret token material; credential expiry remains ordinary lifecycle metadata. */\nexport type Credential = Omit<ManagedDnsConnections.StoredCredential, \"expiresAt\">;\n\nexport class Error extends Schema.TaggedError<Error>()(\"CredentialCustodyError\", {\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\nexport interface Interface {\n readonly open: (ciphertext: string) => Effect.Effect<Credential, Error>;\n readonly seal: (credential: Credential) => Effect.Effect<string, Error>;\n}\n\n/** Host-owned encryption boundary. DomainKit never receives keys or stores plaintext. */\nexport class Service extends Context.Service<Service, Interface>()(\n \"@domainkit/capsuledb/CredentialCustody\",\n) {}\n","import { Context, Effect, Schema } from \"effect\";\n\nexport class Error extends Schema.TaggedError<Error>()(\"HostBindingError\", {\n message: Schema.String,\n operation: Schema.String,\n retry: Schema.Literals([\"never\", \"after-user-action\", \"safe\", \"unknown\"]),\n}) {}\n\nexport interface OwnerReference {\n readonly ownerReference: string;\n}\n\nexport interface DomainReference extends OwnerReference {\n readonly domainReference: string;\n}\n\nexport interface Interface {\n /** Resolve a durable host owner reference without capturing request identity. */\n readonly owner: (ownerId: string) => Effect.Effect<OwnerReference, Error>;\n /** Resolve a host domain reference inside the caller's active transaction context. */\n readonly domain: (input: {\n readonly domain: string;\n readonly ownerId: string;\n }) => Effect.Effect<DomainReference, Error>;\n /** Project an opaque stored owner reference back to DomainKit's semantic owner id. */\n readonly ownerId: (ownerReference: string) => Effect.Effect<string, Error>;\n}\n\n/** Stateless host mapping for tenant/domain foreign-key references. */\nexport class Service extends Context.Service<Service, Interface>()(\n \"@domainkit/capsuledb/HostBindings\",\n) {}\n","import { makeCapsule, makeMigration, sqlMigrationBody } from \"capsuledb\";\nimport { Connection, ManagedDnsConnections } from \"domainkit\";\nimport { Effect, Layer, Schema } from \"effect\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\nimport * as SqlError from \"effect/unstable/sql/SqlError\";\n\nimport * as CredentialCustody from \"./custody.ts\";\nimport * as HostBindings from \"./host-bindings.ts\";\n\ntype Authorization = ManagedDnsConnections.Authorization.ProviderAuthorization;\ntype StoredConnection = typeof ManagedDnsConnections.StoredConnection.Type;\ntype DomainAttachment = typeof Connection.DomainAttachment.Type;\n\ninterface StoredAggregate {\n readonly attachments: ReadonlyArray<DomainAttachment>;\n readonly authorization: Authorization;\n readonly connections: ReadonlyArray<StoredConnection>;\n readonly credentialCiphertext: string;\n readonly credentialExpiresAt: Date | null;\n}\n\ninterface AuthorizationRow {\n readonly capability_evidence: unknown;\n readonly capabilities: unknown;\n readonly created_at: Date;\n readonly credential_ciphertext: string | null;\n readonly expires_at: Date | null;\n readonly id: string;\n readonly kind: string;\n readonly provider_context: unknown;\n readonly provider_id: string;\n readonly revocation: unknown;\n readonly scopes: unknown;\n readonly subject_id: string;\n}\n\ninterface ConnectionRow {\n readonly authorization_id: string;\n readonly created_at: Date;\n readonly id: string;\n readonly organization_id: string;\n}\n\ninterface AttachmentRow {\n readonly connection_id: string;\n readonly created_at: Date;\n readonly id: string;\n readonly provider_account_id: string;\n readonly provider_target_context: unknown;\n readonly provider_zone_id: string;\n readonly provider_zone_name: string;\n}\n\nconst AttachmentContext = Schema.Struct({\n version: Schema.Literal(\"domainkit.attachment.v1\"),\n value: Schema.Struct({\n accountKind: Schema.NullOr(Schema.Literals([\"account\", \"personal\", \"team\"])),\n domain: Schema.String,\n evidence: Schema.optionalKey(Connection.ProviderTargetEvidence),\n }),\n});\n\nconst storageError = (\n operation: string,\n message: string,\n retry: \"never\" | \"after-user-action\" | \"safe\" | \"unknown\" = \"unknown\",\n) =>\n new ManagedDnsConnections.Error({\n category: \"storage\",\n message,\n operation,\n retry,\n });\n\nconst missing = (operation: string, message: string) => storageError(operation, message, \"never\");\nconst conflict = (operation: string, message: string) =>\n storageError(operation, message, \"after-user-action\");\n\nconst sqlErrorMessage = (error: SqlError.SqlError): string =>\n error.reason.cause instanceof Error\n ? `${error.reason._tag}: ${error.reason.cause.message}`\n : `${error.reason._tag}: ${error.reason.message ?? String(error.reason.cause)}`;\n\nconst mapCapabilityError = (\n operation: string,\n error: {\n readonly message: string;\n readonly retry: \"never\" | \"after-user-action\" | \"safe\" | \"unknown\";\n },\n) => storageError(operation, error.message, error.retry);\n\nconst mapSql = <A, E, R>(\n operation: string,\n effect: Effect.Effect<A, E, R>,\n): Effect.Effect<A, Exclude<E, SqlError.SqlError> | ManagedDnsConnections.Error, R> =>\n // SAFETY: the runtime guard maps every SqlError and re-fails every other E unchanged.\n Effect.matchEffect(effect, {\n onFailure: (error) => {\n const mapped: E | ManagedDnsConnections.Error = SqlError.isSqlError(error)\n ? storageError(operation, sqlErrorMessage(error), \"unknown\")\n : error;\n return Effect.fail(mapped);\n },\n onSuccess: Effect.succeed,\n }) as Effect.Effect<A, Exclude<E, SqlError.SqlError> | ManagedDnsConnections.Error, R>;\n\nconst sameAttachment = (left: DomainAttachment, right: DomainAttachment): boolean =>\n left.connectionId === right.connectionId &&\n left.domain === right.domain &&\n left.target.accountId === right.target.accountId &&\n left.target.accountKind === right.target.accountKind &&\n left.target.zoneId === right.target.zoneId &&\n left.target.zoneName === right.target.zoneName;\n\nconst decodeAuthorization = Effect.fn(\"CapsuleManagedDnsConnections.decodeAuthorization\")(\n function* (row: AuthorizationRow) {\n if (row.credential_ciphertext === null) {\n return yield* Effect.fail(\n missing(\"decodeAuthorization\", `Authorization ${row.id} has no credential ciphertext`),\n );\n }\n const authorization = yield* Schema.decodeUnknownEffect(\n ManagedDnsConnections.Authorization.Schema,\n )({\n authorizedById: row.subject_id,\n capabilityEvidence: row.capability_evidence,\n createdAt: row.created_at.toISOString(),\n id: row.id,\n method: row.kind,\n providerContext: row.provider_context,\n providerId: row.provider_id,\n requiredCapabilities: row.capabilities,\n revocation: row.revocation,\n scopes: row.scopes,\n }).pipe(\n Effect.mapError((error) =>\n missing(\"decodeAuthorization\", `Authorization ${row.id} is invalid: ${error.message}`),\n ),\n );\n return {\n authorization,\n credentialCiphertext: row.credential_ciphertext,\n credentialExpiresAt: row.expires_at,\n };\n },\n);\n\nconst decodeAttachment = Effect.fn(\"CapsuleManagedDnsConnections.decodeAttachment\")(function* (\n row: AttachmentRow,\n) {\n const context = yield* Schema.decodeUnknownEffect(AttachmentContext)(\n row.provider_target_context,\n ).pipe(\n Effect.mapError((error) =>\n missing(\"decodeAttachment\", `Attachment ${row.id} context is invalid: ${error.message}`),\n ),\n );\n return yield* Schema.decodeUnknownEffect(Connection.DomainAttachment)({\n connectionId: row.connection_id,\n createdAt: row.created_at.toISOString(),\n domain: context.value.domain,\n id: row.id,\n target: {\n accountId: row.provider_account_id,\n accountKind: context.value.accountKind,\n ...(context.value.evidence === undefined ? {} : { evidence: context.value.evidence }),\n zoneId: row.provider_zone_id,\n zoneName: row.provider_zone_name,\n },\n }).pipe(\n Effect.mapError((error) =>\n missing(\"decodeAttachment\", `Attachment ${row.id} is invalid: ${error.message}`),\n ),\n );\n});\n\nconst encodeAuthorization = Effect.fn(\"CapsuleManagedDnsConnections.encodeAuthorization\")(\n function* (authorization: Authorization) {\n return yield* Schema.encodeUnknownEffect(ManagedDnsConnections.Authorization.Schema)(\n authorization,\n ).pipe(\n Effect.mapError((error) =>\n conflict(\"encodeAuthorization\", `Authorization cannot be encoded: ${error.message}`),\n ),\n );\n },\n);\n\nconst loadAggregate = Effect.fn(\"CapsuleManagedDnsConnections.loadAggregate\")(function* (\n sql: SqlClient.SqlClient,\n bindings: HostBindings.Interface,\n authorizationId: string,\n lock: \"share\" | \"update\" = \"share\",\n) {\n const lockClause = lock === \"update\" ? \"FOR UPDATE\" : \"FOR SHARE\";\n const authorizationRows = yield* sql.unsafe<AuthorizationRow>(\n `SELECT id, provider_id, subject_id, kind, capabilities, capability_evidence, scopes,\n provider_context, revocation, credential_ciphertext, expires_at, created_at\n FROM domain_provider_authorizations WHERE id = $1 ${lockClause}`,\n [authorizationId],\n );\n const row = authorizationRows[0];\n if (row === undefined) return null;\n const decoded = yield* decodeAuthorization(row);\n const connectionRows = yield* sql<ConnectionRow>`SELECT id, organization_id, authorization_id,\n created_at FROM organization_domain_provider_connections\n WHERE authorization_id = ${authorizationId} ORDER BY id`;\n const connections = yield* Effect.forEach(connectionRows, (connection) =>\n bindings.ownerId(connection.organization_id).pipe(\n Effect.mapError((error) => mapCapabilityError(\"loadAggregate\", error)),\n Effect.map(\n (ownerId) =>\n ({\n authorizationId: connection.authorization_id,\n createdAt: connection.created_at,\n id: connection.id,\n method: decoded.authorization.method,\n ownerId,\n providerId: decoded.authorization.providerId,\n }) satisfies StoredConnection,\n ),\n ),\n );\n const attachmentRows = yield* sql<AttachmentRow>`SELECT a.id, a.connection_id,\n a.provider_account_id, a.provider_zone_id, a.provider_zone_name,\n a.provider_target_context, a.created_at\n FROM domain_provider_attachments a\n JOIN organization_domain_provider_connections c ON c.id = a.connection_id\n WHERE c.authorization_id = ${authorizationId} ORDER BY a.id`;\n const attachments = yield* Effect.forEach(attachmentRows, decodeAttachment);\n return {\n attachments,\n authorization: decoded.authorization,\n connections,\n credentialCiphertext: decoded.credentialCiphertext,\n credentialExpiresAt: decoded.credentialExpiresAt,\n } satisfies StoredAggregate;\n});\n\nconst authorizationIdForConnection = Effect.fn(\n \"CapsuleManagedDnsConnections.authorizationIdForConnection\",\n)(function* (sql: SqlClient.SqlClient, connectionId: string) {\n const rows = yield* sql<{ readonly authorization_id: string }>`SELECT authorization_id\n FROM organization_domain_provider_connections WHERE id = ${connectionId}`;\n return rows[0]?.authorization_id ?? null;\n});\n\nconst authorizationIdForAttachment = Effect.fn(\n \"CapsuleManagedDnsConnections.authorizationIdForAttachment\",\n)(function* (sql: SqlClient.SqlClient, attachmentId: string) {\n const rows = yield* sql<{ readonly authorization_id: string }>`SELECT c.authorization_id\n FROM domain_provider_attachments a\n JOIN organization_domain_provider_connections c ON c.id = a.connection_id\n WHERE a.id = ${attachmentId}`;\n return rows[0]?.authorization_id ?? null;\n});\n\nconst openAggregate = Effect.fn(\"CapsuleManagedDnsConnections.openAggregate\")(function* (\n custody: CredentialCustody.Interface,\n aggregate: StoredAggregate,\n) {\n const opened = yield* custody\n .open(aggregate.credentialCiphertext)\n .pipe(Effect.mapError((error) => mapCapabilityError(\"openCredential\", error)));\n const credential = { ...opened, expiresAt: aggregate.credentialExpiresAt };\n return {\n attachments: aggregate.attachments,\n authorization: aggregate.authorization,\n connections: aggregate.connections,\n credential,\n } satisfies ManagedDnsConnections.Aggregate;\n});\n\nconst projectConnection = Effect.fn(\"CapsuleManagedDnsConnections.projectConnection\")(function* (\n custody: CredentialCustody.Interface,\n aggregate: StoredAggregate,\n connection: StoredConnection,\n authorization: Authorization = aggregate.authorization,\n) {\n const opened = yield* openAggregate(custody, aggregate);\n return Connection.project(connection, authorization, opened.credential);\n});\n\nconst writeAuthorization = Effect.fn(\"CapsuleManagedDnsConnections.writeAuthorization\")(function* (\n sql: SqlClient.SqlClient,\n authorization: Authorization,\n credentialCiphertext: string,\n credentialExpiresAt: Date | null,\n) {\n const encoded = yield* encodeAuthorization(authorization);\n yield* sql`INSERT INTO domain_provider_authorizations (\n id, provider_id, account_id, subject_id, kind, capabilities, capability_evidence, scopes,\n provider_context, revocation, credential_ciphertext, expires_at, created_at, updated_at\n ) VALUES (\n ${authorization.id}, ${authorization.providerId}, NULL, ${authorization.authorizedById},\n ${authorization.method}, ${JSON.stringify(encoded.requiredCapabilities)}::jsonb,\n ${JSON.stringify(encoded.capabilityEvidence)}::jsonb,\n ${JSON.stringify(encoded.scopes)}::jsonb, ${JSON.stringify(encoded.providerContext)}::jsonb,\n ${JSON.stringify(encoded.revocation)}::jsonb,\n ${credentialCiphertext}, ${credentialExpiresAt}, ${authorization.createdAt}, NOW()\n ) ON CONFLICT (id) DO UPDATE SET\n provider_id = EXCLUDED.provider_id,\n subject_id = EXCLUDED.subject_id,\n kind = EXCLUDED.kind,\n capabilities = EXCLUDED.capabilities,\n capability_evidence = EXCLUDED.capability_evidence,\n scopes = EXCLUDED.scopes,\n provider_context = EXCLUDED.provider_context,\n revocation = EXCLUDED.revocation,\n credential_ciphertext = EXCLUDED.credential_ciphertext,\n expires_at = EXCLUDED.expires_at,\n updated_at = NOW()`;\n});\n\nconst makeRepository = Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n const custody = yield* CredentialCustody.Service;\n const bindings = yield* HostBindings.Service;\n\n const withRevocationLock = <A, E, R>(\n operation: string,\n authorizationId: string,\n effect: Effect.Effect<A, E, R>,\n ) =>\n sql.withTransaction(\n Effect.gen(function* () {\n const rows = yield* sql<{ readonly acquired: boolean }>`\n SELECT pg_try_advisory_xact_lock(hashtextextended(${authorizationId}, 0)) AS acquired`;\n if (rows[0]?.acquired !== true)\n return yield* Effect.fail(\n storageError(operation, \"Provider revocation is already in progress\", \"safe\"),\n );\n return yield* effect;\n }),\n );\n\n const getStored = (authorizationId: string, lock: \"share\" | \"update\" = \"share\") =>\n loadAggregate(sql, bindings, authorizationId, lock);\n\n const get = (authorizationId: string) =>\n mapSql(\n \"get\",\n sql\n .withTransaction(getStored(authorizationId))\n .pipe(\n Effect.flatMap((aggregate) =>\n aggregate === null ? Effect.succeed(null) : openAggregate(custody, aggregate),\n ),\n ),\n );\n\n const getByConnectionId = (connectionId: string) =>\n mapSql(\n \"getByConnectionId\",\n sql\n .withTransaction(\n Effect.gen(function* () {\n const authorizationId = yield* authorizationIdForConnection(sql, connectionId);\n if (authorizationId === null) return null;\n const aggregate = yield* getStored(authorizationId);\n if (\n aggregate === null ||\n !aggregate.connections.some((connection) => connection.id === connectionId)\n )\n return null;\n return aggregate;\n }),\n )\n .pipe(\n Effect.flatMap((aggregate) =>\n aggregate === null ? Effect.succeed(null) : openAggregate(custody, aggregate),\n ),\n ),\n );\n\n const service: ManagedDnsConnections.Interface = ManagedDnsConnections.Service.of({\n attach: (input) =>\n mapSql(\n \"attach\",\n sql.withTransaction(\n Effect.gen(function* () {\n const authorizationId = yield* authorizationIdForConnection(sql, input.connectionId);\n if (authorizationId === null)\n return yield* Effect.fail(missing(\"attach\", \"Provider connection does not exist\"));\n const aggregate = yield* getStored(authorizationId, \"update\");\n if (aggregate === null)\n return yield* Effect.fail(missing(\"attach\", \"Provider authorization does not exist\"));\n const connection = aggregate.connections.find(\n (candidate) =>\n candidate.id === input.connectionId && candidate.ownerId === input.ownerId,\n );\n if (connection === undefined)\n return yield* Effect.fail(\n missing(\"attach\", \"Provider connection does not belong to this owner\"),\n );\n if (aggregate.authorization.revocation._tag === \"Pending\")\n return yield* Effect.fail(\n conflict(\"attach\", \"Provider authorization is awaiting revocation recovery\"),\n );\n if (input.attachment.connectionId !== input.connectionId)\n return yield* Effect.fail(\n conflict(\"attach\", \"Domain attachment targets another connection\"),\n );\n const existing = aggregate.attachments.find(({ id }) => id === input.attachment.id);\n if (existing !== undefined) {\n if (!sameAttachment(existing, input.attachment))\n return yield* Effect.fail(\n conflict(\"attach\", \"Domain attachment id is already in use\"),\n );\n return {\n attachment: existing,\n connection: yield* projectConnection(custody, aggregate, connection),\n };\n }\n const reference = yield* bindings\n .domain({ domain: input.attachment.domain, ownerId: input.ownerId })\n .pipe(Effect.mapError((error) => mapCapabilityError(\"attach\", error)));\n const context = {\n version: \"domainkit.attachment.v1\" as const,\n value: {\n accountKind: input.attachment.target.accountKind,\n domain: input.attachment.domain,\n ...(input.attachment.target.evidence === undefined\n ? {}\n : { evidence: input.attachment.target.evidence }),\n },\n };\n yield* sql`INSERT INTO domain_provider_attachments (\n id, organization_id, connection_id, domain_id, provider_account_id,\n provider_zone_id, provider_zone_name, provider_target_context, created_at, updated_at\n ) VALUES (\n ${input.attachment.id}, ${reference.ownerReference}, ${input.connectionId},\n ${reference.domainReference}, ${input.attachment.target.accountId},\n ${input.attachment.target.zoneId}, ${input.attachment.target.zoneName},\n ${JSON.stringify(context)}::jsonb,\n ${input.attachment.createdAt}, NOW()\n )`;\n return {\n attachment: input.attachment,\n connection: yield* projectConnection(custody, aggregate, connection),\n };\n }),\n ),\n ),\n connect: (input) =>\n custody.seal(input.credential).pipe(\n Effect.mapError((error) => mapCapabilityError(\"connect\", error)),\n Effect.flatMap((credentialCiphertext) =>\n mapSql(\n \"connect\",\n sql.withTransaction(\n Effect.gen(function* () {\n yield* sql`SELECT pg_advisory_xact_lock(hashtextextended(${input.authorization.id}, 0))`;\n const current = yield* getStored(input.authorization.id, \"update\");\n if (\n current?.authorization.revocation._tag === \"Pending\" ||\n (input.expectedAuthorizationId !== undefined && current === null)\n )\n return yield* Effect.fail(\n conflict(\n \"connect\",\n current === null\n ? \"Provider authorization no longer exists\"\n : \"Provider authorization is awaiting revocation recovery\",\n ),\n );\n if (\n input.authorization.id !== input.connection.authorizationId ||\n input.authorization.providerId !== input.connection.providerId ||\n input.authorization.method !== input.connection.method\n )\n return yield* Effect.fail(\n conflict(\"connect\", \"Connection does not match its authorization\"),\n );\n const existingConnection = current?.connections.find(\n ({ ownerId }) => ownerId === input.connection.ownerId,\n );\n if (\n input.expectedConnectionId !== undefined &&\n existingConnection?.id !== input.expectedConnectionId\n )\n return yield* Effect.fail(\n conflict(\"connect\", \"Organization connection changed during reconnect\"),\n );\n yield* writeAuthorization(\n sql,\n input.authorization,\n credentialCiphertext,\n input.credential.expiresAt,\n );\n if (existingConnection === undefined) {\n const reference = yield* bindings\n .owner(input.connection.ownerId)\n .pipe(Effect.mapError((error) => mapCapabilityError(\"connect\", error)));\n yield* sql`INSERT INTO organization_domain_provider_connections (\n id, organization_id, authorization_id, created_at, updated_at\n ) VALUES (\n ${input.connection.id}, ${reference.ownerReference},\n ${input.authorization.id}, ${input.connection.createdAt}, NOW()\n )`;\n }\n const stored = yield* getStored(input.authorization.id, \"update\");\n return (\n stored ?? (yield* Effect.fail(missing(\"connect\", \"Authorization write vanished\")))\n );\n }),\n ),\n ),\n ),\n Effect.flatMap((aggregate) => openAggregate(custody, aggregate)),\n ),\n detach: ({ attachmentId, ownerId }) =>\n mapSql(\n \"detach\",\n sql.withTransaction(\n Effect.gen(function* () {\n const authorizationId = yield* authorizationIdForAttachment(sql, attachmentId);\n if (authorizationId === null)\n return yield* Effect.fail(missing(\"detach\", \"Domain attachment does not exist\"));\n const aggregate = yield* getStored(authorizationId, \"update\");\n const attachment = aggregate?.attachments.find(({ id }) => id === attachmentId);\n if (aggregate === null || attachment === undefined)\n return yield* Effect.fail(missing(\"detach\", \"Domain attachment does not exist\"));\n const connection = aggregate.connections.find(\n ({ id, ownerId: candidate }) =>\n id === attachment.connectionId && candidate === ownerId,\n );\n if (connection === undefined)\n return yield* Effect.fail(\n missing(\"detach\", \"Domain attachment does not belong to this owner\"),\n );\n yield* sql`DELETE FROM domain_provider_attachments WHERE id = ${attachmentId}`;\n return {\n attachment,\n connection: yield* projectConnection(custody, aggregate, connection),\n remainingAttachments: aggregate.attachments.filter(\n ({ connectionId, id }) => connectionId === connection.id && id !== attachmentId,\n ).length,\n };\n }),\n ),\n ),\n disconnect: <E>({\n connectionId,\n ownerId,\n revoke,\n }: {\n readonly connectionId: string;\n readonly ownerId: string;\n readonly revoke: (authorization: Authorization) => Effect.Effect<void, E>;\n }) =>\n mapSql(\n \"disconnect\",\n sql\n .withTransaction(\n Effect.gen(function* () {\n const authorizationId = yield* authorizationIdForConnection(sql, connectionId);\n if (authorizationId === null)\n return yield* Effect.fail(\n missing(\"disconnect\", \"Provider connection does not exist\"),\n );\n const aggregate = yield* getStored(authorizationId, \"update\");\n const connection = aggregate?.connections.find(\n ({ id, ownerId: candidate }) => id === connectionId && candidate === ownerId,\n );\n if (aggregate === null || connection === undefined)\n return yield* Effect.fail(\n missing(\"disconnect\", \"Provider connection does not belong to this owner\"),\n );\n if (aggregate.attachments.some(({ connectionId: id }) => id === connectionId))\n return yield* Effect.fail(\n conflict(\n \"disconnect\",\n \"Detach all organization domains before disconnecting the provider\",\n ),\n );\n if (aggregate.connections.length > 1) {\n yield* sql`DELETE FROM organization_domain_provider_connections\n WHERE id = ${connectionId}`;\n return {\n _tag: \"Disconnected\" as const,\n connection: yield* projectConnection(custody, aggregate, connection),\n remainingConnections: aggregate.connections.length - 1,\n };\n }\n if (aggregate.authorization.revocation._tag === \"Pending\")\n return yield* Effect.fail(\n conflict(\"disconnect\", \"Provider authorization is awaiting revocation recovery\"),\n );\n const pending: Authorization = {\n ...aggregate.authorization,\n revocation: { _tag: \"Pending\", requestedAt: new Date() },\n };\n yield* writeAuthorization(\n sql,\n pending,\n aggregate.credentialCiphertext,\n aggregate.credentialExpiresAt,\n );\n return {\n _tag: \"Prepared\" as const,\n authorization: pending,\n connection: yield* projectConnection(custody, aggregate, connection, pending),\n };\n }),\n )\n .pipe(\n Effect.flatMap((prepared) => {\n if (prepared._tag === \"Disconnected\") {\n const result: ManagedDnsConnections.DisconnectResult = {\n connection: prepared.connection,\n remainingConnections: prepared.remainingConnections,\n revokedAuthorization: false,\n };\n return Effect.succeed(result);\n }\n const result: ManagedDnsConnections.DisconnectResult = {\n connection: prepared.connection,\n remainingConnections: 0,\n revokedAuthorization: true,\n };\n return withRevocationLock(\n \"disconnect\",\n prepared.authorization.id,\n getStored(prepared.authorization.id, \"update\").pipe(\n Effect.flatMap((current) => {\n if (current?.authorization.revocation._tag !== \"Pending\")\n return Effect.fail(\n conflict(\"disconnect\", \"Revocation state changed before provider call\"),\n );\n return revoke(current.authorization).pipe(\n Effect.andThen(\n Effect.gen(function* () {\n const aggregate = yield* getStored(prepared.authorization.id, \"update\");\n if (aggregate?.authorization.revocation._tag !== \"Pending\")\n return yield* Effect.fail(\n conflict(\"disconnect\", \"Revocation state changed before completion\"),\n );\n yield* sql`DELETE FROM domain_provider_attachments WHERE connection_id IN\n (SELECT id FROM organization_domain_provider_connections\n WHERE authorization_id = ${prepared.authorization.id})`;\n yield* sql`DELETE FROM organization_domain_provider_connections\n WHERE authorization_id = ${prepared.authorization.id}`;\n yield* sql`DELETE FROM domain_provider_authorizations\n WHERE id = ${prepared.authorization.id}`;\n }),\n ),\n Effect.as(result),\n );\n }),\n ),\n );\n }),\n ),\n ),\n findConnection: (ownerId, authorizationId) =>\n get(authorizationId).pipe(\n Effect.map(\n (aggregate) =>\n aggregate?.connections.find((connection) => connection.ownerId === ownerId) ?? null,\n ),\n ),\n get,\n getAttachment: (attachmentId) =>\n mapSql(\n \"getAttachment\",\n sql.withTransaction(\n Effect.gen(function* () {\n const authorizationId = yield* authorizationIdForAttachment(sql, attachmentId);\n if (authorizationId === null) return null;\n const aggregate = yield* getStored(authorizationId);\n return aggregate?.attachments.find(({ id }) => id === attachmentId) ?? null;\n }),\n ),\n ),\n getByConnectionId,\n listAttachments: (connectionId, ownerId) =>\n getByConnectionId(connectionId).pipe(\n Effect.flatMap((aggregate) => {\n if (aggregate === null)\n return Effect.fail(missing(\"listAttachments\", \"Provider connection does not exist\"));\n if (\n !aggregate.connections.some(\n (connection) => connection.id === connectionId && connection.ownerId === ownerId,\n )\n )\n return Effect.fail(\n missing(\"listAttachments\", \"Provider connection does not belong to this owner\"),\n );\n return Effect.succeed(\n aggregate.attachments.filter((attachment) => attachment.connectionId === connectionId),\n );\n }),\n ),\n promoteEvidence: (authorizationId, evidence) =>\n mapSql(\n \"promoteEvidence\",\n sql.withTransaction(\n Effect.gen(function* () {\n const aggregate = yield* getStored(authorizationId, \"update\");\n if (aggregate === null)\n return yield* Effect.fail(\n missing(\"promoteEvidence\", \"Provider authorization does not exist\"),\n );\n const byCapability = new Map(\n aggregate.authorization.capabilityEvidence.map((item) => [item.capability, item]),\n );\n for (const item of evidence) byCapability.set(item.capability, item);\n yield* writeAuthorization(\n sql,\n {\n ...aggregate.authorization,\n capabilityEvidence: [...byCapability.values()],\n },\n aggregate.credentialCiphertext,\n aggregate.credentialExpiresAt,\n );\n return (\n (yield* getStored(authorizationId, \"update\")) ??\n (yield* Effect.fail(missing(\"promoteEvidence\", \"Authorization write vanished\")))\n );\n }),\n ),\n ).pipe(Effect.flatMap((aggregate) => openAggregate(custody, aggregate))),\n recover: ({ authorizationId, revoke }) =>\n mapSql(\n \"recover\",\n withRevocationLock(\n \"recover\",\n authorizationId,\n getStored(authorizationId, \"update\").pipe(\n Effect.flatMap((aggregate) =>\n Effect.gen(function* () {\n if (aggregate === null)\n return yield* Effect.fail(\n missing(\"recover\", \"Provider authorization does not exist\"),\n );\n if (aggregate.authorization.revocation._tag !== \"Pending\")\n return yield* Effect.fail(\n missing(\"recover\", \"Provider authorization is not awaiting revocation\"),\n );\n const connection = aggregate.connections[0];\n if (connection === undefined)\n return yield* Effect.fail(\n missing(\"recover\", \"Pending authorization has no connection\"),\n );\n const projected = yield* projectConnection(custody, aggregate, connection);\n return yield* revoke(aggregate.authorization).pipe(\n Effect.andThen(\n Effect.gen(function* () {\n const current = yield* getStored(authorizationId, \"update\");\n if (current?.authorization.revocation._tag !== \"Pending\")\n return yield* Effect.fail(\n conflict(\"recover\", \"Revocation state changed before completion\"),\n );\n yield* sql`DELETE FROM domain_provider_attachments WHERE connection_id IN\n (SELECT id FROM organization_domain_provider_connections\n WHERE authorization_id = ${authorizationId})`;\n yield* sql`DELETE FROM organization_domain_provider_connections\n WHERE authorization_id = ${authorizationId}`;\n yield* sql`DELETE FROM domain_provider_authorizations WHERE id = ${authorizationId}`;\n }),\n ),\n Effect.as({\n connection: projected,\n remainingConnections: 0,\n revokedAuthorization: true as const,\n }),\n );\n }),\n ),\n ),\n ),\n ),\n rotate: (authorizationId, credential) =>\n custody.seal(credential).pipe(\n Effect.mapError((error) => mapCapabilityError(\"rotate\", error)),\n Effect.flatMap((credentialCiphertext) =>\n mapSql(\n \"rotate\",\n sql.withTransaction(\n Effect.gen(function* () {\n const aggregate = yield* getStored(authorizationId, \"update\");\n if (aggregate === null)\n return yield* Effect.fail(\n missing(\"rotate\", \"Provider authorization does not exist\"),\n );\n yield* writeAuthorization(\n sql,\n aggregate.authorization,\n credentialCiphertext,\n credential.expiresAt,\n );\n return (\n (yield* getStored(authorizationId, \"update\")) ??\n (yield* Effect.fail(missing(\"rotate\", \"Authorization write vanished\")))\n );\n }),\n ),\n ),\n ),\n Effect.flatMap((aggregate) => openAggregate(custody, aggregate)),\n ),\n });\n\n return service;\n});\n\nconst migration = makeMigration({\n id: 1,\n name: \"adopt-authorization-lifecycle\",\n risk: \"additive\",\n providers: {\n Postgres: sqlMigrationBody([\n `CREATE TABLE IF NOT EXISTS domain_provider_authorizations (\n id TEXT PRIMARY KEY NOT NULL,\n provider_id TEXT NOT NULL,\n account_id TEXT,\n subject_id TEXT NOT NULL,\n kind TEXT NOT NULL,\n capabilities JSONB NOT NULL,\n capability_evidence JSONB NOT NULL,\n scopes JSONB NOT NULL,\n provider_context JSONB NOT NULL,\n revocation JSONB NOT NULL,\n credential_ciphertext TEXT,\n expires_at TIMESTAMPTZ,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()\n )`,\n `ALTER TABLE domain_provider_authorizations\n DROP CONSTRAINT IF EXISTS uq_domain_provider_authorizations_provider_account`,\n `ALTER TABLE domain_provider_authorizations ALTER COLUMN account_id DROP NOT NULL`,\n `CREATE TABLE IF NOT EXISTS organization_domain_provider_connections (\n id TEXT PRIMARY KEY NOT NULL,\n organization_id TEXT NOT NULL,\n authorization_id TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n CONSTRAINT uq_organization_domain_provider_connections_org_authorization\n UNIQUE (organization_id, authorization_id),\n CONSTRAINT uq_organization_domain_provider_connections_id_org\n UNIQUE (id, organization_id)\n )`,\n `CREATE INDEX IF NOT EXISTS idx_organization_domain_provider_connections_authorization\n ON organization_domain_provider_connections (authorization_id)`,\n `DO $$ BEGIN\n IF to_regclass('domain_connections') IS NOT NULL THEN\n INSERT INTO organization_domain_provider_connections (\n id, organization_id, authorization_id, created_at, updated_at\n ) SELECT id, organization_id, authorization_id, created_at, updated_at\n FROM domain_connections ON CONFLICT DO NOTHING;\n END IF;\n END $$`,\n `CREATE TABLE IF NOT EXISTS domain_provider_attachments (\n id TEXT PRIMARY KEY NOT NULL,\n organization_id TEXT NOT NULL,\n connection_id TEXT NOT NULL,\n domain_id TEXT NOT NULL,\n provider_account_id TEXT NOT NULL,\n provider_zone_id TEXT NOT NULL,\n provider_zone_name TEXT NOT NULL,\n provider_target_context JSONB NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n CONSTRAINT uq_domain_provider_attachments_org_domain UNIQUE (organization_id, domain_id),\n CONSTRAINT uq_domain_provider_attachments_connection_domain UNIQUE (connection_id, domain_id)\n )`,\n `CREATE INDEX IF NOT EXISTS idx_domain_provider_attachments_connection\n ON domain_provider_attachments (connection_id)`,\n `DO $$ BEGIN\n IF EXISTS (SELECT 1 FROM domain_provider_authorizations WHERE credential_ciphertext IS NULL)\n THEN RAISE EXCEPTION 'DomainKit adoption requires encrypted credential ciphertext';\n END IF;\n IF EXISTS (\n SELECT 1 FROM domain_provider_attachments\n WHERE provider_target_context #>> '{value,domain}' IS NULL\n ) THEN RAISE EXCEPTION 'DomainKit adoption requires semantic attachment domains';\n END IF;\n END $$`,\n ]),\n },\n});\n\n/** PostgreSQL-only authorization lifecycle capsule. The host must prepare its registry at startup. */\nexport const capsule = Effect.gen(function* () {\n const definedMigration = yield* migration;\n return yield* makeCapsule({\n id: \"domainkit.authorization-lifecycle\",\n migrations: [definedMigration],\n layer: Layer.effect(ManagedDnsConnections.Service, makeRepository),\n });\n});\n","import packageJson from \"../package.json\" with { type: \"json\" };\n\nexport const VERSION = packageJson.version;\n\nexport * as CredentialCustody from \"./custody.ts\";\nexport * as HostBindings from \"./host-bindings.ts\";\nexport { capsule } from \"./persistence.ts\";\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll as t };
package/package.json CHANGED
@@ -1,5 +1,69 @@
1
1
  {
2
2
  "name": "@domainkit/capsuledb",
3
- "version": "0.0.0-tegami-trusted-publish-setup",
4
- "description": "Placeholder published by Tegami for npm trusted publishing setup."
3
+ "version": "0.1.1",
4
+ "description": "Optional PostgreSQL storage for DomainKit's Effect apps",
5
+ "keywords": [
6
+ "dns",
7
+ "domainkit",
8
+ "effect",
9
+ "postgresql",
10
+ "typescript"
11
+ ],
12
+ "homepage": "https://github.com/AryaLabsHQ/domainkit#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/AryaLabsHQ/domainkit/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "Arya Labs",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/AryaLabsHQ/domainkit.git",
21
+ "directory": "packages/capsuledb"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "LICENSE",
26
+ "README.md"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.mts",
33
+ "import": "./dist/index.mjs"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "scripts": {
41
+ "build": "tsdown",
42
+ "release:check": "bun run typecheck && bun run test && bun run build && bun run test:artifact",
43
+ "test": "vitest run --exclude tests/artifact/**/*.test.ts",
44
+ "test:artifact": "vitest run tests/artifact",
45
+ "typecheck": "tsc --noEmit"
46
+ },
47
+ "dependencies": {
48
+ "domainkit": "^0.7.0"
49
+ },
50
+ "devDependencies": {
51
+ "@effect/sql-pg": "4.0.0-rc.112",
52
+ "@effect/vitest": "4.0.0-rc.112",
53
+ "@testcontainers/postgresql": "12.1.0",
54
+ "@types/bun": "1.4.0",
55
+ "capsuledb": "git+https://github.com/aryasaatvik/CapsuleDB.git#561aa127b37055f885c703583c3c5e80b44395f3",
56
+ "drizzle-orm": "1.0.0-rc.5-ab785fc",
57
+ "effect": "4.0.0-rc.112",
58
+ "tsdown": "0.22.14",
59
+ "typescript": "7.0.2",
60
+ "vitest": "4.1.11"
61
+ },
62
+ "peerDependencies": {
63
+ "capsuledb": ">=0.1.0 <0.2.0",
64
+ "effect": ">=4.0.0-rc.112 <5.0.0"
65
+ },
66
+ "engines": {
67
+ "node": ">=24.10.0"
68
+ }
5
69
  }