@yielded/auth-persistence-drizzle 0.1.0-beta.1 → 0.1.0-beta.12

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 (222) hide show
  1. package/dist/D1.d.mts +27 -22
  2. package/dist/D1.mjs +10 -4
  3. package/dist/D1.mjs.map +1 -1
  4. package/dist/Libsql.d.mts +66 -61
  5. package/dist/Libsql.mjs +20 -15
  6. package/dist/Libsql.mjs.map +1 -1
  7. package/dist/Mysql2.d.mts +58 -46
  8. package/dist/Mysql2.mjs +13 -6
  9. package/dist/Mysql2.mjs.map +1 -1
  10. package/dist/Pglite.d.mts +43 -32
  11. package/dist/Pglite.mjs +12 -7
  12. package/dist/Pglite.mjs.map +1 -1
  13. package/dist/Postgres.d.mts +59 -48
  14. package/dist/Postgres.mjs +12 -7
  15. package/dist/Postgres.mjs.map +1 -1
  16. package/dist/SqliteBun.d.mts +58 -53
  17. package/dist/SqliteBun.mjs +20 -14
  18. package/dist/SqliteBun.mjs.map +1 -1
  19. package/dist/SqliteDo.d.mts +66 -60
  20. package/dist/SqliteDo.mjs +26 -14
  21. package/dist/SqliteDo.mjs.map +1 -1
  22. package/dist/SqliteNode.d.mts +58 -53
  23. package/dist/SqliteNode.mjs +20 -14
  24. package/dist/SqliteNode.mjs.map +1 -1
  25. package/dist/SqliteWasm.d.mts +66 -61
  26. package/dist/SqliteWasm.mjs +20 -14
  27. package/dist/SqliteWasm.mjs.map +1 -1
  28. package/dist/drizzle/d1-database.d.mts +11 -0
  29. package/dist/drizzle/d1-database.mjs +8 -0
  30. package/dist/drizzle/d1-database.mjs.map +1 -0
  31. package/dist/drizzle/d1-emails.d.mts +8 -7
  32. package/dist/drizzle/d1-emails.mjs +7 -4
  33. package/dist/drizzle/d1-emails.mjs.map +1 -1
  34. package/dist/drizzle/d1-identity.mjs +12 -9
  35. package/dist/drizzle/d1-identity.mjs.map +1 -1
  36. package/dist/drizzle/d1-oauth.d.mts +14 -13
  37. package/dist/drizzle/d1-oauth.mjs +7 -4
  38. package/dist/drizzle/d1-oauth.mjs.map +1 -1
  39. package/dist/drizzle/d1-passkey.d.mts +3 -14
  40. package/dist/drizzle/d1-passkey.mjs +2 -1
  41. package/dist/drizzle/d1-passkey.mjs.map +1 -1
  42. package/dist/drizzle/d1-password-prepared.d.mts +4 -3
  43. package/dist/drizzle/d1-password-prepared.mjs +3 -1
  44. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  45. package/dist/drizzle/d1-passwords.d.mts +6 -5
  46. package/dist/drizzle/d1-passwords.mjs +5 -2
  47. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  48. package/dist/drizzle/d1-phone.d.mts +3 -4
  49. package/dist/drizzle/d1-phone.mjs +2 -1
  50. package/dist/drizzle/d1-phone.mjs.map +1 -1
  51. package/dist/drizzle/d1-planning.d.mts +1 -1
  52. package/dist/drizzle/d1-proofs.d.mts +4 -3
  53. package/dist/drizzle/d1-proofs.mjs +3 -1
  54. package/dist/drizzle/d1-proofs.mjs.map +1 -1
  55. package/dist/drizzle/d1-sessions.d.mts +11 -10
  56. package/dist/drizzle/d1-sessions.mjs +15 -9
  57. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  58. package/dist/drizzle/d1-totp.d.mts +3 -4
  59. package/dist/drizzle/d1-totp.mjs +2 -1
  60. package/dist/drizzle/d1-totp.mjs.map +1 -1
  61. package/dist/drizzle/email-registration.mjs +2 -1
  62. package/dist/drizzle/email-registration.mjs.map +1 -1
  63. package/dist/drizzle/email-target.d.mts +7 -6
  64. package/dist/drizzle/email-target.mjs +10 -10
  65. package/dist/drizzle/email-target.mjs.map +1 -1
  66. package/dist/drizzle/mysql-database.d.mts +8 -0
  67. package/dist/drizzle/mysql-database.mjs +8 -0
  68. package/dist/drizzle/mysql-database.mjs.map +1 -0
  69. package/dist/drizzle/mysql-emails.d.mts +7 -6
  70. package/dist/drizzle/mysql-emails.mjs +12 -8
  71. package/dist/drizzle/mysql-emails.mjs.map +1 -1
  72. package/dist/drizzle/mysql-identity.mjs +12 -9
  73. package/dist/drizzle/mysql-identity.mjs.map +1 -1
  74. package/dist/drizzle/mysql-password-prepared.d.mts +3 -2
  75. package/dist/drizzle/mysql-password-prepared.mjs +6 -2
  76. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
  77. package/dist/drizzle/mysql-passwords.d.mts +6 -4
  78. package/dist/drizzle/mysql-passwords.mjs +11 -7
  79. package/dist/drizzle/mysql-passwords.mjs.map +1 -1
  80. package/dist/drizzle/mysql-proofs.d.mts +3 -2
  81. package/dist/drizzle/mysql-proofs.mjs +8 -4
  82. package/dist/drizzle/mysql-proofs.mjs.map +1 -1
  83. package/dist/drizzle/mysql-sessions.d.mts +11 -10
  84. package/dist/drizzle/mysql-sessions.mjs +16 -12
  85. package/dist/drizzle/mysql-sessions.mjs.map +1 -1
  86. package/dist/drizzle/native-database.mjs +10 -0
  87. package/dist/drizzle/native-database.mjs.map +1 -0
  88. package/dist/drizzle/oauth-connected-drivers.mjs +7 -5
  89. package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
  90. package/dist/drizzle/oauth-connected-target.d.mts +6 -7
  91. package/dist/drizzle/oauth-connected-target.mjs +4 -5
  92. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  93. package/dist/drizzle/oauth-drivers.mjs +8 -6
  94. package/dist/drizzle/oauth-drivers.mjs.map +1 -1
  95. package/dist/drizzle/oauth-target.d.mts +12 -11
  96. package/dist/drizzle/oauth-target.mjs +13 -12
  97. package/dist/drizzle/oauth-target.mjs.map +1 -1
  98. package/dist/drizzle/passkey-drivers.mjs +8 -6
  99. package/dist/drizzle/passkey-drivers.mjs.map +1 -1
  100. package/dist/drizzle/passkey-write-drivers.mjs +5 -3
  101. package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
  102. package/dist/drizzle/passkey-write-target.d.mts +1 -1
  103. package/dist/drizzle/password-prepared-sql.mjs +2 -1
  104. package/dist/drizzle/password-prepared-sql.mjs.map +1 -1
  105. package/dist/drizzle/password-prepared-target.d.mts +3 -2
  106. package/dist/drizzle/password-prepared-target.mjs +4 -3
  107. package/dist/drizzle/password-prepared-target.mjs.map +1 -1
  108. package/dist/drizzle/password-registration.mjs +2 -1
  109. package/dist/drizzle/password-registration.mjs.map +1 -1
  110. package/dist/drizzle/password-target.d.mts +5 -4
  111. package/dist/drizzle/password-target.mjs +8 -8
  112. package/dist/drizzle/password-target.mjs.map +1 -1
  113. package/dist/drizzle/pg-database.d.mts +9 -0
  114. package/dist/drizzle/pg-database.mjs +8 -0
  115. package/dist/drizzle/pg-database.mjs.map +1 -0
  116. package/dist/drizzle/pg-emails.d.mts +7 -6
  117. package/dist/drizzle/pg-emails.mjs +12 -8
  118. package/dist/drizzle/pg-emails.mjs.map +1 -1
  119. package/dist/drizzle/pg-identity.mjs +12 -9
  120. package/dist/drizzle/pg-identity.mjs.map +1 -1
  121. package/dist/drizzle/pg-password-prepared.d.mts +3 -2
  122. package/dist/drizzle/pg-password-prepared.mjs +6 -2
  123. package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
  124. package/dist/drizzle/pg-passwords.d.mts +6 -4
  125. package/dist/drizzle/pg-passwords.mjs +11 -7
  126. package/dist/drizzle/pg-passwords.mjs.map +1 -1
  127. package/dist/drizzle/pg-proofs.d.mts +3 -2
  128. package/dist/drizzle/pg-proofs.mjs +8 -4
  129. package/dist/drizzle/pg-proofs.mjs.map +1 -1
  130. package/dist/drizzle/pg-sessions.d.mts +11 -10
  131. package/dist/drizzle/pg-sessions.mjs +16 -12
  132. package/dist/drizzle/pg-sessions.mjs.map +1 -1
  133. package/dist/drizzle/phone-target.d.mts +4 -3
  134. package/dist/drizzle/phone-target.mjs +12 -11
  135. package/dist/drizzle/phone-target.mjs.map +1 -1
  136. package/dist/drizzle/proof-target.d.mts +3 -2
  137. package/dist/drizzle/proof-target.mjs +5 -5
  138. package/dist/drizzle/proof-target.mjs.map +1 -1
  139. package/dist/drizzle/session-sql.d.mts +1 -0
  140. package/dist/drizzle/session-target.d.mts +10 -8
  141. package/dist/drizzle/session-target.mjs +11 -11
  142. package/dist/drizzle/session-target.mjs.map +1 -1
  143. package/dist/drizzle/sqlite-emails.mjs +9 -5
  144. package/dist/drizzle/sqlite-emails.mjs.map +1 -1
  145. package/dist/drizzle/sqlite-identity.mjs +14 -11
  146. package/dist/drizzle/sqlite-identity.mjs.map +1 -1
  147. package/dist/drizzle/sqlite-password-prepared.mjs +7 -3
  148. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
  149. package/dist/drizzle/sqlite-passwords.mjs +10 -6
  150. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  151. package/dist/drizzle/sqlite-proofs.mjs +7 -3
  152. package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
  153. package/dist/drizzle/sqlite-sessions.mjs +16 -12
  154. package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
  155. package/dist/drizzle/standalone-guard.d.mts +2 -0
  156. package/dist/drizzle/standalone-guard.mjs +8 -4
  157. package/dist/drizzle/standalone-guard.mjs.map +1 -1
  158. package/dist/drizzle/totp-target.d.mts +4 -3
  159. package/dist/drizzle/totp-target.mjs +31 -28
  160. package/dist/drizzle/totp-target.mjs.map +1 -1
  161. package/package.json +1 -1
  162. package/src/D1.ts +37 -10
  163. package/src/Libsql.ts +45 -17
  164. package/src/Mysql2.ts +39 -13
  165. package/src/Pglite.ts +47 -13
  166. package/src/Postgres.ts +47 -13
  167. package/src/SqliteBun.ts +58 -30
  168. package/src/SqliteDo.ts +61 -19
  169. package/src/SqliteNode.ts +55 -28
  170. package/src/SqliteWasm.ts +55 -28
  171. package/src/drizzle/d1-database.ts +10 -0
  172. package/src/drizzle/d1-emails.ts +84 -84
  173. package/src/drizzle/d1-identity.ts +17 -20
  174. package/src/drizzle/d1-oauth.ts +19 -8
  175. package/src/drizzle/d1-passkey.ts +5 -1
  176. package/src/drizzle/d1-password-prepared.ts +38 -37
  177. package/src/drizzle/d1-passwords.ts +74 -76
  178. package/src/drizzle/d1-phone.ts +5 -1
  179. package/src/drizzle/d1-proofs.ts +29 -30
  180. package/src/drizzle/d1-sessions.ts +51 -38
  181. package/src/drizzle/d1-totp.ts +5 -1
  182. package/src/drizzle/email-registration.ts +6 -2
  183. package/src/drizzle/email-target.ts +17 -19
  184. package/src/drizzle/mysql-database.ts +8 -0
  185. package/src/drizzle/mysql-emails.ts +28 -16
  186. package/src/drizzle/mysql-identity.ts +18 -21
  187. package/src/drizzle/mysql-password-prepared.ts +10 -8
  188. package/src/drizzle/mysql-passwords.ts +21 -9
  189. package/src/drizzle/mysql-proofs.ts +16 -5
  190. package/src/drizzle/mysql-sessions.ts +40 -17
  191. package/src/drizzle/native-database.ts +22 -0
  192. package/src/drizzle/oauth-connected-drivers.ts +18 -6
  193. package/src/drizzle/oauth-connected-target.ts +16 -17
  194. package/src/drizzle/oauth-drivers.ts +26 -10
  195. package/src/drizzle/oauth-target.ts +30 -42
  196. package/src/drizzle/passkey-drivers.ts +21 -13
  197. package/src/drizzle/passkey-write-drivers.ts +11 -6
  198. package/src/drizzle/password-prepared-sql.ts +2 -4
  199. package/src/drizzle/password-prepared-target.ts +9 -6
  200. package/src/drizzle/password-registration.ts +7 -8
  201. package/src/drizzle/password-target.ts +19 -18
  202. package/src/drizzle/pg-database.ts +10 -0
  203. package/src/drizzle/pg-emails.ts +28 -16
  204. package/src/drizzle/pg-identity.ts +18 -22
  205. package/src/drizzle/pg-password-prepared.ts +10 -8
  206. package/src/drizzle/pg-passwords.ts +21 -9
  207. package/src/drizzle/pg-proofs.ts +16 -5
  208. package/src/drizzle/pg-sessions.ts +40 -17
  209. package/src/drizzle/phone-target.ts +22 -17
  210. package/src/drizzle/proof-target.ts +9 -12
  211. package/src/drizzle/session-target.ts +32 -50
  212. package/src/drizzle/sqlite-emails.ts +30 -13
  213. package/src/drizzle/sqlite-identity.ts +22 -42
  214. package/src/drizzle/sqlite-password-prepared.ts +23 -9
  215. package/src/drizzle/sqlite-passwords.ts +29 -15
  216. package/src/drizzle/sqlite-proofs.ts +28 -5
  217. package/src/drizzle/sqlite-sessions.ts +49 -23
  218. package/src/drizzle/standalone-guard.ts +18 -6
  219. package/src/drizzle/totp-target.ts +61 -60
  220. package/dist/drizzle/d1-identity.d.mts +0 -30
  221. package/dist/drizzle/mysql-identity.d.mts +0 -21
  222. package/dist/drizzle/pg-identity.d.mts +0 -22
