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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +6 -1
  2. package/dist/D1.d.mts +135 -25
  3. package/dist/D1.mjs +1 -3
  4. package/dist/D1.mjs.map +1 -1
  5. package/dist/Libsql.d.mts +192 -75
  6. package/dist/Libsql.mjs +1 -7
  7. package/dist/Libsql.mjs.map +1 -1
  8. package/dist/Mysql2.d.mts +177 -37
  9. package/dist/Mysql2.mjs +1 -3
  10. package/dist/Mysql2.mjs.map +1 -1
  11. package/dist/Pglite.d.mts +171 -30
  12. package/dist/Pglite.mjs +2 -3
  13. package/dist/Pglite.mjs.map +1 -1
  14. package/dist/Postgres.d.mts +177 -36
  15. package/dist/Postgres.mjs +2 -3
  16. package/dist/Postgres.mjs.map +1 -1
  17. package/dist/SqliteBun.d.mts +192 -74
  18. package/dist/SqliteBun.mjs +1 -5
  19. package/dist/SqliteBun.mjs.map +1 -1
  20. package/dist/SqliteDo.d.mts +194 -110
  21. package/dist/SqliteDo.mjs +2 -32
  22. package/dist/SqliteDo.mjs.map +1 -1
  23. package/dist/SqliteNode.d.mts +190 -72
  24. package/dist/SqliteNode.mjs +1 -5
  25. package/dist/SqliteNode.mjs.map +1 -1
  26. package/dist/SqliteWasm.d.mts +192 -74
  27. package/dist/SqliteWasm.mjs +1 -5
  28. package/dist/SqliteWasm.mjs.map +1 -1
  29. package/dist/drizzle/D1BatchStatements.d.mts +1 -1
  30. package/dist/drizzle/D1BatchStatements.mjs.map +1 -1
  31. package/dist/drizzle/d1-emails.mjs.map +1 -1
  32. package/dist/drizzle/d1-generated-statement.mjs.map +1 -1
  33. package/dist/drizzle/d1-identity.d.mts +1 -1
  34. package/dist/drizzle/d1-oauth.d.mts +35 -5
  35. package/dist/drizzle/d1-oauth.mjs +1 -1
  36. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  37. package/dist/drizzle/d1-passwords.d.mts +1 -1
  38. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  39. package/dist/drizzle/d1-proofs.d.mts +1 -1
  40. package/dist/drizzle/d1-proofs.mjs.map +1 -1
  41. package/dist/drizzle/d1-sessions.d.mts +3 -3
  42. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  43. package/dist/drizzle/email-registration.d.mts +1 -1
  44. package/dist/drizzle/email-target.d.mts +1 -1
  45. package/dist/drizzle/email-target.mjs.map +1 -1
  46. package/dist/drizzle/model.d.mts +2 -126
  47. package/dist/drizzle/model.mjs +2 -21
  48. package/dist/drizzle/model.mjs.map +1 -1
  49. package/dist/drizzle/mysql-emails.d.mts +1 -1
  50. package/dist/drizzle/mysql-emails.mjs.map +1 -1
  51. package/dist/drizzle/mysql-identity.d.mts +1 -1
  52. package/dist/drizzle/mysql-password-prepared.d.mts +1 -1
  53. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
  54. package/dist/drizzle/mysql-passwords.d.mts +1 -1
  55. package/dist/drizzle/mysql-passwords.mjs.map +1 -1
  56. package/dist/drizzle/mysql-proofs.d.mts +1 -1
  57. package/dist/drizzle/mysql-proofs.mjs.map +1 -1
  58. package/dist/drizzle/mysql-sessions.d.mts +1 -1
  59. package/dist/drizzle/mysql-sessions.mjs.map +1 -1
  60. package/dist/drizzle/oauth-accounts.mjs +1 -1
  61. package/dist/drizzle/oauth-connected-access.mjs +14 -12
  62. package/dist/drizzle/oauth-connected-access.mjs.map +1 -1
  63. package/dist/drizzle/oauth-connected-custody.mjs +2 -2
  64. package/dist/drizzle/oauth-connected-drivers.mjs +4 -1
  65. package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
  66. package/dist/drizzle/oauth-connected-flow.mjs +2 -2
  67. package/dist/drizzle/oauth-connected-input.mjs +14 -1
  68. package/dist/drizzle/oauth-connected-input.mjs.map +1 -1
  69. package/dist/drizzle/oauth-connected-maintenance.mjs +1 -1
  70. package/dist/drizzle/oauth-connected-management.mjs +2 -2
  71. package/dist/drizzle/oauth-connected-model.d.mts +17 -3
  72. package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
  73. package/dist/drizzle/oauth-connected-settlement.mjs +51 -41
  74. package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -1
  75. package/dist/drizzle/oauth-connected-sign-in.mjs +263 -0
  76. package/dist/drizzle/oauth-connected-sign-in.mjs.map +1 -0
  77. package/dist/drizzle/oauth-connected-state.d.mts +110 -2
  78. package/dist/drizzle/oauth-connected-state.mjs +9 -4
  79. package/dist/drizzle/oauth-connected-state.mjs.map +1 -1
  80. package/dist/drizzle/oauth-connected-target.d.mts +137 -9
  81. package/dist/drizzle/oauth-connected-target.mjs +6 -2
  82. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  83. package/dist/drizzle/oauth-drivers.mjs +1 -1
  84. package/dist/drizzle/oauth-flow.d.mts +1 -1
  85. package/dist/drizzle/oauth-flow.mjs +1 -1
  86. package/dist/drizzle/oauth-input.mjs +1 -1
  87. package/dist/drizzle/oauth-model.d.mts +1 -1
  88. package/dist/drizzle/oauth-owner.d.mts +1 -1
  89. package/dist/drizzle/oauth-registration.d.mts +2 -2
  90. package/dist/drizzle/oauth-registration.mjs +1 -1
  91. package/dist/drizzle/oauth-state.mjs +5 -4
  92. package/dist/drizzle/oauth-state.mjs.map +1 -1
  93. package/dist/drizzle/oauth-target.d.mts +2 -2
  94. package/dist/drizzle/oauth-target.mjs +1 -1
  95. package/dist/drizzle/oauth-target.mjs.map +1 -1
  96. package/dist/drizzle/passkey-write-target.d.mts +1 -1
  97. package/dist/drizzle/password-prepared-state.mjs +1 -1
  98. package/dist/drizzle/password-prepared-target.d.mts +1 -1
  99. package/dist/drizzle/password-prepared-target.mjs.map +1 -1
  100. package/dist/drizzle/password-target.d.mts +1 -1
  101. package/dist/drizzle/password-target.mjs.map +1 -1
  102. package/dist/drizzle/pg-emails.d.mts +1 -1
  103. package/dist/drizzle/pg-emails.mjs.map +1 -1
  104. package/dist/drizzle/pg-identity.d.mts +22 -0
  105. package/dist/drizzle/pg-identity.mjs +89 -0
  106. package/dist/drizzle/pg-identity.mjs.map +1 -0
  107. package/dist/drizzle/pg-password-prepared.d.mts +1 -1
  108. package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
  109. package/dist/drizzle/pg-passwords.d.mts +1 -1
  110. package/dist/drizzle/pg-passwords.mjs.map +1 -1
  111. package/dist/drizzle/pg-proofs.d.mts +1 -1
  112. package/dist/drizzle/pg-proofs.mjs.map +1 -1
  113. package/dist/drizzle/pg-sessions.d.mts +1 -1
  114. package/dist/drizzle/pg-sessions.mjs.map +1 -1
  115. package/dist/drizzle/phone-model.d.mts +1 -1
  116. package/dist/drizzle/phone-target.d.mts +1 -1
  117. package/dist/drizzle/phone-target.mjs.map +1 -1
  118. package/dist/drizzle/proof-target.d.mts +1 -1
  119. package/dist/drizzle/proof-target.mjs.map +1 -1
  120. package/dist/drizzle/session-target.d.mts +1 -1
  121. package/dist/drizzle/session-target.mjs.map +1 -1
  122. package/dist/drizzle/sqlite-emails.mjs.map +1 -1
  123. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
  124. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  125. package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
  126. package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
  127. package/dist/drizzle/standalone-guard.mjs.map +1 -1
  128. package/dist/drizzle/totp-model.d.mts +1 -1
  129. package/dist/drizzle/totp-target.d.mts +1 -1
  130. package/dist/drizzle/totp-target.mjs.map +1 -1
  131. package/dist/drizzle/transaction-mysql.mjs +1 -1
  132. package/dist/drizzle/transaction-mysql.mjs.map +1 -1
  133. package/dist/index.d.mts +2 -4
  134. package/dist/index.mjs +2 -4
  135. package/dist/internal/drizzle-postgres.mjs.map +1 -1
  136. package/dist/internal/drizzle-sqlite.mjs.map +1 -1
  137. package/package.json +1 -1
  138. package/src/D1.ts +1 -17
  139. package/src/Libsql.ts +0 -44
  140. package/src/Mysql2.ts +1 -23
  141. package/src/Pglite.ts +2 -18
  142. package/src/Postgres.ts +2 -18
  143. package/src/SqliteBun.ts +1 -38
  144. package/src/SqliteDo.ts +1 -256
  145. package/src/SqliteNode.ts +1 -38
  146. package/src/SqliteWasm.ts +1 -38
  147. package/src/drizzle/D1BatchStatements.ts +1 -1
  148. package/src/drizzle/d1-emails.ts +2 -4
  149. package/src/drizzle/d1-generated-statement.ts +1 -1
  150. package/src/drizzle/d1-password-prepared.ts +2 -5
  151. package/src/drizzle/d1-passwords.ts +2 -4
  152. package/src/drizzle/d1-proofs.ts +2 -4
  153. package/src/drizzle/d1-sessions.ts +2 -2
  154. package/src/drizzle/email-target.ts +1 -1
  155. package/src/drizzle/model.ts +1 -208
  156. package/src/drizzle/mysql-emails.ts +1 -1
  157. package/src/drizzle/mysql-password-prepared.ts +1 -1
  158. package/src/drizzle/mysql-passwords.ts +1 -1
  159. package/src/drizzle/mysql-proofs.ts +1 -1
  160. package/src/drizzle/mysql-sessions.ts +1 -1
  161. package/src/drizzle/oauth-connected-access.ts +8 -1
  162. package/src/drizzle/oauth-connected-drivers.ts +3 -0
  163. package/src/drizzle/oauth-connected-input.ts +13 -0
  164. package/src/drizzle/oauth-connected-model.ts +17 -0
  165. package/src/drizzle/oauth-connected-settlement.ts +65 -42
  166. package/src/drizzle/oauth-connected-sign-in.ts +438 -0
  167. package/src/drizzle/oauth-connected-state.ts +19 -7
  168. package/src/drizzle/oauth-connected-target.ts +10 -1
  169. package/src/drizzle/oauth-state.ts +5 -4
  170. package/src/drizzle/oauth-target.ts +1 -1
  171. package/src/drizzle/password-prepared-target.ts +1 -1
  172. package/src/drizzle/password-target.ts +1 -1
  173. package/src/drizzle/pg-emails.ts +1 -1
  174. package/src/drizzle/pg-identity.ts +301 -0
  175. package/src/drizzle/pg-password-prepared.ts +1 -1
  176. package/src/drizzle/pg-passwords.ts +1 -1
  177. package/src/drizzle/pg-proofs.ts +1 -1
  178. package/src/drizzle/pg-sessions.ts +1 -1
  179. package/src/drizzle/phone-target.ts +1 -1
  180. package/src/drizzle/proof-target.ts +1 -1
  181. package/src/drizzle/session-target.ts +1 -1
  182. package/src/drizzle/sqlite-emails.ts +1 -1
  183. package/src/drizzle/sqlite-password-prepared.ts +1 -1
  184. package/src/drizzle/sqlite-passwords.ts +1 -1
  185. package/src/drizzle/sqlite-proofs.ts +1 -1
  186. package/src/drizzle/sqlite-sessions.ts +1 -1
  187. package/src/drizzle/standalone-guard.ts +1 -1
  188. package/src/drizzle/totp-target.ts +1 -1
  189. package/src/drizzle/transaction-mysql.ts +1 -1
  190. package/src/index.ts +0 -24
  191. package/src/internal/drizzle-postgres.ts +1 -1
  192. package/src/internal/drizzle-sqlite.ts +1 -1
  193. package/dist/drizzle/mysql.d.mts +0 -69
  194. package/dist/drizzle/mysql.mjs +0 -218
  195. package/dist/drizzle/mysql.mjs.map +0 -1
  196. package/dist/drizzle/pg.d.mts +0 -80
  197. package/dist/drizzle/pg.mjs +0 -289
  198. package/dist/drizzle/pg.mjs.map +0 -1
  199. package/dist/drizzle/sqlite.d.mts +0 -77
  200. package/dist/drizzle/sqlite.mjs +0 -217
  201. package/dist/drizzle/sqlite.mjs.map +0 -1
  202. package/src/drizzle/mysql.ts +0 -687
  203. package/src/drizzle/pg.ts +0 -984
  204. package/src/drizzle/sqlite.ts +0 -705
@@ -1,217 +0,0 @@
1
- import { column, requireStandaloneConsume, updateValues } from "./model.mjs";
2
- import { AuthStore, EmailOtpRejected } from "@yielded/auth/AuthStore";
3
- import { AuthRateLimited, AuthStoreError, InvalidRegistration } from "@yielded/auth/Errors";
4
- import { InvalidOAuthState, OAuthStateDecisions, OAuthStateStore } from "@yielded/auth/OAuth";
5
- import { VerifiedEmail } from "@yielded/auth/Schema";
6
- import { and, eq, gt, lt, lte, ne, or, sql } from "drizzle-orm";
7
- import { Cause, Context, DateTime, Duration, Effect, Schema } from "effect";
8
- import { AuthStoreDecisions, reportPersistenceFailure } from "@yielded/auth/Persistence";
9
- //#region src/drizzle/sqlite.ts
10
- const storeReadError = () => AuthStoreError.make({ message: "Auth store read failed" });
11
- const storeWriteError = () => AuthStoreError.make({ message: "Auth store write failed" });
12
- const isStoreFailure = Schema.is(AuthStoreError);
13
- const mapStoreFailure = (failure) => (effect) => reportPersistenceFailure(effect, isStoreFailure).pipe(Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, failure))));
14
- const mapStoreReadFailure = mapStoreFailure(storeReadError);
15
- const mapStoreWriteFailure = mapStoreFailure(storeWriteError);
16
- const selected = (row) => row;
17
- /**
18
- * Shared SQLite semantics for libSQL, Node, Bun, WASM, Durable Objects and D1.
19
- * Every mutation here is one conditional statement, so D1 never reaches its
20
- * unsupported interactive transaction and Durable Objects never suspend in a
21
- * transactionSync callback.
22
- */
23
- const makeSqliteAuthStoreServices = (database, mapping, standaloneGuard) => {
24
- const db = database;
25
- const requireStandalone = standaloneGuard ?? Effect.suspend(() => db.$client === void 0 ? AuthStoreError.make({ message: "Use a root auth store or its decision transaction API" }) : requireStandaloneConsume({ $client: db.$client }));
26
- const challengeTable = mapping.challenge.table;
27
- const challengeColumns = mapping.challenge.columns;
28
- const challenge = {
29
- challengeId: column(challengeTable, challengeColumns.challengeId),
30
- tokenDigest: column(challengeTable, challengeColumns.tokenDigest),
31
- namespace: column(challengeTable, challengeColumns.namespace),
32
- value: column(challengeTable, challengeColumns.value),
33
- purpose: column(challengeTable, challengeColumns.purpose),
34
- otpKeyId: column(challengeTable, challengeColumns.otpKeyId),
35
- otpDigest: column(challengeTable, challengeColumns.otpDigest),
36
- issuedAt: column(challengeTable, challengeColumns.issuedAt),
37
- expiresAt: column(challengeTable, challengeColumns.expiresAt),
38
- attemptLimit: column(challengeTable, challengeColumns.attemptLimit),
39
- failedAttempts: column(challengeTable, challengeColumns.failedAttempts),
40
- consumed: column(challengeTable, challengeColumns.consumed)
41
- };
42
- const registrationTable = mapping.registration.table;
43
- const registrationColumns = mapping.registration.columns;
44
- const registration = {
45
- tokenDigest: column(registrationTable, registrationColumns.tokenDigest),
46
- expiresAt: column(registrationTable, registrationColumns.expiresAt),
47
- consumed: column(registrationTable, registrationColumns.consumed)
48
- };
49
- const issueChallenge = Effect.fn("DrizzleSqliteAuthStore.issueChallenge")(function* (input) {
50
- const now = yield* DateTime.now;
51
- const cooldownCutoff = DateTime.mapEpochMillis(now, (millis) => millis - Duration.toMillis(input.resendCooldown));
52
- if ((yield* Effect.suspend(() => {
53
- const values = mapping.challenge.encodeInsert(input, {
54
- namespace: mapping.challenge.identifierNamespace,
55
- failedAttempts: 0,
56
- consumed: false
57
- });
58
- const nativeNow = mapping.challenge.encodeInstant(now);
59
- const nativeCutoff = mapping.challenge.encodeInstant(cooldownCutoff);
60
- const nativeIssuedAt = mapping.challenge.encodeInstant(input.issuedAt);
61
- const preservedAttempts = sql`case when ${gt(challenge.expiresAt, nativeNow)} then ${challenge.failedAttempts} else 0 end`;
62
- const update = mapping.challenge.encodeUpdate(input, {
63
- namespace: mapping.challenge.identifierNamespace,
64
- failedAttempts: preservedAttempts,
65
- consumed: false
66
- });
67
- return db.insert(challengeTable).values(values).onConflictDoUpdate({
68
- target: [
69
- challenge.namespace,
70
- challenge.value,
71
- challenge.purpose
72
- ],
73
- set: update,
74
- setWhere: and(ne(challenge.challengeId, input.challengeId), lt(challenge.issuedAt, nativeIssuedAt), or(eq(challenge.consumed, true), lte(challenge.issuedAt, nativeCutoff)))
75
- }).returning();
76
- }).pipe(mapStoreWriteFailure)).length > 0) return;
77
- const existing = yield* Effect.suspend(() => db.select().from(challengeTable).where(and(eq(challenge.namespace, mapping.challenge.identifierNamespace), eq(challenge.value, input.email), eq(challenge.purpose, input.purpose))).limit(1)).pipe(mapStoreReadFailure);
78
- const decoded = existing[0] === void 0 ? void 0 : yield* Effect.suspend(() => mapping.challenge.decode(selected(existing[0]))).pipe(mapStoreReadFailure);
79
- const retryAfterSeconds = decoded === void 0 ? Math.max(1, Math.ceil(Duration.toMillis(input.resendCooldown) / 1e3)) : Math.max(1, Math.ceil((DateTime.toEpochMillis(decoded.challenge.issuedAt) + Duration.toMillis(input.resendCooldown) - DateTime.toEpochMillis(now)) / 1e3));
80
- return yield* AuthRateLimited.make({ retryAfterSeconds });
81
- });
82
- const consumeChallengeDecision = Effect.fn("DrizzleSqliteAuthStore.consumeChallengeDecision")(function* (input) {
83
- const now = yield* DateTime.now;
84
- const alternatives = Object.entries(input.otpDigests).map(([keyId, digest]) => and(eq(challenge.otpKeyId, keyId), eq(challenge.otpDigest, digest)));
85
- const matches = alternatives.length === 0 ? sql`false` : or(...alternatives);
86
- const rows = yield* Effect.suspend(() => db.update(challengeTable).set(updateValues([[challengeColumns.consumed, sql`case when ${matches} then true else ${challenge.consumed} end`], [challengeColumns.failedAttempts, sql`${challenge.failedAttempts} + case when ${matches} then 0 else 1 end`]])).where(and(eq(challenge.tokenDigest, input.tokenDigest), eq(challenge.consumed, false), gt(challenge.expiresAt, mapping.challenge.encodeInstant(now)), sql`${challenge.failedAttempts} < ${challenge.attemptLimit}`)).returning()).pipe(mapStoreWriteFailure);
87
- if (rows[0] === void 0) return {
88
- _tag: "rejected",
89
- reason: "missing_challenge"
90
- };
91
- const decoded = yield* Effect.suspend(() => mapping.challenge.decode(selected(rows[0]))).pipe(mapStoreReadFailure);
92
- if (!decoded.consumed) return {
93
- _tag: "rejected",
94
- reason: "bad_code"
95
- };
96
- return {
97
- _tag: "accepted",
98
- value: VerifiedEmail.make({
99
- email: decoded.challenge.email,
100
- purpose: decoded.challenge.purpose
101
- })
102
- };
103
- });
104
- const consumeChallenge = Effect.fn("DrizzleSqliteAuthStore.consumeChallenge")(function* (input) {
105
- yield* requireStandalone;
106
- const decision = yield* consumeChallengeDecision(input);
107
- return decision._tag === "accepted" ? decision.value : yield* EmailOtpRejected.make({ reason: decision.reason });
108
- });
109
- const issueRegistration = Effect.fn("DrizzleSqliteAuthStore.issueRegistration")(function* (input) {
110
- yield* Effect.suspend(() => db.insert(registrationTable).values(mapping.registration.encodeInsert(input, false))).pipe(mapStoreWriteFailure);
111
- });
112
- const inspectRegistration = Effect.fn("DrizzleSqliteAuthStore.inspectRegistration")(function* (tokenDigest) {
113
- const now = yield* DateTime.now;
114
- const rows = yield* Effect.suspend(() => db.select().from(registrationTable).where(and(eq(registration.tokenDigest, tokenDigest), eq(registration.consumed, false), gt(registration.expiresAt, mapping.registration.encodeInstant(now)))).limit(1)).pipe(mapStoreReadFailure);
115
- if (rows[0] === void 0) return yield* InvalidRegistration.make();
116
- return (yield* Effect.suspend(() => mapping.registration.decode(selected(rows[0]))).pipe(mapStoreReadFailure)).registration;
117
- });
118
- const consumeRegistrationDecision = Effect.fn("DrizzleSqliteAuthStore.consumeRegistrationDecision")(function* (input) {
119
- const now = yield* DateTime.now;
120
- return (yield* Effect.suspend(() => db.update(registrationTable).set(updateValues([[registrationColumns.consumed, true]])).where(and(eq(registration.tokenDigest, input.tokenDigest), eq(registration.consumed, false), gt(registration.expiresAt, mapping.registration.encodeInstant(now)))).returning({ consumed: registration.consumed })).pipe(mapStoreWriteFailure)).length === 0 ? { _tag: "rejected" } : {
121
- _tag: "accepted",
122
- value: void 0
123
- };
124
- });
125
- const consumeRegistration = Effect.fn("DrizzleSqliteAuthStore.consumeRegistration")(function* (input) {
126
- yield* requireStandalone;
127
- if ((yield* consumeRegistrationDecision(input))._tag === "rejected") return yield* InvalidRegistration.make();
128
- });
129
- return {
130
- authStore: AuthStore.of({
131
- issueChallenge,
132
- consumeChallenge,
133
- issueRegistration,
134
- inspectRegistration,
135
- consumeRegistration
136
- }),
137
- decisions: {
138
- consumeChallenge: consumeChallengeDecision,
139
- consumeRegistration: consumeRegistrationDecision
140
- }
141
- };
142
- };
143
- const makeSqliteOAuthStateServices = (database, mapping, standaloneGuard) => {
144
- const db = database;
145
- const requireStandalone = standaloneGuard ?? Effect.suspend(() => db.$client === void 0 ? AuthStoreError.make({ message: "Use a root auth store or its decision transaction API" }) : requireStandaloneConsume({ $client: db.$client }));
146
- const stateTable = mapping.oauthState.table;
147
- const stateColumns = mapping.oauthState.columns;
148
- const state = {
149
- stateDigest: column(stateTable, stateColumns.stateDigest),
150
- expiresAt: column(stateTable, stateColumns.expiresAt),
151
- consumed: column(stateTable, stateColumns.consumed)
152
- };
153
- const issue = Effect.fn("DrizzleSqliteOAuthStateStore.issue")(function* (input) {
154
- yield* Effect.suspend(() => db.insert(stateTable).values(mapping.oauthState.encodeInsert(input, false))).pipe(mapStoreWriteFailure);
155
- });
156
- const consumeDecision = Effect.fn("DrizzleSqliteOAuthStateStore.consumeDecision")(function* (digest) {
157
- const now = yield* DateTime.now;
158
- const rows = yield* Effect.suspend(() => db.update(stateTable).set(updateValues([[stateColumns.consumed, true]])).where(and(eq(state.stateDigest, digest), eq(state.consumed, false), gt(state.expiresAt, mapping.oauthState.encodeInstant(now)))).returning()).pipe(mapStoreWriteFailure);
159
- if (rows[0] === void 0) return { _tag: "rejected" };
160
- return {
161
- _tag: "accepted",
162
- value: (yield* Effect.suspend(() => mapping.oauthState.decode(selected(rows[0]))).pipe(mapStoreReadFailure)).state
163
- };
164
- });
165
- const consume = Effect.fn("DrizzleSqliteOAuthStateStore.consume")(function* (digest) {
166
- yield* requireStandalone;
167
- const decision = yield* consumeDecision(digest);
168
- return decision._tag === "accepted" ? decision.value : yield* InvalidOAuthState.make();
169
- });
170
- return {
171
- oauthStateStore: OAuthStateStore.of({
172
- issue,
173
- consume
174
- }),
175
- decisions: { consumeOAuthState: consumeDecision }
176
- };
177
- };
178
- const makeSqliteAuthServices = (database, mapping, standaloneGuard) => {
179
- const auth = makeSqliteAuthStoreServices(database, mapping, standaloneGuard);
180
- const oauth = makeSqliteOAuthStateServices(database, mapping, standaloneGuard);
181
- return {
182
- ...auth,
183
- ...oauth,
184
- decisions: {
185
- ...auth.decisions,
186
- ...oauth.decisions
187
- }
188
- };
189
- };
190
- function coordinateSqliteAuthStoreTransaction(acquire, options, body) {
191
- return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
192
- const decisions = makeSqliteAuthStoreServices(transaction, options.mapping).decisions;
193
- const provided = Context.make(AuthStoreDecisions, decisions);
194
- const work = Effect.provideContext(body, provided);
195
- return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
196
- }));
197
- }
198
- function coordinateSqliteOAuthStateTransaction(acquire, options, body) {
199
- return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
200
- const decisions = makeSqliteOAuthStateServices(transaction, options.mapping).decisions;
201
- const provided = Context.make(OAuthStateDecisions, decisions);
202
- const work = Effect.provideContext(body, provided);
203
- return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
204
- }));
205
- }
206
- function coordinateSqliteAuthTransaction(acquire, options, body) {
207
- return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
208
- const decisions = makeSqliteAuthServices(transaction, options.mapping).decisions;
209
- const provided = Context.make(AuthStoreDecisions, decisions).pipe(Context.add(OAuthStateDecisions, decisions));
210
- const work = Effect.provideContext(body, provided);
211
- return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
212
- }));
213
- }
214
- //#endregion
215
- export { coordinateSqliteAuthStoreTransaction, coordinateSqliteAuthTransaction, coordinateSqliteOAuthStateTransaction, makeSqliteAuthServices, makeSqliteAuthStoreServices, makeSqliteOAuthStateServices };
216
-
217
- //# sourceMappingURL=sqlite.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqlite.mjs","names":[],"sources":["../../src/drizzle/sqlite.ts"],"sourcesContent":["import { AuthStore, EmailOtpRejected } from \"@yielded/auth/AuthStore\";\nimport { AuthRateLimited, AuthStoreError, InvalidRegistration } from \"@yielded/auth/Errors\";\nimport {\n InvalidOAuthState,\n OAuthStateDecisions,\n OAuthStateStore,\n type OAuthState,\n} from \"@yielded/auth/OAuth\";\nimport { AuthStoreDecisions, reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport {\n VerifiedEmail,\n type ConsumeChallenge,\n type ConsumeRegistration,\n type NewChallenge,\n type NewRegistration,\n type TokenDigest,\n} from \"@yielded/auth/Schema\";\n/* oxlint-disable no-explicit-any -- Drizzle's generic query builders lose the concrete consumer table through a runtime column map. Assertions stay in this adapter. */\nimport {\n and,\n eq,\n gt,\n lt,\n lte,\n ne,\n or,\n sql,\n type AnyRelations,\n type InferSelectModel,\n} from \"drizzle-orm\";\nimport type { QueryEffectHKTBase } from \"drizzle-orm/effect-core\";\nimport type { SQLiteColumn, AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport type { SQLiteEffectDatabase } from \"drizzle-orm/sqlite-core/effect/db\";\nimport { Cause, Context, DateTime, Duration, Effect, Schema } from \"effect\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport {\n column,\n requireStandaloneConsume,\n updateValues,\n type AuthTables,\n type AuthStoreTables,\n type ChallengeConsumeDecision,\n type ConsumeDecision,\n type OAuthStateTables,\n} from \"./model\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype AnyDatabase = SQLiteEffectDatabase<any, any, AnyRelations>;\ntype ClosedQueryEffectHKT = QueryEffectHKTBase & { readonly context: never };\ntype RuntimeDatabase<HKT extends ClosedQueryEffectHKT, RunResult> = SQLiteEffectDatabase<\n HKT,\n RunResult,\n AnyRelations\n> &\n Partial<Parameters<typeof requireStandaloneConsume>[0]>;\ntype TransactionOf<D extends AnyDatabase> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nconst storeReadError = () => AuthStoreError.make({ message: \"Auth store read failed\" });\nconst storeWriteError = () => AuthStoreError.make({ message: \"Auth store write failed\" });\nconst isStoreFailure = Schema.is(AuthStoreError);\n\nconst mapStoreFailure =\n (failure: () => AuthStoreError) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, AuthStoreError, R> =>\n reportPersistenceFailure(effect, isStoreFailure).pipe(\n Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, failure))),\n );\n\nconst mapStoreReadFailure = mapStoreFailure(storeReadError);\nconst mapStoreWriteFailure = mapStoreFailure(storeWriteError);\n\nconst selected = <T extends AnySQLiteTable>(row: unknown): InferSelectModel<T> =>\n row as InferSelectModel<T>;\n\n/**\n * Shared SQLite semantics for libSQL, Node, Bun, WASM, Durable Objects and D1.\n * Every mutation here is one conditional statement, so D1 never reaches its\n * unsupported interactive transaction and Durable Objects never suspend in a\n * transactionSync callback.\n */\nexport const makeSqliteAuthStoreServices = <\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n HKT extends ClosedQueryEffectHKT = ClosedQueryEffectHKT,\n RunResult = unknown,\n>(\n database: SQLiteEffectDatabase<HKT, RunResult, AnyRelations>,\n mapping: AuthStoreTables<C, R>,\n standaloneGuard?: Effect.Effect<void, AuthStoreError>,\n) => {\n const db = database as RuntimeDatabase<HKT, RunResult>;\n\n const requireStandalone =\n standaloneGuard ??\n Effect.suspend(() =>\n db.$client === undefined\n ? AuthStoreError.make({ message: \"Use a root auth store or its decision transaction API\" })\n : requireStandaloneConsume({ $client: db.$client }),\n );\n\n const challengeTable = mapping.challenge.table;\n const challengeColumns = mapping.challenge.columns;\n\n const challenge = {\n challengeId: column(challengeTable, challengeColumns.challengeId),\n tokenDigest: column(challengeTable, challengeColumns.tokenDigest),\n namespace: column(challengeTable, challengeColumns.namespace),\n value: column(challengeTable, challengeColumns.value),\n purpose: column(challengeTable, challengeColumns.purpose),\n otpKeyId: column(challengeTable, challengeColumns.otpKeyId),\n otpDigest: column(challengeTable, challengeColumns.otpDigest),\n issuedAt: column(challengeTable, challengeColumns.issuedAt),\n expiresAt: column(challengeTable, challengeColumns.expiresAt),\n attemptLimit: column(challengeTable, challengeColumns.attemptLimit),\n failedAttempts: column(challengeTable, challengeColumns.failedAttempts),\n consumed: column(challengeTable, challengeColumns.consumed),\n } as Record<string, SQLiteColumn>;\n\n const registrationTable = mapping.registration.table;\n const registrationColumns = mapping.registration.columns;\n\n const registration = {\n tokenDigest: column(registrationTable, registrationColumns.tokenDigest),\n expiresAt: column(registrationTable, registrationColumns.expiresAt),\n consumed: column(registrationTable, registrationColumns.consumed),\n } as Record<string, SQLiteColumn>;\n\n const issueChallenge = Effect.fn(\"DrizzleSqliteAuthStore.issueChallenge\")(function* (\n input: NewChallenge,\n ) {\n const now = yield* DateTime.now;\n\n const cooldownCutoff = DateTime.mapEpochMillis(\n now,\n (millis) => millis - Duration.toMillis(input.resendCooldown),\n );\n\n const rows = (yield* Effect.suspend(() => {\n const values = mapping.challenge.encodeInsert(input, {\n namespace: mapping.challenge.identifierNamespace,\n failedAttempts: 0,\n consumed: false,\n });\n\n const nativeNow = mapping.challenge.encodeInstant(now);\n const nativeCutoff = mapping.challenge.encodeInstant(cooldownCutoff);\n const nativeIssuedAt = mapping.challenge.encodeInstant(input.issuedAt);\n const preservedAttempts = sql`case when ${gt(challenge.expiresAt, nativeNow)} then ${challenge.failedAttempts} else 0 end`;\n\n const update = mapping.challenge.encodeUpdate(input, {\n namespace: mapping.challenge.identifierNamespace,\n failedAttempts: preservedAttempts as any,\n consumed: false,\n });\n\n return db\n .insert(challengeTable as any)\n .values(values as any)\n .onConflictDoUpdate({\n target: [challenge.namespace, challenge.value, challenge.purpose],\n set: update as any,\n setWhere: and(\n ne(challenge.challengeId, input.challengeId),\n lt(challenge.issuedAt, nativeIssuedAt),\n or(eq(challenge.consumed, true), lte(challenge.issuedAt, nativeCutoff)),\n ),\n })\n .returning();\n }).pipe(mapStoreWriteFailure)) as ReadonlyArray<unknown>;\n\n if (rows.length > 0) return;\n\n const existing = (yield* Effect.suspend(() =>\n db\n .select()\n .from(challengeTable as any)\n .where(\n and(\n eq(challenge.namespace, mapping.challenge.identifierNamespace),\n eq(challenge.value, input.email),\n eq(challenge.purpose, input.purpose),\n ),\n )\n .limit(1),\n ).pipe(mapStoreReadFailure)) as ReadonlyArray<unknown>;\n\n const decoded =\n existing[0] === undefined\n ? undefined\n : yield* Effect.suspend(() => mapping.challenge.decode(selected<C>(existing[0]))).pipe(\n mapStoreReadFailure,\n );\n\n const retryAfterSeconds =\n decoded === undefined\n ? Math.max(1, Math.ceil(Duration.toMillis(input.resendCooldown) / 1000))\n : Math.max(\n 1,\n Math.ceil(\n (DateTime.toEpochMillis(decoded.challenge.issuedAt) +\n Duration.toMillis(input.resendCooldown) -\n DateTime.toEpochMillis(now)) /\n 1000,\n ),\n );\n\n return yield* AuthRateLimited.make({ retryAfterSeconds });\n });\n\n const consumeChallengeDecision = Effect.fn(\"DrizzleSqliteAuthStore.consumeChallengeDecision\")(\n function* (\n input: ConsumeChallenge,\n ): Effect.fn.Return<ChallengeConsumeDecision, AuthStoreError> {\n const now = yield* DateTime.now;\n\n const alternatives = Object.entries(input.otpDigests).map(([keyId, digest]) =>\n and(eq(challenge.otpKeyId, keyId), eq(challenge.otpDigest, digest)),\n );\n\n const matches = alternatives.length === 0 ? sql<boolean>`false` : or(...alternatives)!;\n\n const rows = (yield* Effect.suspend(() =>\n db\n .update(challengeTable as any)\n .set(\n updateValues<C>([\n [\n challengeColumns.consumed,\n sql`case when ${matches} then true else ${challenge.consumed} end`,\n ],\n [\n challengeColumns.failedAttempts,\n sql`${challenge.failedAttempts} + case when ${matches} then 0 else 1 end`,\n ],\n ]) as any,\n )\n .where(\n and(\n eq(challenge.tokenDigest, input.tokenDigest),\n eq(challenge.consumed, false),\n gt(challenge.expiresAt, mapping.challenge.encodeInstant(now)),\n sql`${challenge.failedAttempts} < ${challenge.attemptLimit}`,\n ),\n )\n .returning(),\n ).pipe(mapStoreWriteFailure)) as ReadonlyArray<unknown>;\n\n if (rows[0] === undefined) {\n return { _tag: \"rejected\", reason: \"missing_challenge\" };\n }\n\n const decoded = yield* Effect.suspend(() =>\n mapping.challenge.decode(selected<C>(rows[0])),\n ).pipe(mapStoreReadFailure);\n\n if (!decoded.consumed) return { _tag: \"rejected\", reason: \"bad_code\" };\n\n return {\n _tag: \"accepted\",\n value: VerifiedEmail.make({\n email: decoded.challenge.email,\n purpose: decoded.challenge.purpose,\n }),\n };\n },\n );\n\n const consumeChallenge = Effect.fn(\"DrizzleSqliteAuthStore.consumeChallenge\")(function* (\n input: ConsumeChallenge,\n ) {\n yield* requireStandalone;\n const decision = yield* consumeChallengeDecision(input);\n\n return decision._tag === \"accepted\"\n ? decision.value\n : yield* EmailOtpRejected.make({ reason: decision.reason });\n });\n\n const issueRegistration = Effect.fn(\"DrizzleSqliteAuthStore.issueRegistration\")(function* (\n input: NewRegistration,\n ) {\n yield* Effect.suspend(() =>\n db\n .insert(registrationTable as any)\n .values(mapping.registration.encodeInsert(input, false) as any),\n ).pipe(mapStoreWriteFailure);\n });\n\n const inspectRegistration = Effect.fn(\"DrizzleSqliteAuthStore.inspectRegistration\")(function* (\n tokenDigest: TokenDigest,\n ) {\n const now = yield* DateTime.now;\n\n const rows = (yield* Effect.suspend(() =>\n db\n .select()\n .from(registrationTable as any)\n .where(\n and(\n eq(registration.tokenDigest, tokenDigest),\n eq(registration.consumed, false),\n gt(registration.expiresAt, mapping.registration.encodeInstant(now)),\n ),\n )\n .limit(1),\n ).pipe(mapStoreReadFailure)) as ReadonlyArray<unknown>;\n\n if (rows[0] === undefined) return yield* InvalidRegistration.make();\n\n const decoded = yield* Effect.suspend(() =>\n mapping.registration.decode(selected<R>(rows[0])),\n ).pipe(mapStoreReadFailure);\n\n return decoded.registration;\n });\n\n const consumeRegistrationDecision = Effect.fn(\n \"DrizzleSqliteAuthStore.consumeRegistrationDecision\",\n )(function* (\n input: ConsumeRegistration,\n ): Effect.fn.Return<ConsumeDecision<void>, AuthStoreError> {\n const now = yield* DateTime.now;\n\n const rows = (yield* Effect.suspend(() =>\n db\n .update(registrationTable as any)\n .set(updateValues<R>([[registrationColumns.consumed, true]]) as any)\n .where(\n and(\n eq(registration.tokenDigest, input.tokenDigest),\n eq(registration.consumed, false),\n gt(registration.expiresAt, mapping.registration.encodeInstant(now)),\n ),\n )\n .returning({ consumed: registration.consumed }),\n ).pipe(mapStoreWriteFailure)) as ReadonlyArray<unknown>;\n\n return rows.length === 0 ? { _tag: \"rejected\" } : { _tag: \"accepted\", value: undefined };\n });\n\n const consumeRegistration = Effect.fn(\"DrizzleSqliteAuthStore.consumeRegistration\")(function* (\n input: ConsumeRegistration,\n ) {\n yield* requireStandalone;\n const decision = yield* consumeRegistrationDecision(input);\n\n if (decision._tag === \"rejected\") return yield* InvalidRegistration.make();\n });\n\n return {\n authStore: AuthStore.of({\n issueChallenge,\n consumeChallenge,\n issueRegistration,\n inspectRegistration,\n consumeRegistration,\n }),\n decisions: {\n consumeChallenge: consumeChallengeDecision,\n consumeRegistration: consumeRegistrationDecision,\n },\n } as const;\n};\n\nexport const makeSqliteOAuthStateServices = <\n S extends AnySQLiteTable,\n HKT extends ClosedQueryEffectHKT = ClosedQueryEffectHKT,\n RunResult = unknown,\n>(\n database: SQLiteEffectDatabase<HKT, RunResult, AnyRelations>,\n mapping: OAuthStateTables<S>,\n standaloneGuard?: Effect.Effect<void, AuthStoreError>,\n) => {\n const db = database as RuntimeDatabase<HKT, RunResult>;\n\n const requireStandalone =\n standaloneGuard ??\n Effect.suspend(() =>\n db.$client === undefined\n ? AuthStoreError.make({ message: \"Use a root auth store or its decision transaction API\" })\n : requireStandaloneConsume({ $client: db.$client }),\n );\n\n const stateTable = mapping.oauthState.table;\n const stateColumns = mapping.oauthState.columns;\n\n const state = {\n stateDigest: column(stateTable, stateColumns.stateDigest),\n expiresAt: column(stateTable, stateColumns.expiresAt),\n consumed: column(stateTable, stateColumns.consumed),\n } as Record<string, SQLiteColumn>;\n\n const issue = Effect.fn(\"DrizzleSqliteOAuthStateStore.issue\")(function* (input: OAuthState) {\n yield* Effect.suspend(() =>\n db.insert(stateTable as any).values(mapping.oauthState.encodeInsert(input, false) as any),\n ).pipe(mapStoreWriteFailure);\n });\n\n const consumeDecision = Effect.fn(\"DrizzleSqliteOAuthStateStore.consumeDecision\")(function* (\n digest: TokenDigest,\n ): Effect.fn.Return<ConsumeDecision<OAuthState>, AuthStoreError> {\n const now = yield* DateTime.now;\n\n const rows = (yield* Effect.suspend(() =>\n db\n .update(stateTable as any)\n .set(updateValues<S>([[stateColumns.consumed, true]]) as any)\n .where(\n and(\n eq(state.stateDigest, digest),\n eq(state.consumed, false),\n gt(state.expiresAt, mapping.oauthState.encodeInstant(now)),\n ),\n )\n .returning(),\n ).pipe(mapStoreWriteFailure)) as ReadonlyArray<unknown>;\n\n if (rows[0] === undefined) return { _tag: \"rejected\" };\n\n const decoded = yield* Effect.suspend(() =>\n mapping.oauthState.decode(selected<S>(rows[0])),\n ).pipe(mapStoreReadFailure);\n\n return { _tag: \"accepted\", value: decoded.state };\n });\n\n const consume = Effect.fn(\"DrizzleSqliteOAuthStateStore.consume\")(function* (\n digest: TokenDigest,\n ) {\n yield* requireStandalone;\n const decision = yield* consumeDecision(digest);\n\n return decision._tag === \"accepted\" ? decision.value : yield* InvalidOAuthState.make();\n });\n\n return {\n oauthStateStore: OAuthStateStore.of({ issue, consume }),\n decisions: { consumeOAuthState: consumeDecision },\n } as const;\n};\n\nexport const makeSqliteAuthServices = <\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n S extends AnySQLiteTable,\n HKT extends ClosedQueryEffectHKT = ClosedQueryEffectHKT,\n RunResult = unknown,\n>(\n database: SQLiteEffectDatabase<HKT, RunResult, AnyRelations>,\n mapping: AuthTables<C, R, S>,\n standaloneGuard?: Effect.Effect<void, AuthStoreError>,\n) => {\n const auth = makeSqliteAuthStoreServices(database, mapping, standaloneGuard);\n const oauth = makeSqliteOAuthStateServices(database, mapping, standaloneGuard);\n\n return { ...auth, ...oauth, decisions: { ...auth.decisions, ...oauth.decisions } } as const;\n};\n\n/**\n * Owns the native outer commit for interactive SQLite targets. Keep rejection\n * as a decision value inside the owner; interruption before commit rolls back.\n */\nexport function coordinateSqliteAuthStoreTransaction<\n D extends AnyDatabase,\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: AuthStoreTables<C, R>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions> | DatabaseRequirements\n>;\n\nexport function coordinateSqliteAuthStoreTransaction<\n D extends AnyDatabase,\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthStoreTables<C, R>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinateSqliteAuthStoreTransaction<\n D extends AnyDatabase,\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthStoreTables<C, R>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, AuthStoreDecisions>>((transaction) => {\n const decisions = makeSqliteAuthStoreServices(transaction, options.mapping).decisions;\n const provided = Context.make(AuthStoreDecisions, decisions);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n }),\n );\n}\n\nexport function coordinateSqliteOAuthStateTransaction<\n D extends AnyDatabase,\n S extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthStateTables<S>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, OAuthStateDecisions> | DatabaseRequirements\n>;\n\nexport function coordinateSqliteOAuthStateTransaction<\n D extends AnyDatabase,\n S extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthStateTables<S>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, OAuthStateDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinateSqliteOAuthStateTransaction<\n D extends AnyDatabase,\n S extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthStateTables<S>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, OAuthStateDecisions>>((transaction) => {\n const decisions = makeSqliteOAuthStateServices(transaction, options.mapping).decisions;\n const provided = Context.make(OAuthStateDecisions, decisions);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n }),\n );\n}\n\nexport function coordinateSqliteAuthTransaction<\n D extends AnyDatabase,\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n S extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: AuthTables<C, R, S>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions> | DatabaseRequirements\n>;\n\nexport function coordinateSqliteAuthTransaction<\n D extends AnyDatabase,\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n S extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthTables<C, R, S>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinateSqliteAuthTransaction<\n D extends AnyDatabase,\n C extends AnySQLiteTable,\n R extends AnySQLiteTable,\n S extends AnySQLiteTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthTables<C, R, S>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions>>(\n (transaction) => {\n const decisions = makeSqliteAuthServices(transaction, options.mapping).decisions;\n\n const provided = Context.make(AuthStoreDecisions, decisions).pipe(\n Context.add(OAuthStateDecisions, decisions),\n );\n\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n },\n ),\n );\n}\n"],"mappings":";;;;;;;;;AA0DA,MAAM,uBAAuB,eAAe,KAAK,EAAE,SAAS,yBAAyB,CAAC;AACtF,MAAM,wBAAwB,eAAe,KAAK,EAAE,SAAS,0BAA0B,CAAC;AACxF,MAAM,iBAAiB,OAAO,GAAG,cAAc;AAE/C,MAAM,mBACH,aACS,WACR,yBAAyB,QAAQ,cAAc,CAAC,CAAC,KAC/C,OAAO,YAAY,UAAU,OAAO,UAAU,MAAM,IAAI,OAAO,OAAO,CAAC,CAAC,CAC1E;AAEJ,MAAM,sBAAsB,gBAAgB,cAAc;AAC1D,MAAM,uBAAuB,gBAAgB,eAAe;AAE5D,MAAM,YAAsC,QAC1C;;;;;;;AAQF,MAAa,+BAMX,UACA,SACA,oBACG;CACH,MAAM,KAAK;CAEX,MAAM,oBACJ,mBACA,OAAO,cACL,GAAG,YAAY,KAAA,IACX,eAAe,KAAK,EAAE,SAAS,wDAAwD,CAAC,IACxF,yBAAyB,EAAE,SAAS,GAAG,QAAQ,CAAC,CACtD;CAEF,MAAM,iBAAiB,QAAQ,UAAU;CACzC,MAAM,mBAAmB,QAAQ,UAAU;CAE3C,MAAM,YAAY;EAChB,aAAa,OAAO,gBAAgB,iBAAiB,WAAW;EAChE,aAAa,OAAO,gBAAgB,iBAAiB,WAAW;EAChE,WAAW,OAAO,gBAAgB,iBAAiB,SAAS;EAC5D,OAAO,OAAO,gBAAgB,iBAAiB,KAAK;EACpD,SAAS,OAAO,gBAAgB,iBAAiB,OAAO;EACxD,UAAU,OAAO,gBAAgB,iBAAiB,QAAQ;EAC1D,WAAW,OAAO,gBAAgB,iBAAiB,SAAS;EAC5D,UAAU,OAAO,gBAAgB,iBAAiB,QAAQ;EAC1D,WAAW,OAAO,gBAAgB,iBAAiB,SAAS;EAC5D,cAAc,OAAO,gBAAgB,iBAAiB,YAAY;EAClE,gBAAgB,OAAO,gBAAgB,iBAAiB,cAAc;EACtE,UAAU,OAAO,gBAAgB,iBAAiB,QAAQ;CAC5D;CAEA,MAAM,oBAAoB,QAAQ,aAAa;CAC/C,MAAM,sBAAsB,QAAQ,aAAa;CAEjD,MAAM,eAAe;EACnB,aAAa,OAAO,mBAAmB,oBAAoB,WAAW;EACtE,WAAW,OAAO,mBAAmB,oBAAoB,SAAS;EAClE,UAAU,OAAO,mBAAmB,oBAAoB,QAAQ;CAClE;CAEA,MAAM,iBAAiB,OAAO,GAAG,uCAAuC,CAAC,CAAC,WACxE,OACA;EACA,MAAM,MAAM,OAAO,SAAS;EAE5B,MAAM,iBAAiB,SAAS,eAC9B,MACC,WAAW,SAAS,SAAS,SAAS,MAAM,cAAc,CAC7D;EAmCA,KAAI,OAjCiB,OAAO,cAAc;GACxC,MAAM,SAAS,QAAQ,UAAU,aAAa,OAAO;IACnD,WAAW,QAAQ,UAAU;IAC7B,gBAAgB;IAChB,UAAU;GACZ,CAAC;GAED,MAAM,YAAY,QAAQ,UAAU,cAAc,GAAG;GACrD,MAAM,eAAe,QAAQ,UAAU,cAAc,cAAc;GACnE,MAAM,iBAAiB,QAAQ,UAAU,cAAc,MAAM,QAAQ;GACrE,MAAM,oBAAoB,GAAG,aAAa,GAAG,UAAU,WAAW,SAAS,EAAE,QAAQ,UAAU,eAAe;GAE9G,MAAM,SAAS,QAAQ,UAAU,aAAa,OAAO;IACnD,WAAW,QAAQ,UAAU;IAC7B,gBAAgB;IAChB,UAAU;GACZ,CAAC;GAED,OAAO,GACJ,OAAO,cAAqB,CAAC,CAC7B,OAAO,MAAa,CAAC,CACrB,mBAAmB;IAClB,QAAQ;KAAC,UAAU;KAAW,UAAU;KAAO,UAAU;IAAO;IAChE,KAAK;IACL,UAAU,IACR,GAAG,UAAU,aAAa,MAAM,WAAW,GAC3C,GAAG,UAAU,UAAU,cAAc,GACrC,GAAG,GAAG,UAAU,UAAU,IAAI,GAAG,IAAI,UAAU,UAAU,YAAY,CAAC,CACxE;GACF,CAAC,CAAC,CACD,UAAU;EACf,CAAC,CAAC,CAAC,KAAK,oBAAoB,EAAA,CAEnB,SAAS,GAAG;EAErB,MAAM,WAAY,OAAO,OAAO,cAC9B,GACG,OAAO,CAAC,CACR,KAAK,cAAqB,CAAC,CAC3B,MACC,IACE,GAAG,UAAU,WAAW,QAAQ,UAAU,mBAAmB,GAC7D,GAAG,UAAU,OAAO,MAAM,KAAK,GAC/B,GAAG,UAAU,SAAS,MAAM,OAAO,CACrC,CACF,CAAC,CACA,MAAM,CAAC,CACZ,CAAC,CAAC,KAAK,mBAAmB;EAE1B,MAAM,UACJ,SAAS,OAAO,KAAA,IACZ,KAAA,IACA,OAAO,OAAO,cAAc,QAAQ,UAAU,OAAO,SAAY,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,KAC9E,mBACF;EAEN,MAAM,oBACJ,YAAY,KAAA,IACR,KAAK,IAAI,GAAG,KAAK,KAAK,SAAS,SAAS,MAAM,cAAc,IAAI,GAAI,CAAC,IACrE,KAAK,IACH,GACA,KAAK,MACF,SAAS,cAAc,QAAQ,UAAU,QAAQ,IAChD,SAAS,SAAS,MAAM,cAAc,IACtC,SAAS,cAAc,GAAG,KAC1B,GACJ,CACF;EAEN,OAAO,OAAO,gBAAgB,KAAK,EAAE,kBAAkB,CAAC;CAC1D,CAAC;CAED,MAAM,2BAA2B,OAAO,GAAG,iDAAiD,CAAC,CAC3F,WACE,OAC4D;EAC5D,MAAM,MAAM,OAAO,SAAS;EAE5B,MAAM,eAAe,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,KAAK,CAAC,OAAO,YACjE,IAAI,GAAG,UAAU,UAAU,KAAK,GAAG,GAAG,UAAU,WAAW,MAAM,CAAC,CACpE;EAEA,MAAM,UAAU,aAAa,WAAW,IAAI,GAAY,UAAU,GAAG,GAAG,YAAY;EAEpF,MAAM,OAAQ,OAAO,OAAO,cAC1B,GACG,OAAO,cAAqB,CAAC,CAC7B,IACC,aAAgB,CACd,CACE,iBAAiB,UACjB,GAAG,aAAa,QAAQ,kBAAkB,UAAU,SAAS,KAC/D,GACA,CACE,iBAAiB,gBACjB,GAAG,GAAG,UAAU,eAAe,eAAe,QAAQ,mBACxD,CACF,CAAC,CACH,CAAC,CACA,MACC,IACE,GAAG,UAAU,aAAa,MAAM,WAAW,GAC3C,GAAG,UAAU,UAAU,KAAK,GAC5B,GAAG,UAAU,WAAW,QAAQ,UAAU,cAAc,GAAG,CAAC,GAC5D,GAAG,GAAG,UAAU,eAAe,KAAK,UAAU,cAChD,CACF,CAAC,CACA,UAAU,CACf,CAAC,CAAC,KAAK,oBAAoB;EAE3B,IAAI,KAAK,OAAO,KAAA,GACd,OAAO;GAAE,MAAM;GAAY,QAAQ;EAAoB;EAGzD,MAAM,UAAU,OAAO,OAAO,cAC5B,QAAQ,UAAU,OAAO,SAAY,KAAK,EAAE,CAAC,CAC/C,CAAC,CAAC,KAAK,mBAAmB;EAE1B,IAAI,CAAC,QAAQ,UAAU,OAAO;GAAE,MAAM;GAAY,QAAQ;EAAW;EAErE,OAAO;GACL,MAAM;GACN,OAAO,cAAc,KAAK;IACxB,OAAO,QAAQ,UAAU;IACzB,SAAS,QAAQ,UAAU;GAC7B,CAAC;EACH;CACF,CACF;CAEA,MAAM,mBAAmB,OAAO,GAAG,yCAAyC,CAAC,CAAC,WAC5E,OACA;EACA,OAAO;EACP,MAAM,WAAW,OAAO,yBAAyB,KAAK;EAEtD,OAAO,SAAS,SAAS,aACrB,SAAS,QACT,OAAO,iBAAiB,KAAK,EAAE,QAAQ,SAAS,OAAO,CAAC;CAC9D,CAAC;CAED,MAAM,oBAAoB,OAAO,GAAG,0CAA0C,CAAC,CAAC,WAC9E,OACA;EACA,OAAO,OAAO,cACZ,GACG,OAAO,iBAAwB,CAAC,CAChC,OAAO,QAAQ,aAAa,aAAa,OAAO,KAAK,CAAQ,CAClE,CAAC,CAAC,KAAK,oBAAoB;CAC7B,CAAC;CAED,MAAM,sBAAsB,OAAO,GAAG,4CAA4C,CAAC,CAAC,WAClF,aACA;EACA,MAAM,MAAM,OAAO,SAAS;EAE5B,MAAM,OAAQ,OAAO,OAAO,cAC1B,GACG,OAAO,CAAC,CACR,KAAK,iBAAwB,CAAC,CAC9B,MACC,IACE,GAAG,aAAa,aAAa,WAAW,GACxC,GAAG,aAAa,UAAU,KAAK,GAC/B,GAAG,aAAa,WAAW,QAAQ,aAAa,cAAc,GAAG,CAAC,CACpE,CACF,CAAC,CACA,MAAM,CAAC,CACZ,CAAC,CAAC,KAAK,mBAAmB;EAE1B,IAAI,KAAK,OAAO,KAAA,GAAW,OAAO,OAAO,oBAAoB,KAAK;EAMlE,QAAO,OAJgB,OAAO,cAC5B,QAAQ,aAAa,OAAO,SAAY,KAAK,EAAE,CAAC,CAClD,CAAC,CAAC,KAAK,mBAAmB,EAAA,CAEX;CACjB,CAAC;CAED,MAAM,8BAA8B,OAAO,GACzC,oDACF,CAAC,CAAC,WACA,OACyD;EACzD,MAAM,MAAM,OAAO,SAAS;EAgB5B,QAAO,OAdc,OAAO,cAC1B,GACG,OAAO,iBAAwB,CAAC,CAChC,IAAI,aAAgB,CAAC,CAAC,oBAAoB,UAAU,IAAI,CAAC,CAAC,CAAQ,CAAC,CACnE,MACC,IACE,GAAG,aAAa,aAAa,MAAM,WAAW,GAC9C,GAAG,aAAa,UAAU,KAAK,GAC/B,GAAG,aAAa,WAAW,QAAQ,aAAa,cAAc,GAAG,CAAC,CACpE,CACF,CAAC,CACA,UAAU,EAAE,UAAU,aAAa,SAAS,CAAC,CAClD,CAAC,CAAC,KAAK,oBAAoB,EAAA,CAEf,WAAW,IAAI,EAAE,MAAM,WAAW,IAAI;GAAE,MAAM;GAAY,OAAO,KAAA;EAAU;CACzF,CAAC;CAED,MAAM,sBAAsB,OAAO,GAAG,4CAA4C,CAAC,CAAC,WAClF,OACA;EACA,OAAO;EAGP,KAAI,OAFoB,4BAA4B,KAAK,EAAA,CAE5C,SAAS,YAAY,OAAO,OAAO,oBAAoB,KAAK;CAC3E,CAAC;CAED,OAAO;EACL,WAAW,UAAU,GAAG;GACtB;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,WAAW;GACT,kBAAkB;GAClB,qBAAqB;EACvB;CACF;AACF;AAEA,MAAa,gCAKX,UACA,SACA,oBACG;CACH,MAAM,KAAK;CAEX,MAAM,oBACJ,mBACA,OAAO,cACL,GAAG,YAAY,KAAA,IACX,eAAe,KAAK,EAAE,SAAS,wDAAwD,CAAC,IACxF,yBAAyB,EAAE,SAAS,GAAG,QAAQ,CAAC,CACtD;CAEF,MAAM,aAAa,QAAQ,WAAW;CACtC,MAAM,eAAe,QAAQ,WAAW;CAExC,MAAM,QAAQ;EACZ,aAAa,OAAO,YAAY,aAAa,WAAW;EACxD,WAAW,OAAO,YAAY,aAAa,SAAS;EACpD,UAAU,OAAO,YAAY,aAAa,QAAQ;CACpD;CAEA,MAAM,QAAQ,OAAO,GAAG,oCAAoC,CAAC,CAAC,WAAW,OAAmB;EAC1F,OAAO,OAAO,cACZ,GAAG,OAAO,UAAiB,CAAC,CAAC,OAAO,QAAQ,WAAW,aAAa,OAAO,KAAK,CAAQ,CAC1F,CAAC,CAAC,KAAK,oBAAoB;CAC7B,CAAC;CAED,MAAM,kBAAkB,OAAO,GAAG,8CAA8C,CAAC,CAAC,WAChF,QAC+D;EAC/D,MAAM,MAAM,OAAO,SAAS;EAE5B,MAAM,OAAQ,OAAO,OAAO,cAC1B,GACG,OAAO,UAAiB,CAAC,CACzB,IAAI,aAAgB,CAAC,CAAC,aAAa,UAAU,IAAI,CAAC,CAAC,CAAQ,CAAC,CAC5D,MACC,IACE,GAAG,MAAM,aAAa,MAAM,GAC5B,GAAG,MAAM,UAAU,KAAK,GACxB,GAAG,MAAM,WAAW,QAAQ,WAAW,cAAc,GAAG,CAAC,CAC3D,CACF,CAAC,CACA,UAAU,CACf,CAAC,CAAC,KAAK,oBAAoB;EAE3B,IAAI,KAAK,OAAO,KAAA,GAAW,OAAO,EAAE,MAAM,WAAW;EAMrD,OAAO;GAAE,MAAM;GAAY,QAAO,OAJX,OAAO,cAC5B,QAAQ,WAAW,OAAO,SAAY,KAAK,EAAE,CAAC,CAChD,CAAC,CAAC,KAAK,mBAAmB,EAAA,CAEgB;EAAM;CAClD,CAAC;CAED,MAAM,UAAU,OAAO,GAAG,sCAAsC,CAAC,CAAC,WAChE,QACA;EACA,OAAO;EACP,MAAM,WAAW,OAAO,gBAAgB,MAAM;EAE9C,OAAO,SAAS,SAAS,aAAa,SAAS,QAAQ,OAAO,kBAAkB,KAAK;CACvF,CAAC;CAED,OAAO;EACL,iBAAiB,gBAAgB,GAAG;GAAE;GAAO;EAAQ,CAAC;EACtD,WAAW,EAAE,mBAAmB,gBAAgB;CAClD;AACF;AAEA,MAAa,0BAOX,UACA,SACA,oBACG;CACH,MAAM,OAAO,4BAA4B,UAAU,SAAS,eAAe;CAC3E,MAAM,QAAQ,6BAA6B,UAAU,SAAS,eAAe;CAE7E,OAAO;EAAE,GAAG;EAAM,GAAG;EAAO,WAAW;GAAE,GAAG,KAAK;GAAW,GAAG,MAAM;EAAU;CAAE;AACnF;AAiDA,SAAgB,qCAYd,SACA,SAIA,MACA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,SAAS,aAA8D,gBAAgB;EACrF,MAAM,YAAY,4BAA4B,aAAa,QAAQ,OAAO,CAAC,CAAC;EAC5E,MAAM,WAAW,QAAQ,KAAK,oBAAoB,SAAS;EAC3D,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eACL,MACA,QAAQ,aACR,QAAQ,YAAY,GAAG,WAA+B,CACxD;CACN,CAAC,CACH;AACF;AA2CA,SAAgB,sCAWd,SACA,SAIA,MACA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,SAAS,aAA+D,gBAAgB;EACtF,MAAM,YAAY,6BAA6B,aAAa,QAAQ,OAAO,CAAC,CAAC;EAC7E,MAAM,WAAW,QAAQ,KAAK,qBAAqB,SAAS;EAC5D,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eACL,MACA,QAAQ,aACR,QAAQ,YAAY,GAAG,WAA+B,CACxD;CACN,CAAC,CACH;AACF;AA+CA,SAAgB,gCAad,SACA,SAIA,MACA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,SAAS,aACN,gBAAgB;EACf,MAAM,YAAY,uBAAuB,aAAa,QAAQ,OAAO,CAAC,CAAC;EAEvE,MAAM,WAAW,QAAQ,KAAK,oBAAoB,SAAS,CAAC,CAAC,KAC3D,QAAQ,IAAI,qBAAqB,SAAS,CAC5C;EAEA,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eACL,MACA,QAAQ,aACR,QAAQ,YAAY,GAAG,WAA+B,CACxD;CACN,CACF,CACF;AACF"}