@@ -0,0 +1,8 @@
1
+ import type { AnyRelations } from "drizzle-orm";
2
+ import type { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
3
+ import { Context } from "effect";
4
+
5
+ /** Application-owned MySQL database used to construct persistence services. */
6
+ export class Database extends Context.Service<Database, EffectMysql2Database<AnyRelations>>()(
7
+ "effect-auth/persistence-drizzle/Mysql2/Database",
8
+ ) {}
@@ -13,6 +13,7 @@ import type {
13
13
  EmailSignInMapping,
14
14
  } from "./email-model";
15
15
  import type { EmailRegistrationAuthority } from "./email-registration";
16
+ import { CurrentEmailSql } from "./email-sql";
16
17
  import type { EmailSqlQuery } from "./email-sql";
17
18
  import {
18
19
  coordinateTargetEmailAddress,
@@ -22,9 +23,16 @@ import {
22
23
  makeTargetEmailSignInServices,
23
24
  sqlClientEmailStandaloneGuard,
24
25
  } from "./email-target";
26
+ import { Database as DatabaseService } from "./mysql-database";
27
+ import { nativeDatabase } from "./native-database";
25
28
  import type { ProofPersistenceMapping } from "./proof-model";
26
29
  import type { ProofSqlQuery } from "./proof-sql";
27
30
  import { sqlClientProofStandaloneGuard } from "./proof-target";
31
+ import {
32
+ type TransactionService,
33
+ acquireTransactionService,
34
+ transactionService,
35
+ } from "./standalone-guard";
28
36
  import type { SuppliedService } from "./SuppliedService";
29
37
 
30
38
  type Database = EffectMysql2Database<AnyRelations>;
@@ -44,15 +52,15 @@ type ProofMapping = ProofPersistenceMapping<
44
52
  any
45
53
  >;
46
54
 
47
- const configuration = (database: Database) => ({
55
+ const configuration = (service: TransactionService | undefined) => ({
48
56
  mode: "interactive" as const,
49
57
  locking: true,
50
- standaloneGuard: sqlClientEmailStandaloneGuard(database),
58
+ standaloneGuard: sqlClientEmailStandaloneGuard(service),
51
59
  generatedSubjectRows: (query: EmailSqlQuery) => query.$returningId(),
52
60
  proof: {
53
61
  mode: "interactive" as const,
54
62
  locking: true,
55
- standaloneGuard: sqlClientProofStandaloneGuard(database),
63
+ standaloneGuard: sqlClientProofStandaloneGuard(service),
56
64
  insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>
57
65
  query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),
58
66
  },
@@ -64,9 +72,12 @@ export const makeMysqlEmailSignInServices = <
64
72
  C extends AnyMySqlTable,
65
73
  NativeId,
66
74
  >(
67
- database: Database,
68
75
  mapping: EmailSignInMapping<S, I, C, NativeId>,
69
- ) => makeTargetEmailSignInServices(database, mapping, configuration(database));
76
+ ) =>
77
+ Effect.flatMap(
78
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
79
+ (configuration) => makeTargetEmailSignInServices(mapping, configuration),
80
+ ).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
70
81
 
71
82
  export const makeMysqlEmailAddressServices = <
72
83
  S extends AnyMySqlTable,
@@ -76,10 +87,13 @@ export const makeMysqlEmailAddressServices = <
76
87
  M extends AnyMySqlTable,
77
88
  NativeId,
78
89
  >(
79
- database: Database,
80
90
  mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>,
81
91
  proofMapping: ProofMapping,
82
- ) => makeTargetEmailAddressServices(database, mapping, proofMapping, configuration(database));
92
+ ) =>
93
+ Effect.flatMap(
94
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
95
+ (configuration) => makeTargetEmailAddressServices(mapping, proofMapping, configuration),
96
+ ).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
83
97
 
84
98
  export function coordinateMysqlEmailAddress<
85
99
  D extends Database,
@@ -170,7 +184,7 @@ export function coordinateMysqlEmailAddress<
170
184
  database,
171
185
  options.mapping,
172
186
  options.proofMapping,
173
- configuration(database),
187
+ configuration(transactionService(database)),
174
188
  (
175
189
  transaction: TransactionOf<D>,
176
190
  services: { readonly emailAddressPersistence: EmailAddressPersistence["Service"] },
@@ -195,16 +209,14 @@ export const makeMysqlEmailRegistrationServices = <
195
209
  Rq extends AnyMySqlTable,
196
210
  NativeId,
197
211
  >(
198
- database: Database,
199
212
  mapping: EmailRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,
200
213
  proofMapping: ProofMapping,
201
214
  ) =>
202
- makeTargetEmailRegistrationServices<Registration>(
203
- database,
204
- mapping,
205
- proofMapping,
206
- configuration(database),
207
- );
215
+ Effect.flatMap(
216
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
217
+ (configuration) =>
218
+ makeTargetEmailRegistrationServices<Registration>(mapping, proofMapping, configuration),
219
+ ).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
208
220
 
209
221
  export function coordinateMysqlEmailRegistration<
210
222
  TargetId,
@@ -304,7 +316,7 @@ export function coordinateMysqlEmailRegistration<
304
316
  database,
305
317
  options.mapping,
306
318
  options.proofMapping,
307
- configuration(database),
319
+ configuration(transactionService(database)),
308
320
  (
309
321
  transaction: TransactionOf<D>,
310
322
  services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },
@@ -10,7 +10,7 @@ import {
10
10
  import { reportPersistenceFailure } from "@yielded/auth/Persistence";
11
11
  import type { SubjectId } from "@yielded/auth/Schema";
12
12
  /* oxlint-disable no-explicit-any -- Drizzle generic query types are narrowed at this technology boundary. */
13
- import { and, eq, type AnyRelations } from "drizzle-orm";
13
+ import { and, eq } from "drizzle-orm";
14
14
  import type { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
15
15
  import type { AnyMySqlTable, MySqlColumn } from "drizzle-orm/mysql-core";
16
16
  import { Cause, Effect, Schema } from "effect";
@@ -24,8 +24,8 @@ import {
24
24
  type IdentityTables,
25
25
  type SubjectProvisioningTables,
26
26
  } from "./model";
27
+ import { Database as DatabaseService } from "./mysql-database";
27
28
 
28
- type Database = EffectMysql2Database<AnyRelations>;
29
29
  type RuntimeDatabase = EffectMysql2Database<any>;
30
30
  const unavailable = () => IdentityUnavailable.make();
31
31
  const isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));
@@ -39,15 +39,14 @@ const mapUnavailable = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
39
39
  ),
40
40
  );
41
41
 
42
- export const makeMysqlSubjectProvisioningServices = <
42
+ export const makeMysqlSubjectProvisioningServices = Effect.fnUntraced(function* <
43
43
  Subject extends AnyMySqlTable,
44
44
  Identifier extends AnyMySqlTable,
45
45
  Request extends AnyMySqlTable,
46
46
  NativeId,
47
- >(
48
- database: Database,
49
- mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>,
50
- ) => {
47
+ >(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {
48
+ const database = yield* DatabaseService;
49
+
51
50
  const db = database as RuntimeDatabase;
52
51
  const requestTable = mapping.provisioningRequest.table;
53
52
 
@@ -190,16 +189,15 @@ export const makeMysqlSubjectProvisioningServices = <
190
189
  }, mapUnavailable);
191
190
 
192
191
  return { subjectProvisioner: SubjectProvisioner.of({ provision }) } as const;
193
- };
192
+ });
194
193
 
195
- export const makeMysqlExternalIdentityServices = <
194
+ export const makeMysqlExternalIdentityServices = Effect.fnUntraced(function* <
196
195
  Subject extends AnyMySqlTable,
197
196
  External extends AnyMySqlTable,
198
197
  NativeId,
199
- >(
200
- database: Database,
201
- mapping: ExternalIdentityTables<Subject, External, NativeId>,
202
- ) => {
198
+ >(mapping: ExternalIdentityTables<Subject, External, NativeId>) {
199
+ const database = yield* DatabaseService;
200
+
203
201
  const db = database as RuntimeDatabase;
204
202
  const externalTable = mapping.externalIdentity.table;
205
203
 
@@ -307,18 +305,17 @@ export const makeMysqlExternalIdentityServices = <
307
305
  }, mapUnavailable);
308
306
 
309
307
  return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) } as const;
310
- };
308
+ });
311
309
 
312
- export const makeMysqlIdentityServices = <
310
+ export const makeMysqlIdentityServices = Effect.fnUntraced(function* <
313
311
  Subject extends AnyMySqlTable,
314
312
  Identifier extends AnyMySqlTable,
315
313
  External extends AnyMySqlTable,
316
314
  Request extends AnyMySqlTable,
317
315
  NativeId,
318
- >(
319
- database: Database,
320
- mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>,
321
- ) => ({
322
- ...makeMysqlSubjectProvisioningServices(database, mapping),
323
- ...makeMysqlExternalIdentityServices(database, mapping),
316
+ >(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {
317
+ return {
318
+ ...(yield* makeMysqlSubjectProvisioningServices(mapping)),
319
+ ...(yield* makeMysqlExternalIdentityServices(mapping)),
320
+ };
324
321
  });
@@ -6,7 +6,9 @@ import type { AnyMySqlTable } from "drizzle-orm/mysql-core";
6
6
  import { Effect, Context } from "effect";
7
7
  import type { SqlError } from "effect/sql/SqlError";
8
8
 
9
+ import { Database as DatabaseService } from "./mysql-database";
9
10
  import { mysqlPasswordConfiguration as configuration } from "./mysql-passwords";
11
+ import { nativeDatabase } from "./native-database";
10
12
  import type {
11
13
  PasswordPreparedPersistenceMapping,
12
14
  PasswordPreparedProofMapping,
@@ -15,6 +17,8 @@ import {
15
17
  makeTargetPasswordPreparedPersistenceServices,
16
18
  coordinateTargetPasswordPreparedPersistence,
17
19
  } from "./password-prepared-target";
20
+ import { CurrentPasswordSql } from "./password-sql";
21
+ import { acquireTransactionService, transactionService } from "./standalone-guard";
18
22
  import type { SuppliedService } from "./SuppliedService";
19
23
  type Database = EffectMysql2Database<AnyRelations>;
20
24
  type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
@@ -39,16 +43,14 @@ export const makeMySqlPasswordPreparedPersistenceServices = <
39
43
  PCr extends AnyMySqlTable = AnyMySqlTable,
40
44
  PNativeId = unknown,
41
45
  >(
42
- database: Database,
43
46
  mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>,
44
47
  proofMapping?: PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>,
45
48
  ) =>
46
- makeTargetPasswordPreparedPersistenceServices(
47
- database,
48
- mapping,
49
- configuration(database),
50
- proofMapping,
51
- );
49
+ Effect.flatMap(
50
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
51
+ (configuration) =>
52
+ makeTargetPasswordPreparedPersistenceServices(mapping, configuration, proofMapping),
53
+ ).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
52
54
 
53
55
  export function coordinateMySqlPasswordPreparedPersistence<
54
56
  TargetId,
@@ -186,7 +188,7 @@ export function coordinateMySqlPasswordPreparedPersistence<
186
188
  coordinateTargetPasswordPreparedPersistence<TransactionOf<D>, Out, E, Exclude<R, TargetId>>(
187
189
  database,
188
190
  options.mapping,
189
- configuration(database),
191
+ configuration(transactionService(database)),
190
192
  options.proofMapping,
191
193
  (
192
194
  transaction: TransactionOf<D>,
@@ -7,8 +7,11 @@ import type { AnyMySqlTable } from "drizzle-orm/mysql-core";
7
7
  import { Effect, Context } from "effect";
8
8
  import type { SqlError } from "effect/sql/SqlError";
9
9
 
10
+ import { Database as DatabaseService } from "./mysql-database";
11
+ import { nativeDatabase } from "./native-database";
10
12
  import type { PasswordPersistenceMapping, PasswordRegistrationMapping } from "./password-model";
11
13
  import type { PasswordRegistrationAuthority } from "./password-registration";
14
+ import { CurrentPasswordSql } from "./password-sql";
12
15
  import type { PasswordSqlQuery } from "./password-sql";
13
16
  import {
14
17
  coordinateTargetPasswordPersistence,
@@ -20,22 +23,27 @@ import {
20
23
  import type { ProofPersistenceMapping } from "./proof-model";
21
24
  import type { ProofSqlQuery } from "./proof-sql";
22
25
  import { sqlClientProofStandaloneGuard } from "./proof-target";
26
+ import {
27
+ type TransactionService,
28
+ acquireTransactionService,
29
+ transactionService,
30
+ } from "./standalone-guard";
23
31
  import type { SuppliedService } from "./SuppliedService";
24
32
 
25
33
  type Database = EffectMysql2Database<AnyRelations>;
26
34
  type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
27
35
 
28
- const configuration = (database: Database) => ({
36
+ const configuration = (service: TransactionService | undefined) => ({
29
37
  mode: "interactive" as const,
30
38
  locking: true,
31
- standaloneGuard: sqlClientPasswordStandaloneGuard(database),
39
+ standaloneGuard: sqlClientPasswordStandaloneGuard(service),
32
40
  insertIfAbsent: (query: PasswordSqlQuery, selfKey: string, selfValue: unknown) =>
33
41
  query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),
34
42
  generatedSubjectRows: (query: PasswordSqlQuery) => query.$returningId(),
35
43
  proof: {
36
44
  mode: "interactive" as const,
37
45
  locking: true,
38
- standaloneGuard: sqlClientProofStandaloneGuard(database),
46
+ standaloneGuard: sqlClientProofStandaloneGuard(service),
39
47
  insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>
40
48
  query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),
41
49
  },
@@ -64,7 +72,6 @@ export const makeMysqlPasswordPersistenceServices = <
64
72
  M extends AnyMySqlTable,
65
73
  NativeId,
66
74
  >(
67
- database: Database,
68
75
  mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>,
69
76
  proofMapping?: ProofPersistenceMapping<
70
77
  any,
@@ -81,7 +88,10 @@ export const makeMysqlPasswordPersistenceServices = <
81
88
  any
82
89
  >,
83
90
  ) =>
84
- makeTargetPasswordPersistenceServices(database, mapping, configuration(database), proofMapping);
91
+ Effect.flatMap(
92
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
93
+ (configuration) => makeTargetPasswordPersistenceServices(mapping, configuration, proofMapping),
94
+ ).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
85
95
 
86
96
  export function coordinateMysqlPasswordPersistence<
87
97
  D extends Database,
@@ -189,7 +199,7 @@ export function coordinateMysqlPasswordPersistence<
189
199
  coordinateTargetPasswordPersistence<TransactionOf<D>, Out, E, Exclude<R, PasswordPersistence>>(
190
200
  database,
191
201
  options.mapping,
192
- configuration(database),
202
+ configuration(transactionService(database)),
193
203
  options.proofMapping,
194
204
  (
195
205
  transaction: TransactionOf<D>,
@@ -215,10 +225,12 @@ export const makeMysqlPasswordRegistrationServices = <
215
225
  Rq extends AnyMySqlTable,
216
226
  NativeId,
217
227
  >(
218
- database: Database,
219
228
  mapping: PasswordRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,
220
229
  ) =>
221
- makeTargetPasswordRegistrationServices<Registration>(database, mapping, configuration(database));
230
+ Effect.flatMap(
231
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
232
+ (configuration) => makeTargetPasswordRegistrationServices<Registration>(mapping, configuration),
233
+ ).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
222
234
 
223
235
  export function coordinateMysqlPasswordRegistration<
224
236
  TargetId,
@@ -320,7 +332,7 @@ export function coordinateMysqlPasswordRegistration<
320
332
  >(
321
333
  database,
322
334
  options.mapping,
323
- configuration(database),
335
+ configuration(transactionService(database)),
324
336
  (
325
337
  transaction: TransactionOf<D>,
326
338
  services: { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },
@@ -7,13 +7,21 @@ import { Effect, Context } from "effect";
7
7
  import type { SqlError } from "effect/sql/SqlError";
8
8
 
9
9
  import { updateValues } from "./model";
10
+ import { Database as DatabaseService } from "./mysql-database";
11
+ import { nativeDatabase } from "./native-database";
10
12
  import type { ProofPersistenceMapping } from "./proof-model";
13
+ import { CurrentProofSql } from "./proof-sql";
11
14
  import type { ProofSqlQuery } from "./proof-sql";
12
15
  import {
13
16
  coordinateTargetProofPersistence,
14
17
  makeTargetProofPersistenceServices,
15
18
  sqlClientProofStandaloneGuard,
16
19
  } from "./proof-target";
20
+ import {
21
+ type TransactionService,
22
+ acquireTransactionService,
23
+ transactionService,
24
+ } from "./standalone-guard";
17
25
  import type { SuppliedService } from "./SuppliedService";
18
26
 
19
27
  type Database = EffectMysql2Database<AnyRelations>;
@@ -33,10 +41,10 @@ type Mapping<
33
41
  NativeId,
34
42
  > = ProofPersistenceMapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, NativeId>;
35
43
 
36
- const configuration = (database: Database) => ({
44
+ const configuration = (service: TransactionService | undefined) => ({
37
45
  mode: "interactive" as const,
38
46
  locking: true,
39
- standaloneGuard: sqlClientProofStandaloneGuard(database),
47
+ standaloneGuard: sqlClientProofStandaloneGuard(service),
40
48
  insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>
41
49
  query.onDuplicateKeyUpdate({
42
50
  set: updateValues([[selfKey, selfValue]]),
@@ -57,9 +65,12 @@ export const makeMysqlProofPersistenceServices = <
57
65
  Cr extends AnyMySqlTable,
58
66
  NativeId,
59
67
  >(
60
- database: Database,
61
68
  mapping: Mapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, NativeId>,
62
- ) => makeTargetProofPersistenceServices(database, mapping, configuration(database));
69
+ ) =>
70
+ Effect.flatMap(
71
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
72
+ (configuration) => makeTargetProofPersistenceServices(mapping, configuration),
73
+ ).pipe(Effect.provideServiceEffect(CurrentProofSql, nativeDatabase(DatabaseService)));
63
74
 
64
75
  export function coordinateMysqlProofPersistence<
65
76
  D extends Database,
@@ -164,7 +175,7 @@ export function coordinateMysqlProofPersistence<
164
175
  coordinateTargetProofPersistence<Transaction, A, E, Exclude<R, ProofPersistence>>(
165
176
  database,
166
177
  options.mapping,
167
- configuration(database),
178
+ configuration(transactionService(database)),
168
179
  (
169
180
  transaction: Transaction,
170
181
  services: { readonly proofPersistence: ProofPersistence["Service"] },
@@ -14,12 +14,15 @@ import type { AnyMySqlTable } from "drizzle-orm/mysql-core";
14
14
  import { Effect, Context } from "effect";
15
15
  import type { SqlError } from "effect/sql/SqlError";
16
16
 
17
+ import { Database as DatabaseService } from "./mysql-database";
18
+ import { nativeDatabase } from "./native-database";
17
19
  import type {
18
20
  AuthenticationAuthorityMapping,
19
21
  PendingAuthenticationMapping,
20
22
  SignedSessionValidityMapping,
21
23
  StatefulSessionMapping,
22
24
  } from "./session-model";
25
+ import { CurrentSessionSql } from "./session-sql";
23
26
  import {
24
27
  coordinateTargetAuthenticationAuthority,
25
28
  coordinateTargetPendingAuthentication,
@@ -33,15 +36,20 @@ import {
33
36
  makeTargetSessionStepUpServices,
34
37
  coordinateTargetSessionStepUp,
35
38
  } from "./session-target";
39
+ import {
40
+ type TransactionService,
41
+ acquireTransactionService,
42
+ transactionService,
43
+ } from "./standalone-guard";
36
44
  import type { SuppliedService } from "./SuppliedService";
37
45
 
38
46
  type Database = EffectMysql2Database<AnyRelations>;
39
47
  type Transaction = Parameters<Parameters<Database["transaction"]>[0]>[0];
40
48
 
41
- const configuration = (database: Database) => ({
49
+ const configuration = (service: TransactionService | undefined) => ({
42
50
  mode: "interactive" as const,
43
51
  locking: true,
44
- standaloneGuard: sqlClientSessionStandaloneGuard(database),
52
+ standaloneGuard: sqlClientSessionStandaloneGuard(service),
45
53
  });
46
54
 
47
55
  export const makeMysqlAuthenticationAuthorityServices = <
@@ -52,9 +60,12 @@ export const makeMysqlAuthenticationAuthorityServices = <
52
60
  P extends AnyMySqlTable,
53
61
  NativeId,
54
62
  >(
55
- database: Database,
56
63
  mapping: AuthenticationAuthorityMapping<Claims, S, C, F, P, NativeId>,
57
- ) => makeTargetAuthenticationAuthorityServices<Claims>(database, mapping, configuration(database));
64
+ ) =>
65
+ Effect.flatMap(
66
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
67
+ (configuration) => makeTargetAuthenticationAuthorityServices<Claims>(mapping, configuration),
68
+ ).pipe(Effect.provideServiceEffect(CurrentSessionSql, nativeDatabase(DatabaseService)));
58
69
 
59
70
  export const makeMysqlPendingAuthenticationServices = <
60
71
  Claims,
@@ -64,9 +75,12 @@ export const makeMysqlPendingAuthenticationServices = <
64
75
  F extends AnyMySqlTable,
65
76
  NativeId,
66
77
  >(
67
- database: Database,
68
78
  mapping: PendingAuthenticationMapping<Claims, S, C, P, F, NativeId>,
69
- ) => makeTargetPendingAuthenticationServices<Claims>(database, mapping, configuration(database));
79
+ ) =>
80
+ Effect.flatMap(
81
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
82
+ (configuration) => makeTargetPendingAuthenticationServices<Claims>(mapping, configuration),
83
+ ).pipe(Effect.provideServiceEffect(CurrentSessionSql, nativeDatabase(DatabaseService)));
70
84
 
71
85
  export const makeMysqlStatefulSessionServices = <
72
86
  Claims,
@@ -78,9 +92,12 @@ export const makeMysqlStatefulSessionServices = <
78
92
  NativeId,
79
93
  NativeSessionId,
80
94
  >(
81
- database: Database,
82
95
  mapping: StatefulSessionMapping<Claims, S, C, Session, F, P, NativeId, NativeSessionId>,
83
- ) => makeTargetStatefulSessionServices<Claims>(database, mapping, configuration(database));
96
+ ) =>
97
+ Effect.flatMap(
98
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
99
+ (configuration) => makeTargetStatefulSessionServices<Claims>(mapping, configuration),
100
+ ).pipe(Effect.provideServiceEffect(CurrentSessionSql, nativeDatabase(DatabaseService)));
84
101
 
85
102
  export const makeMysqlSignedSessionValidityServices = <
86
103
  S extends AnyMySqlTable,
@@ -88,9 +105,12 @@ export const makeMysqlSignedSessionValidityServices = <
88
105
  NativeId,
89
106
  NativeSessionId,
90
107
  >(
91
- database: Database,
92
108
  mapping: SignedSessionValidityMapping<S, T, NativeId, NativeSessionId>,
93
- ) => makeTargetSignedSessionValidityServices(database, mapping, configuration(database));
109
+ ) =>
110
+ Effect.flatMap(
111
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
112
+ (configuration) => makeTargetSignedSessionValidityServices(mapping, configuration),
113
+ ).pipe(Effect.provideServiceEffect(CurrentSessionSql, nativeDatabase(DatabaseService)));
94
114
 
95
115
  export function coordinateMysqlAuthenticationAuthority<
96
116
  D extends Database,
@@ -183,7 +203,7 @@ export function coordinateMysqlAuthenticationAuthority<
183
203
  >(
184
204
  database,
185
205
  options.mapping,
186
- configuration(database),
206
+ configuration(transactionService(database)),
187
207
  (
188
208
  transaction: Transaction,
189
209
  services: { readonly authenticationAuthority: AuthenticationAuthority["Service"] },
@@ -290,7 +310,7 @@ export function coordinateMysqlPendingAuthentication<
290
310
  coordinateTargetPendingAuthentication<Claims, Transaction, A, E, Exclude<R, TargetId>>(
291
311
  database,
292
312
  options.mapping,
293
- configuration(database),
313
+ configuration(transactionService(database)),
294
314
  (
295
315
  transaction: Transaction,
296
316
  services: { readonly pendingAuthentication: PendingAuthentication<Claims> },
@@ -442,7 +462,7 @@ export function coordinateMysqlStatefulSessions<
442
462
  >(
443
463
  database,
444
464
  options.mapping,
445
- configuration(database),
465
+ configuration(transactionService(database)),
446
466
  (
447
467
  transaction: Transaction,
448
468
  services: {
@@ -550,7 +570,7 @@ export function coordinateMysqlSignedSessionValidity<
550
570
  coordinateTargetSignedSessionValidity<Transaction, A, E, Exclude<R, TargetId>>(
551
571
  database,
552
572
  options.mapping,
553
- configuration(database),
573
+ configuration(transactionService(database)),
554
574
  (
555
575
  transaction: Transaction,
556
576
  services: { readonly signedSessionValidity: SignedSessionValidity },
@@ -579,10 +599,13 @@ export const makeMysqlSessionStepUpServices = <
579
599
  NativeId,
580
600
  NativeSessionId,
581
601
  >(
582
- database: Database,
583
602
  mapping: SessionStepUpMapping<NoInfer<Claims>, S, C, I, Session, T, NativeId, NativeSessionId>,
584
603
  target: Context.Service<Id, SessionStepUpPersistence<Claims>>,
585
- ) => makeTargetSessionStepUpServices(database, mapping, target, configuration(database));
604
+ ) =>
605
+ Effect.flatMap(
606
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
607
+ (configuration) => makeTargetSessionStepUpServices(mapping, target, configuration),
608
+ ).pipe(Effect.provideServiceEffect(CurrentSessionSql, nativeDatabase(DatabaseService)));
586
609
 
587
610
  export function coordinateMysqlSessionStepUp<
588
611
  Claims,
@@ -724,7 +747,7 @@ export function coordinateMysqlSessionStepUp<
724
747
  database,
725
748
  options.mapping,
726
749
  options.target,
727
- configuration(database),
750
+ configuration(transactionService(database)),
728
751
  (
729
752
  transaction: Parameters<Parameters<D["transaction"]>[0]>[0],
730
753
  services: { readonly sessionStepUpPersistence: SessionStepUpPersistence<Claims> },
@@ -0,0 +1,22 @@
1
+ import type {
2
+ TransactionNativeDatabase,
3
+ SessionSqlDatabase,
4
+ PasswordSqlDatabase,
5
+ EmailSqlDatabase,
6
+ ProofSqlDatabase,
7
+ } from "@yielded/auth-persistence/Adapter";
8
+ import { type Context, Effect } from "effect";
9
+
10
+ /** Drizzle omits its captured $client from database class types, and only D1
11
+ * exposes batch. Its generic query builders implement the SQL kernel contracts
12
+ * through drizzleQueryOperations. The selected driver mode controls native calls. */
13
+ export const nativeDatabase = <Id, Database>(databaseService: Context.Key<Id, Database>) =>
14
+ Effect.map(
15
+ Effect.service(databaseService),
16
+ (database) =>
17
+ database as unknown as TransactionNativeDatabase &
18
+ SessionSqlDatabase &
19
+ PasswordSqlDatabase &
20
+ EmailSqlDatabase &
21
+ ProofSqlDatabase,
22
+ );
@@ -1,3 +1,4 @@
1
+ import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
1
2
  import type { LifecycleHooks } from "@yielded/auth/Hooks";
2
3
  import {
3
4
  OAuthConnectedPersistence,
@@ -9,6 +10,7 @@ import { Effect, Context } from "effect";
9
10
 
10
11
  import { makeD1Owner } from "./d1-planning";
11
12
  import { D1BatchStatements } from "./D1BatchStatements";
13
+ import { nativeDatabase } from "./native-database";
12
14
  import type {
13
15
  OAuthConnectedMapping,
14
16
  OAuthConnectedRevocationMapping,
@@ -28,11 +30,13 @@ type TransactionOf<D> = D extends { readonly transaction: (...args: any[]) => an
28
30
  const unavailable = () => OAuthUnavailable.make({});
29
31
 
30
32
  export const makeOAuthConnectedTarget = <
33
+ DatabaseId,
31
34
  Database,
32
35
  Family extends Table,
33
36
  Extra = {},
34
37
  Synchronous extends boolean = false,
35
38
  >(
39
+ databaseService: Context.Service<DatabaseId, Database>,
36
40
  configuration: OAuthTargetConfiguration,
37
41
  ) => {
38
42
  function coordinateOAuthConnected<
@@ -300,9 +304,11 @@ export const makeOAuthConnectedTarget = <
300
304
  N,
301
305
  J extends Family = never,
302
306
  >(
303
- database: Database,
304
307
  mapping: OAuthConnectedMapping<S, AC, T, O, F, G, C, H, UA, DC, N, J> & Extra,
305
- ) => makeTargetOAuthConnectedServices(database, mapping, configuration),
308
+ ) =>
309
+ makeTargetOAuthConnectedServices(mapping, configuration).pipe(
310
+ Effect.provideServiceEffect(NativeDatabase, nativeDatabase(databaseService)),
311
+ ),
306
312
  makeOAuthConnectedRevocationServices: <
307
313
  T extends Family,
308
314
  O extends Family,
@@ -313,15 +319,18 @@ export const makeOAuthConnectedTarget = <
313
319
  J extends Family,
314
320
  N,
315
321
  >(
316
- database: Database,
317
322
  mapping: OAuthConnectedRevocationMapping<T, O, F, G, C, H, J, N> & Extra,
318
- ) => makeTargetOAuthConnectedRevocationServices(database, mapping, configuration),
323
+ ) =>
324
+ makeTargetOAuthConnectedRevocationServices(mapping, configuration).pipe(
325
+ Effect.provideServiceEffect(NativeDatabase, nativeDatabase(databaseService)),
326
+ ),
319
327
  coordinateOAuthConnected,
320
328
  coordinateOAuthConnectedRevocations,
321
329
  };
322
330
  };
323
331
 
324
- export const makeD1OAuthConnectedTarget = <Database, Family extends Table, Extra>(
332
+ export const makeD1OAuthConnectedTarget = <DatabaseId, Database, Family extends Table, Extra>(
333
+ databaseService: Context.Service<DatabaseId, Database>,
325
334
  configuration: OAuthTargetConfiguration,
326
335
  ) => {
327
336
  function coordinateOAuthConnected<
@@ -461,7 +470,10 @@ export const makeD1OAuthConnectedTarget = <Database, Family extends Table, Extra
461
470
  }
462
471
 
463
472
  return {
464
- ...makeOAuthConnectedTarget<Database, Family, Extra>(configuration),
473
+ ...makeOAuthConnectedTarget<DatabaseId, Database, Family, Extra>(
474
+ databaseService,
475
+ configuration,
476
+ ),
465
477
  coordinateOAuthConnected,
466
478
  coordinateOAuthConnectedRevocations,
467
479
  };