@yielded/auth 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 (1466) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -0
  3. package/dist/Atom.d.mts +5 -0
  4. package/dist/Atom.mjs +5 -0
  5. package/dist/Auth.d.mts +9 -0
  6. package/dist/Auth.mjs +7 -0
  7. package/dist/AuthContract.d.mts +4 -0
  8. package/dist/AuthContract.mjs +4 -0
  9. package/dist/AuthSession.d.mts +82 -0
  10. package/dist/AuthSession.mjs +138 -0
  11. package/dist/AuthSession.mjs.map +1 -0
  12. package/dist/AuthStore.d.mts +68 -0
  13. package/dist/AuthStore.mjs +194 -0
  14. package/dist/AuthStore.mjs.map +1 -0
  15. package/dist/AuthTokenCodec.d.mts +40 -0
  16. package/dist/AuthTokenCodec.mjs +104 -0
  17. package/dist/AuthTokenCodec.mjs.map +1 -0
  18. package/dist/Client.d.mts +2 -0
  19. package/dist/Client.mjs +2 -0
  20. package/dist/Cloudflare.d.mts +89 -0
  21. package/dist/Cloudflare.mjs +166 -0
  22. package/dist/Cloudflare.mjs.map +1 -0
  23. package/dist/Drizzle.d.mts +28 -0
  24. package/dist/Drizzle.mjs +27 -0
  25. package/dist/DrizzleD1.d.mts +935 -0
  26. package/dist/DrizzleD1.mjs +29 -0
  27. package/dist/DrizzleD1.mjs.map +1 -0
  28. package/dist/DrizzleLibsql.d.mts +2288 -0
  29. package/dist/DrizzleLibsql.mjs +85 -0
  30. package/dist/DrizzleLibsql.mjs.map +1 -0
  31. package/dist/DrizzleMysql2.d.mts +1809 -0
  32. package/dist/DrizzleMysql2.mjs +55 -0
  33. package/dist/DrizzleMysql2.mjs.map +1 -0
  34. package/dist/DrizzlePglite.d.mts +1808 -0
  35. package/dist/DrizzlePglite.mjs +45 -0
  36. package/dist/DrizzlePglite.mjs.map +1 -0
  37. package/dist/DrizzlePostgres.d.mts +1808 -0
  38. package/dist/DrizzlePostgres.mjs +45 -0
  39. package/dist/DrizzlePostgres.mjs.map +1 -0
  40. package/dist/DrizzleSqliteBun.d.mts +2287 -0
  41. package/dist/DrizzleSqliteBun.mjs +62 -0
  42. package/dist/DrizzleSqliteBun.mjs.map +1 -0
  43. package/dist/DrizzleSqliteDo.d.mts +2343 -0
  44. package/dist/DrizzleSqliteDo.mjs +105 -0
  45. package/dist/DrizzleSqliteDo.mjs.map +1 -0
  46. package/dist/DrizzleSqliteNode.d.mts +2287 -0
  47. package/dist/DrizzleSqliteNode.mjs +62 -0
  48. package/dist/DrizzleSqliteNode.mjs.map +1 -0
  49. package/dist/DrizzleSqliteWasm.d.mts +2287 -0
  50. package/dist/DrizzleSqliteWasm.mjs +62 -0
  51. package/dist/DrizzleSqliteWasm.mjs.map +1 -0
  52. package/dist/Email.d.mts +12 -0
  53. package/dist/Email.mjs +11 -0
  54. package/dist/EmailOtp.d.mts +42 -0
  55. package/dist/EmailOtp.mjs +120 -0
  56. package/dist/EmailOtp.mjs.map +1 -0
  57. package/dist/EmailOtpSender.d.mts +22 -0
  58. package/dist/EmailOtpSender.mjs +18 -0
  59. package/dist/EmailOtpSender.mjs.map +1 -0
  60. package/dist/Errors.d.mts +55 -0
  61. package/dist/Errors.mjs +31 -0
  62. package/dist/Errors.mjs.map +1 -0
  63. package/dist/GitHub.d.mts +5 -0
  64. package/dist/GitHub.mjs +4 -0
  65. package/dist/Hooks.d.mts +6 -0
  66. package/dist/Hooks.mjs +6 -0
  67. package/dist/Http.d.mts +12 -0
  68. package/dist/Http.mjs +12 -0
  69. package/dist/HttpServer.d.mts +103 -0
  70. package/dist/HttpServer.mjs +326 -0
  71. package/dist/HttpServer.mjs.map +1 -0
  72. package/dist/Identity.d.mts +9 -0
  73. package/dist/Identity.mjs +9 -0
  74. package/dist/IdentityResolver.d.mts +16 -0
  75. package/dist/IdentityResolver.mjs +12 -0
  76. package/dist/IdentityResolver.mjs.map +1 -0
  77. package/dist/OAuth.d.mts +36 -0
  78. package/dist/OAuth.mjs +35 -0
  79. package/dist/OpenIdClient.d.mts +3 -0
  80. package/dist/OpenIdClient.mjs +3 -0
  81. package/dist/OpenIdClientConnected.d.mts +4 -0
  82. package/dist/OpenIdClientConnected.mjs +3 -0
  83. package/dist/OperationHttp.d.mts +3 -0
  84. package/dist/OperationHttp.mjs +3 -0
  85. package/dist/OperationHttpClient.d.mts +2 -0
  86. package/dist/OperationHttpClient.mjs +2 -0
  87. package/dist/OperationHttpServer.d.mts +5 -0
  88. package/dist/OperationHttpServer.mjs +4 -0
  89. package/dist/Operations.d.mts +8 -0
  90. package/dist/Operations.mjs +8 -0
  91. package/dist/Passkey.d.mts +12 -0
  92. package/dist/Passkey.mjs +12 -0
  93. package/dist/PasskeyBrowser.d.mts +4 -0
  94. package/dist/PasskeyBrowser.mjs +4 -0
  95. package/dist/PasskeyContract.d.mts +641 -0
  96. package/dist/PasskeyContract.mjs +174 -0
  97. package/dist/PasskeyContract.mjs.map +1 -0
  98. package/dist/PasskeyPassword.d.mts +412 -0
  99. package/dist/PasskeyPassword.mjs +174 -0
  100. package/dist/PasskeyPassword.mjs.map +1 -0
  101. package/dist/PasskeySimpleWebAuthn.d.mts +3 -0
  102. package/dist/PasskeySimpleWebAuthn.mjs +3 -0
  103. package/dist/Password.d.mts +19 -0
  104. package/dist/Password.mjs +17 -0
  105. package/dist/PasswordAuth.d.mts +45 -0
  106. package/dist/PasswordAuth.mjs +79 -0
  107. package/dist/PasswordAuth.mjs.map +1 -0
  108. package/dist/PasswordCredentialStore.d.mts +46 -0
  109. package/dist/PasswordCredentialStore.mjs +62 -0
  110. package/dist/PasswordCredentialStore.mjs.map +1 -0
  111. package/dist/PasswordHasher.d.mts +31 -0
  112. package/dist/PasswordHasher.mjs +76 -0
  113. package/dist/PasswordHasher.mjs.map +1 -0
  114. package/dist/PhoneOtp.d.mts +11 -0
  115. package/dist/PhoneOtp.mjs +11 -0
  116. package/dist/Policy.d.mts +52 -0
  117. package/dist/Policy.mjs +36 -0
  118. package/dist/Policy.mjs.map +1 -0
  119. package/dist/Proofs.d.mts +14 -0
  120. package/dist/Proofs.mjs +13 -0
  121. package/dist/Rpc.d.mts +12 -0
  122. package/dist/Rpc.mjs +11 -0
  123. package/dist/Rpc.mjs.map +1 -0
  124. package/dist/Schema.d.mts +160 -0
  125. package/dist/Schema.mjs +141 -0
  126. package/dist/Schema.mjs.map +1 -0
  127. package/dist/SessionContract.d.mts +3 -0
  128. package/dist/SessionContract.mjs +3 -0
  129. package/dist/Sessions.d.mts +14 -0
  130. package/dist/Sessions.mjs +12 -0
  131. package/dist/Testing.d.mts +7 -0
  132. package/dist/Testing.mjs +7 -0
  133. package/dist/Totp.d.mts +8 -0
  134. package/dist/Totp.mjs +8 -0
  135. package/dist/TotpContract.d.mts +318 -0
  136. package/dist/TotpContract.mjs +119 -0
  137. package/dist/TotpContract.mjs.map +1 -0
  138. package/dist/WebCrypto.d.mts +28 -0
  139. package/dist/WebCrypto.mjs +42 -0
  140. package/dist/WebCrypto.mjs.map +1 -0
  141. package/dist/Workflows.d.mts +16 -0
  142. package/dist/Workflows.mjs +11 -0
  143. package/dist/Workflows.mjs.map +1 -0
  144. package/dist/atom/AuthAtomLifetime.d.mts +35 -0
  145. package/dist/atom/AuthAtomLifetime.mjs +50 -0
  146. package/dist/atom/AuthAtomLifetime.mjs.map +1 -0
  147. package/dist/atom/AuthAtomWorkflow.d.mts +17 -0
  148. package/dist/atom/AuthAtomWorkflow.mjs +9 -0
  149. package/dist/atom/AuthAtomWorkflow.mjs.map +1 -0
  150. package/dist/atom/client.d.mts +43 -0
  151. package/dist/atom/client.mjs +168 -0
  152. package/dist/atom/client.mjs.map +1 -0
  153. package/dist/atom/operations.d.mts +35 -0
  154. package/dist/atom/operations.mjs +58 -0
  155. package/dist/atom/operations.mjs.map +1 -0
  156. package/dist/atom/scoped-runtime.mjs +151 -0
  157. package/dist/atom/scoped-runtime.mjs.map +1 -0
  158. package/dist/auth/Auth.d.mts +7806 -0
  159. package/dist/auth/Auth.mjs +141 -0
  160. package/dist/auth/Auth.mjs.map +1 -0
  161. package/dist/auth/AuthConfigurationError.d.mts +10 -0
  162. package/dist/auth/AuthConfigurationError.mjs +14 -0
  163. package/dist/auth/AuthConfigurationError.mjs.map +1 -0
  164. package/dist/auth/AuthRequest.d.mts +21 -0
  165. package/dist/auth/AuthRequest.mjs +10 -0
  166. package/dist/auth/AuthRequest.mjs.map +1 -0
  167. package/dist/auth/AuthStrategy.d.mts +23 -0
  168. package/dist/auth/AuthStrategy.mjs +33 -0
  169. package/dist/auth/AuthStrategy.mjs.map +1 -0
  170. package/dist/auth/ConsumeDecision.d.mts +11 -0
  171. package/dist/auth/actions.d.mts +18 -0
  172. package/dist/auth/actions.mjs +70 -0
  173. package/dist/auth/actions.mjs.map +1 -0
  174. package/dist/auth/defaults.mjs +12 -0
  175. package/dist/auth/defaults.mjs.map +1 -0
  176. package/dist/auth/definition.d.mts +46 -0
  177. package/dist/auth/session.d.mts +27 -0
  178. package/dist/auth/session.mjs +56 -0
  179. package/dist/auth/session.mjs.map +1 -0
  180. package/dist/drizzle/D1BatchStatements.d.mts +11 -0
  181. package/dist/drizzle/D1BatchStatements.mjs +8 -0
  182. package/dist/drizzle/D1BatchStatements.mjs.map +1 -0
  183. package/dist/drizzle/PasswordPreparedPostconditions.mjs +12 -0
  184. package/dist/drizzle/PasswordPreparedPostconditions.mjs.map +1 -0
  185. package/dist/drizzle/SuppliedService.d.mts +10 -0
  186. package/dist/drizzle/d1-emails.d.mts +68 -0
  187. package/dist/drizzle/d1-emails.mjs +580 -0
  188. package/dist/drizzle/d1-emails.mjs.map +1 -0
  189. package/dist/drizzle/d1-generated-statement.mjs +79 -0
  190. package/dist/drizzle/d1-generated-statement.mjs.map +1 -0
  191. package/dist/drizzle/d1-identity.d.mts +33 -0
  192. package/dist/drizzle/d1-identity.mjs +120 -0
  193. package/dist/drizzle/d1-identity.mjs.map +1 -0
  194. package/dist/drizzle/d1-oauth.d.mts +316 -0
  195. package/dist/drizzle/d1-oauth.mjs +79 -0
  196. package/dist/drizzle/d1-oauth.mjs.map +1 -0
  197. package/dist/drizzle/d1-passkey.d.mts +52 -0
  198. package/dist/drizzle/d1-passkey.mjs +97 -0
  199. package/dist/drizzle/d1-passkey.mjs.map +1 -0
  200. package/dist/drizzle/d1-password-prepared.d.mts +27 -0
  201. package/dist/drizzle/d1-password-prepared.mjs +464 -0
  202. package/dist/drizzle/d1-password-prepared.mjs.map +1 -0
  203. package/dist/drizzle/d1-passwords.d.mts +96 -0
  204. package/dist/drizzle/d1-passwords.mjs +1008 -0
  205. package/dist/drizzle/d1-passwords.mjs.map +1 -0
  206. package/dist/drizzle/d1-phone.d.mts +29 -0
  207. package/dist/drizzle/d1-phone.mjs +33 -0
  208. package/dist/drizzle/d1-phone.mjs.map +1 -0
  209. package/dist/drizzle/d1-planning.d.mts +12 -0
  210. package/dist/drizzle/d1-planning.mjs +43 -0
  211. package/dist/drizzle/d1-planning.mjs.map +1 -0
  212. package/dist/drizzle/d1-proofs.d.mts +88 -0
  213. package/dist/drizzle/d1-proofs.mjs +833 -0
  214. package/dist/drizzle/d1-proofs.mjs.map +1 -0
  215. package/dist/drizzle/d1-sessions.d.mts +77 -0
  216. package/dist/drizzle/d1-sessions.mjs +970 -0
  217. package/dist/drizzle/d1-sessions.mjs.map +1 -0
  218. package/dist/drizzle/d1-totp.d.mts +27 -0
  219. package/dist/drizzle/d1-totp.mjs +28 -0
  220. package/dist/drizzle/d1-totp.mjs.map +1 -0
  221. package/dist/drizzle/email-model.d.mts +352 -0
  222. package/dist/drizzle/email-model.mjs +21 -0
  223. package/dist/drizzle/email-model.mjs.map +1 -0
  224. package/dist/drizzle/email-registration.d.mts +33 -0
  225. package/dist/drizzle/email-registration.mjs +238 -0
  226. package/dist/drizzle/email-registration.mjs.map +1 -0
  227. package/dist/drizzle/email-sql.d.mts +18 -0
  228. package/dist/drizzle/email-sql.mjs +473 -0
  229. package/dist/drizzle/email-sql.mjs.map +1 -0
  230. package/dist/drizzle/email-target.d.mts +28 -0
  231. package/dist/drizzle/email-target.mjs +75 -0
  232. package/dist/drizzle/email-target.mjs.map +1 -0
  233. package/dist/drizzle/model.d.mts +259 -0
  234. package/dist/drizzle/model.mjs +81 -0
  235. package/dist/drizzle/model.mjs.map +1 -0
  236. package/dist/drizzle/mysql-emails.d.mts +82 -0
  237. package/dist/drizzle/mysql-emails.mjs +38 -0
  238. package/dist/drizzle/mysql-emails.mjs.map +1 -0
  239. package/dist/drizzle/mysql-identity.d.mts +24 -0
  240. package/dist/drizzle/mysql-identity.mjs +95 -0
  241. package/dist/drizzle/mysql-identity.mjs.map +1 -0
  242. package/dist/drizzle/mysql-password-prepared.d.mts +32 -0
  243. package/dist/drizzle/mysql-password-prepared.mjs +16 -0
  244. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -0
  245. package/dist/drizzle/mysql-passwords.d.mts +102 -0
  246. package/dist/drizzle/mysql-passwords.mjs +38 -0
  247. package/dist/drizzle/mysql-passwords.mjs.map +1 -0
  248. package/dist/drizzle/mysql-proofs.d.mts +83 -0
  249. package/dist/drizzle/mysql-proofs.mjs +23 -0
  250. package/dist/drizzle/mysql-proofs.mjs.map +1 -0
  251. package/dist/drizzle/mysql-sessions.d.mts +250 -0
  252. package/dist/drizzle/mysql-sessions.mjs +53 -0
  253. package/dist/drizzle/mysql-sessions.mjs.map +1 -0
  254. package/dist/drizzle/mysql.d.mts +73 -0
  255. package/dist/drizzle/mysql.mjs +221 -0
  256. package/dist/drizzle/mysql.mjs.map +1 -0
  257. package/dist/drizzle/oauth-accounts.mjs +361 -0
  258. package/dist/drizzle/oauth-accounts.mjs.map +1 -0
  259. package/dist/drizzle/oauth-connected-access.mjs +210 -0
  260. package/dist/drizzle/oauth-connected-access.mjs.map +1 -0
  261. package/dist/drizzle/oauth-connected-collection.mjs +202 -0
  262. package/dist/drizzle/oauth-connected-collection.mjs.map +1 -0
  263. package/dist/drizzle/oauth-connected-custody.mjs +146 -0
  264. package/dist/drizzle/oauth-connected-custody.mjs.map +1 -0
  265. package/dist/drizzle/oauth-connected-drivers.mjs +78 -0
  266. package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -0
  267. package/dist/drizzle/oauth-connected-flow.mjs +248 -0
  268. package/dist/drizzle/oauth-connected-flow.mjs.map +1 -0
  269. package/dist/drizzle/oauth-connected-input.mjs +105 -0
  270. package/dist/drizzle/oauth-connected-input.mjs.map +1 -0
  271. package/dist/drizzle/oauth-connected-maintenance.mjs +215 -0
  272. package/dist/drizzle/oauth-connected-maintenance.mjs.map +1 -0
  273. package/dist/drizzle/oauth-connected-management.mjs +228 -0
  274. package/dist/drizzle/oauth-connected-management.mjs.map +1 -0
  275. package/dist/drizzle/oauth-connected-model.d.mts +278 -0
  276. package/dist/drizzle/oauth-connected-model.mjs +22 -0
  277. package/dist/drizzle/oauth-connected-model.mjs.map +1 -0
  278. package/dist/drizzle/oauth-connected-reference.d.mts +17 -0
  279. package/dist/drizzle/oauth-connected-reference.mjs +53 -0
  280. package/dist/drizzle/oauth-connected-reference.mjs.map +1 -0
  281. package/dist/drizzle/oauth-connected-settlement.mjs +117 -0
  282. package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -0
  283. package/dist/drizzle/oauth-connected-state.d.mts +16 -0
  284. package/dist/drizzle/oauth-connected-state.mjs +422 -0
  285. package/dist/drizzle/oauth-connected-state.mjs.map +1 -0
  286. package/dist/drizzle/oauth-connected-target.d.mts +114 -0
  287. package/dist/drizzle/oauth-connected-target.mjs +94 -0
  288. package/dist/drizzle/oauth-connected-target.mjs.map +1 -0
  289. package/dist/drizzle/oauth-drivers.mjs +53 -0
  290. package/dist/drizzle/oauth-drivers.mjs.map +1 -0
  291. package/dist/drizzle/oauth-flow.d.mts +7 -0
  292. package/dist/drizzle/oauth-flow.mjs +255 -0
  293. package/dist/drizzle/oauth-flow.mjs.map +1 -0
  294. package/dist/drizzle/oauth-input.mjs +130 -0
  295. package/dist/drizzle/oauth-input.mjs.map +1 -0
  296. package/dist/drizzle/oauth-model.d.mts +468 -0
  297. package/dist/drizzle/oauth-model.mjs +49 -0
  298. package/dist/drizzle/oauth-model.mjs.map +1 -0
  299. package/dist/drizzle/oauth-mysql.mjs +8 -0
  300. package/dist/drizzle/oauth-mysql.mjs.map +1 -0
  301. package/dist/drizzle/oauth-owner.d.mts +4 -0
  302. package/dist/drizzle/oauth-owner.mjs +10 -0
  303. package/dist/drizzle/oauth-owner.mjs.map +1 -0
  304. package/dist/drizzle/oauth-registration.d.mts +8 -0
  305. package/dist/drizzle/oauth-registration.mjs +375 -0
  306. package/dist/drizzle/oauth-registration.mjs.map +1 -0
  307. package/dist/drizzle/oauth-state.mjs +109 -0
  308. package/dist/drizzle/oauth-state.mjs.map +1 -0
  309. package/dist/drizzle/oauth-target.d.mts +125 -0
  310. package/dist/drizzle/oauth-target.mjs +252 -0
  311. package/dist/drizzle/oauth-target.mjs.map +1 -0
  312. package/dist/drizzle/passkey-admission.mjs +203 -0
  313. package/dist/drizzle/passkey-admission.mjs.map +1 -0
  314. package/dist/drizzle/passkey-credentials.mjs +239 -0
  315. package/dist/drizzle/passkey-credentials.mjs.map +1 -0
  316. package/dist/drizzle/passkey-drivers.mjs +34 -0
  317. package/dist/drizzle/passkey-drivers.mjs.map +1 -0
  318. package/dist/drizzle/passkey-enrollment.mjs +132 -0
  319. package/dist/drizzle/passkey-enrollment.mjs.map +1 -0
  320. package/dist/drizzle/passkey-flow.mjs +436 -0
  321. package/dist/drizzle/passkey-flow.mjs.map +1 -0
  322. package/dist/drizzle/passkey-management.mjs +225 -0
  323. package/dist/drizzle/passkey-management.mjs.map +1 -0
  324. package/dist/drizzle/passkey-model.d.mts +275 -0
  325. package/dist/drizzle/passkey-model.mjs +36 -0
  326. package/dist/drizzle/passkey-model.mjs.map +1 -0
  327. package/dist/drizzle/passkey-registration-ceremony-model.d.mts +50 -0
  328. package/dist/drizzle/passkey-registration-ceremony-model.mjs +18 -0
  329. package/dist/drizzle/passkey-registration-ceremony-model.mjs.map +1 -0
  330. package/dist/drizzle/passkey-registration-ceremony.mjs +124 -0
  331. package/dist/drizzle/passkey-registration-ceremony.mjs.map +1 -0
  332. package/dist/drizzle/passkey-registration-custody.mjs +51 -0
  333. package/dist/drizzle/passkey-registration-custody.mjs.map +1 -0
  334. package/dist/drizzle/passkey-registration-write.mjs +205 -0
  335. package/dist/drizzle/passkey-registration-write.mjs.map +1 -0
  336. package/dist/drizzle/passkey-state.d.mts +5 -0
  337. package/dist/drizzle/passkey-state.mjs +207 -0
  338. package/dist/drizzle/passkey-state.mjs.map +1 -0
  339. package/dist/drizzle/passkey-target.d.mts +16 -0
  340. package/dist/drizzle/passkey-target.mjs +174 -0
  341. package/dist/drizzle/passkey-target.mjs.map +1 -0
  342. package/dist/drizzle/passkey-write-drivers.mjs +33 -0
  343. package/dist/drizzle/passkey-write-drivers.mjs.map +1 -0
  344. package/dist/drizzle/passkey-write-model.d.mts +192 -0
  345. package/dist/drizzle/passkey-write-model.mjs +13 -0
  346. package/dist/drizzle/passkey-write-model.mjs.map +1 -0
  347. package/dist/drizzle/passkey-write-state.mjs +326 -0
  348. package/dist/drizzle/passkey-write-state.mjs.map +1 -0
  349. package/dist/drizzle/passkey-write-target.d.mts +14 -0
  350. package/dist/drizzle/passkey-write-target.mjs +185 -0
  351. package/dist/drizzle/passkey-write-target.mjs.map +1 -0
  352. package/dist/drizzle/password-model.d.mts +330 -0
  353. package/dist/drizzle/password-model.mjs +22 -0
  354. package/dist/drizzle/password-model.mjs.map +1 -0
  355. package/dist/drizzle/password-prepared-model.d.mts +93 -0
  356. package/dist/drizzle/password-prepared-model.mjs +11 -0
  357. package/dist/drizzle/password-prepared-model.mjs.map +1 -0
  358. package/dist/drizzle/password-prepared-sql.mjs +394 -0
  359. package/dist/drizzle/password-prepared-sql.mjs.map +1 -0
  360. package/dist/drizzle/password-prepared-state.mjs +107 -0
  361. package/dist/drizzle/password-prepared-state.mjs.map +1 -0
  362. package/dist/drizzle/password-prepared-target.d.mts +12 -0
  363. package/dist/drizzle/password-prepared-target.mjs +57 -0
  364. package/dist/drizzle/password-prepared-target.mjs.map +1 -0
  365. package/dist/drizzle/password-registration.d.mts +23 -0
  366. package/dist/drizzle/password-registration.mjs +136 -0
  367. package/dist/drizzle/password-registration.mjs.map +1 -0
  368. package/dist/drizzle/password-sql.d.mts +20 -0
  369. package/dist/drizzle/password-sql.mjs +702 -0
  370. package/dist/drizzle/password-sql.mjs.map +1 -0
  371. package/dist/drizzle/password-target.d.mts +25 -0
  372. package/dist/drizzle/password-target.mjs +63 -0
  373. package/dist/drizzle/password-target.mjs.map +1 -0
  374. package/dist/drizzle/pg-emails.d.mts +83 -0
  375. package/dist/drizzle/pg-emails.mjs +38 -0
  376. package/dist/drizzle/pg-emails.mjs.map +1 -0
  377. package/dist/drizzle/pg-password-prepared.d.mts +33 -0
  378. package/dist/drizzle/pg-password-prepared.mjs +16 -0
  379. package/dist/drizzle/pg-password-prepared.mjs.map +1 -0
  380. package/dist/drizzle/pg-passwords.d.mts +103 -0
  381. package/dist/drizzle/pg-passwords.mjs +38 -0
  382. package/dist/drizzle/pg-passwords.mjs.map +1 -0
  383. package/dist/drizzle/pg-proofs.d.mts +84 -0
  384. package/dist/drizzle/pg-proofs.mjs +22 -0
  385. package/dist/drizzle/pg-proofs.mjs.map +1 -0
  386. package/dist/drizzle/pg-sessions.d.mts +251 -0
  387. package/dist/drizzle/pg-sessions.mjs +53 -0
  388. package/dist/drizzle/pg-sessions.mjs.map +1 -0
  389. package/dist/drizzle/pg.d.mts +88 -0
  390. package/dist/drizzle/pg.mjs +294 -0
  391. package/dist/drizzle/pg.mjs.map +1 -0
  392. package/dist/drizzle/phone-model.d.mts +117 -0
  393. package/dist/drizzle/phone-model.mjs +39 -0
  394. package/dist/drizzle/phone-model.mjs.map +1 -0
  395. package/dist/drizzle/phone-state.mjs +426 -0
  396. package/dist/drizzle/phone-state.mjs.map +1 -0
  397. package/dist/drizzle/phone-target.d.mts +19 -0
  398. package/dist/drizzle/phone-target.mjs +171 -0
  399. package/dist/drizzle/phone-target.mjs.map +1 -0
  400. package/dist/drizzle/proof-model.d.mts +287 -0
  401. package/dist/drizzle/proof-model.mjs +17 -0
  402. package/dist/drizzle/proof-model.mjs.map +1 -0
  403. package/dist/drizzle/proof-sql.d.mts +16 -0
  404. package/dist/drizzle/proof-sql.mjs +618 -0
  405. package/dist/drizzle/proof-sql.mjs.map +1 -0
  406. package/dist/drizzle/proof-target.d.mts +17 -0
  407. package/dist/drizzle/proof-target.mjs +38 -0
  408. package/dist/drizzle/proof-target.mjs.map +1 -0
  409. package/dist/drizzle/session-model.d.mts +201 -0
  410. package/dist/drizzle/session-model.mjs +19 -0
  411. package/dist/drizzle/session-model.mjs.map +1 -0
  412. package/dist/drizzle/session-sql.mjs +732 -0
  413. package/dist/drizzle/session-sql.mjs.map +1 -0
  414. package/dist/drizzle/session-target.d.mts +37 -0
  415. package/dist/drizzle/session-target.mjs +47 -0
  416. package/dist/drizzle/session-target.mjs.map +1 -0
  417. package/dist/drizzle/sqlite-emails.mjs +45 -0
  418. package/dist/drizzle/sqlite-emails.mjs.map +1 -0
  419. package/dist/drizzle/sqlite-identity.mjs +92 -0
  420. package/dist/drizzle/sqlite-identity.mjs.map +1 -0
  421. package/dist/drizzle/sqlite-password-prepared.mjs +21 -0
  422. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -0
  423. package/dist/drizzle/sqlite-passwords.mjs +49 -0
  424. package/dist/drizzle/sqlite-passwords.mjs.map +1 -0
  425. package/dist/drizzle/sqlite-proofs.mjs +29 -0
  426. package/dist/drizzle/sqlite-proofs.mjs.map +1 -0
  427. package/dist/drizzle/sqlite-sessions.mjs +74 -0
  428. package/dist/drizzle/sqlite-sessions.mjs.map +1 -0
  429. package/dist/drizzle/sqlite.d.mts +81 -0
  430. package/dist/drizzle/sqlite.mjs +220 -0
  431. package/dist/drizzle/sqlite.mjs.map +1 -0
  432. package/dist/drizzle/standalone-guard.mjs +19 -0
  433. package/dist/drizzle/standalone-guard.mjs.map +1 -0
  434. package/dist/drizzle/step-up-model.d.mts +65 -0
  435. package/dist/drizzle/step-up-model.mjs +9 -0
  436. package/dist/drizzle/step-up-model.mjs.map +1 -0
  437. package/dist/drizzle/step-up-state.mjs +34 -0
  438. package/dist/drizzle/step-up-state.mjs.map +1 -0
  439. package/dist/drizzle/totp-model.d.mts +85 -0
  440. package/dist/drizzle/totp-model.mjs +13 -0
  441. package/dist/drizzle/totp-model.mjs.map +1 -0
  442. package/dist/drizzle/totp-state.d.mts +39 -0
  443. package/dist/drizzle/totp-state.mjs +288 -0
  444. package/dist/drizzle/totp-state.mjs.map +1 -0
  445. package/dist/drizzle/totp-target.d.mts +16 -0
  446. package/dist/drizzle/totp-target.mjs +83 -0
  447. package/dist/drizzle/totp-target.mjs.map +1 -0
  448. package/dist/drizzle/transaction-execution.d.mts +20 -0
  449. package/dist/drizzle/transaction-execution.mjs +111 -0
  450. package/dist/drizzle/transaction-execution.mjs.map +1 -0
  451. package/dist/drizzle/transaction-mysql.mjs +46 -0
  452. package/dist/drizzle/transaction-mysql.mjs.map +1 -0
  453. package/dist/drizzle/transaction-owner.d.mts +6 -0
  454. package/dist/drizzle/transaction-owner.mjs +252 -0
  455. package/dist/drizzle/transaction-owner.mjs.map +1 -0
  456. package/dist/email/EmailActionEvidence.d.mts +33 -0
  457. package/dist/email/EmailActionEvidence.mjs +15 -0
  458. package/dist/email/EmailActionEvidence.mjs.map +1 -0
  459. package/dist/email/EmailAddressPersistence.d.mts +63 -0
  460. package/dist/email/EmailAddressPersistence.mjs +19 -0
  461. package/dist/email/EmailAddressPersistence.mjs.map +1 -0
  462. package/dist/email/EmailIdentifierNotifier.d.mts +30 -0
  463. package/dist/email/EmailIdentifierNotifier.mjs +31 -0
  464. package/dist/email/EmailIdentifierNotifier.mjs.map +1 -0
  465. package/dist/email/EmailReturnTargets.d.mts +19 -0
  466. package/dist/email/EmailReturnTargets.mjs +29 -0
  467. package/dist/email/EmailReturnTargets.mjs.map +1 -0
  468. package/dist/email/EmailSignInTargets.d.mts +20 -0
  469. package/dist/email/EmailSignInTargets.mjs +12 -0
  470. package/dist/email/EmailSignInTargets.mjs.map +1 -0
  471. package/dist/email/addresses.d.mts +33 -0
  472. package/dist/email/addresses.mjs +404 -0
  473. package/dist/email/addresses.mjs.map +1 -0
  474. package/dist/email/definition.d.mts +10153 -0
  475. package/dist/email/definition.mjs +111 -0
  476. package/dist/email/definition.mjs.map +1 -0
  477. package/dist/email/errors.d.mts +15 -0
  478. package/dist/email/errors.mjs +11 -0
  479. package/dist/email/errors.mjs.map +1 -0
  480. package/dist/email/magicLink.d.mts +33 -0
  481. package/dist/email/magicLink.mjs +58 -0
  482. package/dist/email/magicLink.mjs.map +1 -0
  483. package/dist/email/models.d.mts +56 -0
  484. package/dist/email/models.mjs +31 -0
  485. package/dist/email/models.mjs.map +1 -0
  486. package/dist/email/module.d.mts +22296 -0
  487. package/dist/email/module.mjs +415 -0
  488. package/dist/email/module.mjs.map +1 -0
  489. package/dist/email/registration.d.mts +28 -0
  490. package/dist/email/registration.mjs +243 -0
  491. package/dist/email/registration.mjs.map +1 -0
  492. package/dist/email/snapshot.mjs +37 -0
  493. package/dist/email/snapshot.mjs.map +1 -0
  494. package/dist/hooks/LifecycleHooks.d.mts +34 -0
  495. package/dist/hooks/LifecycleHooks.mjs +74 -0
  496. package/dist/hooks/LifecycleHooks.mjs.map +1 -0
  497. package/dist/hooks/commit.d.mts +66 -0
  498. package/dist/hooks/commit.mjs +136 -0
  499. package/dist/hooks/commit.mjs.map +1 -0
  500. package/dist/hooks/models.d.mts +51 -0
  501. package/dist/hooks/models.mjs +87 -0
  502. package/dist/hooks/models.mjs.map +1 -0
  503. package/dist/hooks/plugins.d.mts +36 -0
  504. package/dist/hooks/plugins.mjs +60 -0
  505. package/dist/hooks/plugins.mjs.map +1 -0
  506. package/dist/hooks/transactions.d.mts +31 -0
  507. package/dist/hooks/transactions.mjs +38 -0
  508. package/dist/hooks/transactions.mjs.map +1 -0
  509. package/dist/http/auth-api.d.mts +9 -0
  510. package/dist/http/auth-api.mjs +13 -0
  511. package/dist/http/auth-api.mjs.map +1 -0
  512. package/dist/http/auth-contract.d.mts +84 -0
  513. package/dist/http/auth-contract.mjs +75 -0
  514. package/dist/http/auth-contract.mjs.map +1 -0
  515. package/dist/http/auth-http.d.mts +216 -0
  516. package/dist/http/auth-http.mjs +184 -0
  517. package/dist/http/auth-http.mjs.map +1 -0
  518. package/dist/http/endpoints/get-session.d.mts +8 -0
  519. package/dist/http/endpoints/get-session.mjs +12 -0
  520. package/dist/http/endpoints/get-session.mjs.map +1 -0
  521. package/dist/http/endpoints/password-sign-in.d.mts +8 -0
  522. package/dist/http/endpoints/password-sign-in.mjs +18 -0
  523. package/dist/http/endpoints/password-sign-in.mjs.map +1 -0
  524. package/dist/http/endpoints/request-email-otp.d.mts +8 -0
  525. package/dist/http/endpoints/request-email-otp.mjs +17 -0
  526. package/dist/http/endpoints/request-email-otp.mjs.map +1 -0
  527. package/dist/http/endpoints/set-password.d.mts +9 -0
  528. package/dist/http/endpoints/set-password.mjs +19 -0
  529. package/dist/http/endpoints/set-password.mjs.map +1 -0
  530. package/dist/http/endpoints/sign-out.d.mts +6 -0
  531. package/dist/http/endpoints/sign-out.mjs +7 -0
  532. package/dist/http/endpoints/sign-out.mjs.map +1 -0
  533. package/dist/http/endpoints/verify-email-otp.d.mts +9 -0
  534. package/dist/http/endpoints/verify-email-otp.mjs +18 -0
  535. package/dist/http/endpoints/verify-email-otp.mjs.map +1 -0
  536. package/dist/http/models.d.mts +49 -0
  537. package/dist/http/models.mjs +35 -0
  538. package/dist/http/models.mjs.map +1 -0
  539. package/dist/http/security.d.mts +91 -0
  540. package/dist/http/security.mjs +77 -0
  541. package/dist/http/security.mjs.map +1 -0
  542. package/dist/http/session-contract.d.mts +303 -0
  543. package/dist/http/session-contract.mjs +38 -0
  544. package/dist/http/session-contract.mjs.map +1 -0
  545. package/dist/http-operation/OperationHttpInvocation.d.mts +16 -0
  546. package/dist/http-operation/OperationHttpInvocation.mjs +11 -0
  547. package/dist/http-operation/OperationHttpInvocation.mjs.map +1 -0
  548. package/dist/http-operation/OperationHttpServerConfig.d.mts +18 -0
  549. package/dist/http-operation/OperationHttpServerConfig.mjs +72 -0
  550. package/dist/http-operation/OperationHttpServerConfig.mjs.map +1 -0
  551. package/dist/http-operation/auth-client.d.mts +75 -0
  552. package/dist/http-operation/auth-client.mjs +116 -0
  553. package/dist/http-operation/auth-client.mjs.map +1 -0
  554. package/dist/http-operation/client.d.mts +50 -0
  555. package/dist/http-operation/client.mjs +188 -0
  556. package/dist/http-operation/client.mjs.map +1 -0
  557. package/dist/http-operation/configuration-schema.mjs +19 -0
  558. package/dist/http-operation/configuration-schema.mjs.map +1 -0
  559. package/dist/http-operation/contract.d.mts +40 -0
  560. package/dist/http-operation/contract.mjs +37 -0
  561. package/dist/http-operation/contract.mjs.map +1 -0
  562. package/dist/http-operation/errors.d.mts +13 -0
  563. package/dist/http-operation/errors.mjs +31 -0
  564. package/dist/http-operation/errors.mjs.map +1 -0
  565. package/dist/http-operation/models.d.mts +32 -0
  566. package/dist/http-operation/models.mjs +14 -0
  567. package/dist/http-operation/models.mjs.map +1 -0
  568. package/dist/http-operation/private.mjs +35 -0
  569. package/dist/http-operation/private.mjs.map +1 -0
  570. package/dist/http-operation/security.mjs +58 -0
  571. package/dist/http-operation/security.mjs.map +1 -0
  572. package/dist/http-operation/server.d.mts +33 -0
  573. package/dist/http-operation/server.mjs +268 -0
  574. package/dist/http-operation/server.mjs.map +1 -0
  575. package/dist/identity/ExternalIdentityMutation.d.mts +15 -0
  576. package/dist/identity/ExternalIdentityMutation.mjs +11 -0
  577. package/dist/identity/ExternalIdentityMutation.mjs.map +1 -0
  578. package/dist/identity/IdentityMutation.d.mts +22 -0
  579. package/dist/identity/IdentityMutation.mjs +17 -0
  580. package/dist/identity/IdentityMutation.mjs.map +1 -0
  581. package/dist/identity/IdentityRepository.d.mts +20 -0
  582. package/dist/identity/IdentityRepository.mjs +11 -0
  583. package/dist/identity/IdentityRepository.mjs.map +1 -0
  584. package/dist/identity/SubjectLifecycle.d.mts +58 -0
  585. package/dist/identity/SubjectLifecycle.mjs +43 -0
  586. package/dist/identity/SubjectLifecycle.mjs.map +1 -0
  587. package/dist/identity/SubjectProvisioner.d.mts +37 -0
  588. package/dist/identity/SubjectProvisioner.mjs +20 -0
  589. package/dist/identity/SubjectProvisioner.mjs.map +1 -0
  590. package/dist/identity/codecs.d.mts +34 -0
  591. package/dist/identity/codecs.mjs +40 -0
  592. package/dist/identity/codecs.mjs.map +1 -0
  593. package/dist/identity/models.d.mts +62 -0
  594. package/dist/identity/models.mjs +51 -0
  595. package/dist/identity/models.mjs.map +1 -0
  596. package/dist/identity/operations.d.mts +118 -0
  597. package/dist/identity/operations.mjs +124 -0
  598. package/dist/identity/operations.mjs.map +1 -0
  599. package/dist/index.d.mts +23 -0
  600. package/dist/index.mjs +23 -0
  601. package/dist/internal/AuthStoreDecisions.d.mts +22 -0
  602. package/dist/internal/AuthStoreDecisions.mjs +8 -0
  603. package/dist/internal/AuthStoreDecisions.mjs.map +1 -0
  604. package/dist/internal/CurrentSession.d.mts +9 -0
  605. package/dist/internal/CurrentSession.mjs +8 -0
  606. package/dist/internal/CurrentSession.mjs.map +1 -0
  607. package/dist/internal/diagnostics.mjs +23 -0
  608. package/dist/internal/diagnostics.mjs.map +1 -0
  609. package/dist/oauth/GithubOAuthProvider.d.mts +43 -0
  610. package/dist/oauth/GithubOAuthProvider.mjs +66 -0
  611. package/dist/oauth/GithubOAuthProvider.mjs.map +1 -0
  612. package/dist/oauth/OAuth.d.mts +73 -0
  613. package/dist/oauth/OAuth.mjs +180 -0
  614. package/dist/oauth/OAuth.mjs.map +1 -0
  615. package/dist/oauth/OAuthAccountsPersistence.d.mts +109 -0
  616. package/dist/oauth/OAuthAccountsPersistence.mjs +12 -0
  617. package/dist/oauth/OAuthAccountsPersistence.mjs.map +1 -0
  618. package/dist/oauth/OAuthActionEvidence.d.mts +28 -0
  619. package/dist/oauth/OAuthActionEvidence.mjs +15 -0
  620. package/dist/oauth/OAuthActionEvidence.mjs.map +1 -0
  621. package/dist/oauth/OAuthConnectedActionEvidence.d.mts +22 -0
  622. package/dist/oauth/OAuthConnectedActionEvidence.mjs +9 -0
  623. package/dist/oauth/OAuthConnectedActionEvidence.mjs.map +1 -0
  624. package/dist/oauth/OAuthConnectedPersistence.d.mts +129 -0
  625. package/dist/oauth/OAuthConnectedPersistence.mjs +12 -0
  626. package/dist/oauth/OAuthConnectedPersistence.mjs.map +1 -0
  627. package/dist/oauth/OAuthConnectedProtocol.d.mts +41 -0
  628. package/dist/oauth/OAuthConnectedProtocol.mjs +13 -0
  629. package/dist/oauth/OAuthConnectedProtocol.mjs.map +1 -0
  630. package/dist/oauth/OAuthConnectedRevocations.d.mts +167 -0
  631. package/dist/oauth/OAuthConnectedRevocations.mjs +21 -0
  632. package/dist/oauth/OAuthConnectedRevocations.mjs.map +1 -0
  633. package/dist/oauth/OAuthConnectedTokenProtector.d.mts +24 -0
  634. package/dist/oauth/OAuthConnectedTokenProtector.mjs +153 -0
  635. package/dist/oauth/OAuthConnectedTokenProtector.mjs.map +1 -0
  636. package/dist/oauth/OAuthConnectedTransactionProtector.d.mts +23 -0
  637. package/dist/oauth/OAuthConnectedTransactionProtector.mjs +37 -0
  638. package/dist/oauth/OAuthConnectedTransactionProtector.mjs.map +1 -0
  639. package/dist/oauth/OAuthConnectedUseAuthority.d.mts +22 -0
  640. package/dist/oauth/OAuthConnectedUseAuthority.mjs +10 -0
  641. package/dist/oauth/OAuthConnectedUseAuthority.mjs.map +1 -0
  642. package/dist/oauth/OAuthConnectionStore.d.mts +33 -0
  643. package/dist/oauth/OAuthConnectionStore.mjs +38 -0
  644. package/dist/oauth/OAuthConnectionStore.mjs.map +1 -0
  645. package/dist/oauth/OAuthLinkTransactionProtector.d.mts +25 -0
  646. package/dist/oauth/OAuthLinkTransactionProtector.mjs +39 -0
  647. package/dist/oauth/OAuthLinkTransactionProtector.mjs.map +1 -0
  648. package/dist/oauth/OAuthProtocol.d.mts +33 -0
  649. package/dist/oauth/OAuthProtocol.mjs +16 -0
  650. package/dist/oauth/OAuthProtocol.mjs.map +1 -0
  651. package/dist/oauth/OAuthProvider.d.mts +70 -0
  652. package/dist/oauth/OAuthProvider.mjs +39 -0
  653. package/dist/oauth/OAuthProvider.mjs.map +1 -0
  654. package/dist/oauth/OAuthProviders.d.mts +27 -0
  655. package/dist/oauth/OAuthProviders.mjs +33 -0
  656. package/dist/oauth/OAuthProviders.mjs.map +1 -0
  657. package/dist/oauth/OAuthRegistrationIntents.d.mts +87 -0
  658. package/dist/oauth/OAuthRegistrationIntents.mjs +19 -0
  659. package/dist/oauth/OAuthRegistrationIntents.mjs.map +1 -0
  660. package/dist/oauth/OAuthReturnTargets.d.mts +15 -0
  661. package/dist/oauth/OAuthReturnTargets.mjs +24 -0
  662. package/dist/oauth/OAuthReturnTargets.mjs.map +1 -0
  663. package/dist/oauth/OAuthSignInPersistence.d.mts +68 -0
  664. package/dist/oauth/OAuthSignInPersistence.mjs +12 -0
  665. package/dist/oauth/OAuthSignInPersistence.mjs.map +1 -0
  666. package/dist/oauth/OAuthStateDecisions.d.mts +14 -0
  667. package/dist/oauth/OAuthStateDecisions.mjs +8 -0
  668. package/dist/oauth/OAuthStateDecisions.mjs.map +1 -0
  669. package/dist/oauth/OAuthStateStore.d.mts +35 -0
  670. package/dist/oauth/OAuthStateStore.mjs +64 -0
  671. package/dist/oauth/OAuthStateStore.mjs.map +1 -0
  672. package/dist/oauth/OAuthTransactionProtector.d.mts +26 -0
  673. package/dist/oauth/OAuthTransactionProtector.mjs +78 -0
  674. package/dist/oauth/OAuthTransactionProtector.mjs.map +1 -0
  675. package/dist/oauth/accounts.d.mts +29 -0
  676. package/dist/oauth/accounts.mjs +515 -0
  677. package/dist/oauth/accounts.mjs.map +1 -0
  678. package/dist/oauth/accountsModels.d.mts +463 -0
  679. package/dist/oauth/accountsModels.mjs +155 -0
  680. package/dist/oauth/accountsModels.mjs.map +1 -0
  681. package/dist/oauth/connected.d.mts +442 -0
  682. package/dist/oauth/connected.mjs +526 -0
  683. package/dist/oauth/connected.mjs.map +1 -0
  684. package/dist/oauth/connectedAccess.d.mts +20 -0
  685. package/dist/oauth/connectedAccess.mjs +279 -0
  686. package/dist/oauth/connectedAccess.mjs.map +1 -0
  687. package/dist/oauth/connectedMaintenance.d.mts +19 -0
  688. package/dist/oauth/connectedMaintenance.mjs +133 -0
  689. package/dist/oauth/connectedMaintenance.mjs.map +1 -0
  690. package/dist/oauth/connectedModels.d.mts +2023 -0
  691. package/dist/oauth/connectedModels.mjs +375 -0
  692. package/dist/oauth/connectedModels.mjs.map +1 -0
  693. package/dist/oauth/definition.d.mts +4396 -0
  694. package/dist/oauth/definition.mjs +120 -0
  695. package/dist/oauth/definition.mjs.map +1 -0
  696. package/dist/oauth/errors.d.mts +49 -0
  697. package/dist/oauth/errors.mjs +42 -0
  698. package/dist/oauth/errors.mjs.map +1 -0
  699. package/dist/oauth/github/identity.d.mts +8 -0
  700. package/dist/oauth/github/identity.mjs +24 -0
  701. package/dist/oauth/github/identity.mjs.map +1 -0
  702. package/dist/oauth/github/models.d.mts +34 -0
  703. package/dist/oauth/github/protocol.d.mts +54 -0
  704. package/dist/oauth/github/protocol.mjs +204 -0
  705. package/dist/oauth/github/protocol.mjs.map +1 -0
  706. package/dist/oauth/openid-client/ProviderRevocation.d.mts +4 -0
  707. package/dist/oauth/openid-client/ProviderRevocation.mjs +11 -0
  708. package/dist/oauth/openid-client/ProviderRevocation.mjs.map +1 -0
  709. package/dist/oauth/openid-client/compatibility.d.mts +1 -0
  710. package/dist/oauth/openid-client/compatibility.mjs +6 -0
  711. package/dist/oauth/openid-client/compatibility.mjs.map +1 -0
  712. package/dist/oauth/openid-client/configuration.mjs +305 -0
  713. package/dist/oauth/openid-client/configuration.mjs.map +1 -0
  714. package/dist/oauth/openid-client/connected/configuration.mjs +338 -0
  715. package/dist/oauth/openid-client/connected/configuration.mjs.map +1 -0
  716. package/dist/oauth/openid-client/connected/models.d.mts +42 -0
  717. package/dist/oauth/openid-client/connected/protocol.d.mts +16 -0
  718. package/dist/oauth/openid-client/connected/protocol.mjs +402 -0
  719. package/dist/oauth/openid-client/connected/protocol.mjs.map +1 -0
  720. package/dist/oauth/openid-client/models.d.mts +67 -0
  721. package/dist/oauth/openid-client/models.mjs +16 -0
  722. package/dist/oauth/openid-client/models.mjs.map +1 -0
  723. package/dist/oauth/openid-client/protocol.d.mts +27 -0
  724. package/dist/oauth/openid-client/protocol.mjs +218 -0
  725. package/dist/oauth/openid-client/protocol.mjs.map +1 -0
  726. package/dist/oauth/openid-client/transport.mjs +59 -0
  727. package/dist/oauth/openid-client/transport.mjs.map +1 -0
  728. package/dist/oauth/policy.d.mts +18 -0
  729. package/dist/oauth/policy.mjs +16 -0
  730. package/dist/oauth/policy.mjs.map +1 -0
  731. package/dist/oauth/registration.d.mts +24 -0
  732. package/dist/oauth/registration.mjs +177 -0
  733. package/dist/oauth/registration.mjs.map +1 -0
  734. package/dist/oauth/registrationModels.d.mts +152 -0
  735. package/dist/oauth/registrationModels.mjs +93 -0
  736. package/dist/oauth/registrationModels.mjs.map +1 -0
  737. package/dist/oauth/registrationSecrets.mjs +70 -0
  738. package/dist/oauth/registrationSecrets.mjs.map +1 -0
  739. package/dist/oauth/schema.d.mts +86 -0
  740. package/dist/oauth/schema.mjs +81 -0
  741. package/dist/oauth/schema.mjs.map +1 -0
  742. package/dist/oauth/signInErrors.d.mts +17 -0
  743. package/dist/oauth/signInErrors.mjs +16 -0
  744. package/dist/oauth/signInErrors.mjs.map +1 -0
  745. package/dist/oauth/signInModels.d.mts +343 -0
  746. package/dist/oauth/signInModels.mjs +181 -0
  747. package/dist/oauth/signInModels.mjs.map +1 -0
  748. package/dist/oauth/signInModule.d.mts +1546 -0
  749. package/dist/oauth/signInModule.mjs +430 -0
  750. package/dist/oauth/signInModule.mjs.map +1 -0
  751. package/dist/oauth/signInSnapshot.mjs +29 -0
  752. package/dist/oauth/signInSnapshot.mjs.map +1 -0
  753. package/dist/oauth/transactionEncryption.d.mts +14 -0
  754. package/dist/oauth/transactionEncryption.mjs +129 -0
  755. package/dist/oauth/transactionEncryption.mjs.map +1 -0
  756. package/dist/operations/RequestBindingConfig.d.mts +11 -0
  757. package/dist/operations/RequestBindingConfig.mjs +10 -0
  758. package/dist/operations/RequestBindingConfig.mjs.map +1 -0
  759. package/dist/operations/actions.d.mts +947 -0
  760. package/dist/operations/actions.mjs +148 -0
  761. package/dist/operations/actions.mjs.map +1 -0
  762. package/dist/operations/context.d.mts +63 -0
  763. package/dist/operations/context.mjs +55 -0
  764. package/dist/operations/context.mjs.map +1 -0
  765. package/dist/operations/credentials.d.mts +39 -0
  766. package/dist/operations/credentials.mjs +60 -0
  767. package/dist/operations/credentials.mjs.map +1 -0
  768. package/dist/operations/errors.d.mts +24 -0
  769. package/dist/operations/errors.mjs +31 -0
  770. package/dist/operations/errors.mjs.map +1 -0
  771. package/dist/operations/operation.d.mts +124 -0
  772. package/dist/operations/operation.mjs +220 -0
  773. package/dist/operations/operation.mjs.map +1 -0
  774. package/dist/operations/requestBinding.d.mts +46 -0
  775. package/dist/operations/requestBinding.mjs +130 -0
  776. package/dist/operations/requestBinding.mjs.map +1 -0
  777. package/dist/operations/requestBindingModels.d.mts +13 -0
  778. package/dist/operations/requestBindingModels.mjs +12 -0
  779. package/dist/operations/requestBindingModels.mjs.map +1 -0
  780. package/dist/operations/reveals.d.mts +28 -0
  781. package/dist/operations/reveals.mjs +88 -0
  782. package/dist/operations/reveals.mjs.map +1 -0
  783. package/dist/passkey/PasskeyActionEvidence.d.mts +22 -0
  784. package/dist/passkey/PasskeyActionEvidence.mjs +9 -0
  785. package/dist/passkey/PasskeyActionEvidence.mjs.map +1 -0
  786. package/dist/passkey/PasskeyCredentials.d.mts +16 -0
  787. package/dist/passkey/PasskeyCredentials.mjs +9 -0
  788. package/dist/passkey/PasskeyCredentials.mjs.map +1 -0
  789. package/dist/passkey/PasskeyEnrollmentContext.d.mts +22 -0
  790. package/dist/passkey/PasskeyEnrollmentContext.mjs +9 -0
  791. package/dist/passkey/PasskeyEnrollmentContext.mjs.map +1 -0
  792. package/dist/passkey/PasskeyManagementPersistence.d.mts +106 -0
  793. package/dist/passkey/PasskeyManagementPersistence.mjs +9 -0
  794. package/dist/passkey/PasskeyManagementPersistence.mjs.map +1 -0
  795. package/dist/passkey/PasskeyPersistence.d.mts +63 -0
  796. package/dist/passkey/PasskeyPersistence.mjs +10 -0
  797. package/dist/passkey/PasskeyPersistence.mjs.map +1 -0
  798. package/dist/passkey/PasskeyProtocol.d.mts +38 -0
  799. package/dist/passkey/PasskeyProtocol.mjs +11 -0
  800. package/dist/passkey/PasskeyProtocol.mjs.map +1 -0
  801. package/dist/passkey/actions.d.mts +50 -0
  802. package/dist/passkey/actions.mjs +376 -0
  803. package/dist/passkey/actions.mjs.map +1 -0
  804. package/dist/passkey/browser/PasskeyBrowser.d.mts +18 -0
  805. package/dist/passkey/browser/PasskeyBrowser.mjs +9 -0
  806. package/dist/passkey/browser/PasskeyBrowser.mjs.map +1 -0
  807. package/dist/passkey/browser/models.d.mts +38 -0
  808. package/dist/passkey/browser/models.mjs +41 -0
  809. package/dist/passkey/browser/models.mjs.map +1 -0
  810. package/dist/passkey/browser/simplewebauthn.d.mts +17 -0
  811. package/dist/passkey/browser/simplewebauthn.mjs +411 -0
  812. package/dist/passkey/browser/simplewebauthn.mjs.map +1 -0
  813. package/dist/passkey/definition.d.mts +5626 -0
  814. package/dist/passkey/definition.mjs +114 -0
  815. package/dist/passkey/definition.mjs.map +1 -0
  816. package/dist/passkey/errors.d.mts +20 -0
  817. package/dist/passkey/errors.mjs +20 -0
  818. package/dist/passkey/errors.mjs.map +1 -0
  819. package/dist/passkey/management.mjs +276 -0
  820. package/dist/passkey/management.mjs.map +1 -0
  821. package/dist/passkey/models.d.mts +1245 -0
  822. package/dist/passkey/models.mjs +301 -0
  823. package/dist/passkey/models.mjs.map +1 -0
  824. package/dist/passkey/module.d.mts +2132 -0
  825. package/dist/passkey/module.mjs +174 -0
  826. package/dist/passkey/module.mjs.map +1 -0
  827. package/dist/passkey/pending.mjs +99 -0
  828. package/dist/passkey/pending.mjs.map +1 -0
  829. package/dist/passkey/policy.d.mts +48 -0
  830. package/dist/passkey/policy.mjs +77 -0
  831. package/dist/passkey/policy.mjs.map +1 -0
  832. package/dist/passkey/registration.mjs +107 -0
  833. package/dist/passkey/registration.mjs.map +1 -0
  834. package/dist/passkey/simplewebauthn/configuration.mjs +45 -0
  835. package/dist/passkey/simplewebauthn/configuration.mjs.map +1 -0
  836. package/dist/passkey/simplewebauthn/models.d.mts +21 -0
  837. package/dist/passkey/simplewebauthn/models.mjs +8 -0
  838. package/dist/passkey/simplewebauthn/models.mjs.map +1 -0
  839. package/dist/passkey/simplewebauthn/protocol.d.mts +62 -0
  840. package/dist/passkey/simplewebauthn/protocol.mjs +402 -0
  841. package/dist/passkey/simplewebauthn/protocol.mjs.map +1 -0
  842. package/dist/passkey/snapshot.mjs +31 -0
  843. package/dist/passkey/snapshot.mjs.map +1 -0
  844. package/dist/passkey/stepUp.mjs +101 -0
  845. package/dist/passkey/stepUp.mjs.map +1 -0
  846. package/dist/password/CompromisedPasswords.d.mts +26 -0
  847. package/dist/password/CompromisedPasswords.mjs +23 -0
  848. package/dist/password/CompromisedPasswords.mjs.map +1 -0
  849. package/dist/password/NewPasswordCheck.d.mts +21 -0
  850. package/dist/password/NewPasswordCheck.mjs +39 -0
  851. package/dist/password/NewPasswordCheck.mjs.map +1 -0
  852. package/dist/password/PasswordHashing.d.mts +24 -0
  853. package/dist/password/PasswordHashing.mjs +96 -0
  854. package/dist/password/PasswordHashing.mjs.map +1 -0
  855. package/dist/password/PasswordKdfAdmission.d.mts +19 -0
  856. package/dist/password/PasswordKdfAdmission.mjs +25 -0
  857. package/dist/password/PasswordKdfAdmission.mjs.map +1 -0
  858. package/dist/password/configuration.d.mts +43 -0
  859. package/dist/password/configuration.mjs +64 -0
  860. package/dist/password/configuration.mjs.map +1 -0
  861. package/dist/password/defaults.mjs +13 -0
  862. package/dist/password/defaults.mjs.map +1 -0
  863. package/dist/password/encoding.mjs +64 -0
  864. package/dist/password/encoding.mjs.map +1 -0
  865. package/dist/password/errors.d.mts +28 -0
  866. package/dist/password/errors.mjs +25 -0
  867. package/dist/password/errors.mjs.map +1 -0
  868. package/dist/password/methods/PasswordActionEvidence.d.mts +38 -0
  869. package/dist/password/methods/PasswordActionEvidence.mjs +22 -0
  870. package/dist/password/methods/PasswordActionEvidence.mjs.map +1 -0
  871. package/dist/password/methods/PasswordPersistence.d.mts +102 -0
  872. package/dist/password/methods/PasswordPersistence.mjs +13 -0
  873. package/dist/password/methods/PasswordPersistence.mjs.map +1 -0
  874. package/dist/password/methods/PasswordPreparedPersistence.d.mts +111 -0
  875. package/dist/password/methods/contracts.d.mts +43 -0
  876. package/dist/password/methods/contracts.mjs +33 -0
  877. package/dist/password/methods/contracts.mjs.map +1 -0
  878. package/dist/password/methods/definition.d.mts +3813 -0
  879. package/dist/password/methods/definition.mjs +56 -0
  880. package/dist/password/methods/definition.mjs.map +1 -0
  881. package/dist/password/methods/errors.d.mts +15 -0
  882. package/dist/password/methods/errors.mjs +11 -0
  883. package/dist/password/methods/errors.mjs.map +1 -0
  884. package/dist/password/methods/models.d.mts +70 -0
  885. package/dist/password/methods/models.mjs +44 -0
  886. package/dist/password/methods/models.mjs.map +1 -0
  887. package/dist/password/methods/module.d.mts +3567 -0
  888. package/dist/password/methods/module.mjs +553 -0
  889. package/dist/password/methods/module.mjs.map +1 -0
  890. package/dist/password/methods/policy.d.mts +84 -0
  891. package/dist/password/methods/policy.mjs +80 -0
  892. package/dist/password/methods/policy.mjs.map +1 -0
  893. package/dist/password/methods/preparation.mjs +54 -0
  894. package/dist/password/methods/preparation.mjs.map +1 -0
  895. package/dist/password/methods/prepared.d.mts +53 -0
  896. package/dist/password/methods/prepared.mjs +610 -0
  897. package/dist/password/methods/prepared.mjs.map +1 -0
  898. package/dist/password/methods/preparedModels.d.mts +1295 -0
  899. package/dist/password/methods/preparedModels.mjs +278 -0
  900. package/dist/password/methods/preparedModels.mjs.map +1 -0
  901. package/dist/password/methods/signIn.d.mts +180 -0
  902. package/dist/password/methods/signIn.mjs +73 -0
  903. package/dist/password/methods/signIn.mjs.map +1 -0
  904. package/dist/password/methods/snapshot.mjs +38 -0
  905. package/dist/password/methods/snapshot.mjs.map +1 -0
  906. package/dist/password/methods/verification.mjs +138 -0
  907. package/dist/password/methods/verification.mjs.map +1 -0
  908. package/dist/password/models.d.mts +13 -0
  909. package/dist/password/models.mjs +12 -0
  910. package/dist/password/models.mjs.map +1 -0
  911. package/dist/password/policy.d.mts +33 -0
  912. package/dist/password/policy.mjs +37 -0
  913. package/dist/password/policy.mjs.map +1 -0
  914. package/dist/phone/PhoneActionEvidence.d.mts +23 -0
  915. package/dist/phone/PhoneActionEvidence.mjs +10 -0
  916. package/dist/phone/PhoneActionEvidence.mjs.map +1 -0
  917. package/dist/phone/PhoneAdmission.d.mts +29 -0
  918. package/dist/phone/PhoneAdmission.mjs +10 -0
  919. package/dist/phone/PhoneAdmission.mjs.map +1 -0
  920. package/dist/phone/PhoneDeliveryEligibility.d.mts +11 -0
  921. package/dist/phone/PhoneDeliveryEligibility.mjs +8 -0
  922. package/dist/phone/PhoneDeliveryEligibility.mjs.map +1 -0
  923. package/dist/phone/PhonePersistence.d.mts +33 -0
  924. package/dist/phone/PhonePersistence.mjs +10 -0
  925. package/dist/phone/PhonePersistence.mjs.map +1 -0
  926. package/dist/phone/PhoneRequestContext.d.mts +10 -0
  927. package/dist/phone/PhoneRequestContext.mjs +8 -0
  928. package/dist/phone/PhoneRequestContext.mjs.map +1 -0
  929. package/dist/phone/PhoneSignInTargets.d.mts +19 -0
  930. package/dist/phone/PhoneSignInTargets.mjs +13 -0
  931. package/dist/phone/PhoneSignInTargets.mjs.map +1 -0
  932. package/dist/phone/definition.d.mts +7190 -0
  933. package/dist/phone/definition.mjs +28 -0
  934. package/dist/phone/definition.mjs.map +1 -0
  935. package/dist/phone/failure.mjs +23 -0
  936. package/dist/phone/failure.mjs.map +1 -0
  937. package/dist/phone/lifecycle.mjs +427 -0
  938. package/dist/phone/lifecycle.mjs.map +1 -0
  939. package/dist/phone/lifecycleModels.d.mts +164 -0
  940. package/dist/phone/lifecycleModels.mjs +91 -0
  941. package/dist/phone/lifecycleModels.mjs.map +1 -0
  942. package/dist/phone/models.d.mts +41 -0
  943. package/dist/phone/models.mjs +29 -0
  944. package/dist/phone/models.mjs.map +1 -0
  945. package/dist/phone/module.d.mts +6027 -0
  946. package/dist/phone/module.mjs +293 -0
  947. package/dist/phone/module.mjs.map +1 -0
  948. package/dist/proofs/EmailProofDelivery.d.mts +13 -0
  949. package/dist/proofs/EmailProofDelivery.mjs +11 -0
  950. package/dist/proofs/EmailProofDelivery.mjs.map +1 -0
  951. package/dist/proofs/HostIngressLimiter.d.mts +20 -0
  952. package/dist/proofs/HostIngressLimiter.mjs +13 -0
  953. package/dist/proofs/HostIngressLimiter.mjs.map +1 -0
  954. package/dist/proofs/ProofPersistence.d.mts +140 -0
  955. package/dist/proofs/ProofPersistence.mjs +13 -0
  956. package/dist/proofs/ProofPersistence.mjs.map +1 -0
  957. package/dist/proofs/SmsProofDelivery.d.mts +13 -0
  958. package/dist/proofs/SmsProofDelivery.mjs +11 -0
  959. package/dist/proofs/SmsProofDelivery.mjs.map +1 -0
  960. package/dist/proofs/abuse.d.mts +15 -0
  961. package/dist/proofs/abuse.mjs +12 -0
  962. package/dist/proofs/abuse.mjs.map +1 -0
  963. package/dist/proofs/completion.d.mts +22 -0
  964. package/dist/proofs/crypto.d.mts +196 -0
  965. package/dist/proofs/crypto.mjs +189 -0
  966. package/dist/proofs/crypto.mjs.map +1 -0
  967. package/dist/proofs/definition.d.mts +335 -0
  968. package/dist/proofs/definition.mjs +10 -0
  969. package/dist/proofs/definition.mjs.map +1 -0
  970. package/dist/proofs/delivery.d.mts +30 -0
  971. package/dist/proofs/delivery.mjs +26 -0
  972. package/dist/proofs/delivery.mjs.map +1 -0
  973. package/dist/proofs/dispatch.d.mts +20 -0
  974. package/dist/proofs/dispatch.mjs +54 -0
  975. package/dist/proofs/dispatch.mjs.map +1 -0
  976. package/dist/proofs/errors.d.mts +21 -0
  977. package/dist/proofs/errors.mjs +25 -0
  978. package/dist/proofs/errors.mjs.map +1 -0
  979. package/dist/proofs/models.d.mts +141 -0
  980. package/dist/proofs/models.mjs +93 -0
  981. package/dist/proofs/models.mjs.map +1 -0
  982. package/dist/proofs/module.d.mts +344 -0
  983. package/dist/proofs/module.mjs +350 -0
  984. package/dist/proofs/module.mjs.map +1 -0
  985. package/dist/proofs/policy.d.mts +152 -0
  986. package/dist/proofs/policy.mjs +51 -0
  987. package/dist/proofs/policy.mjs.map +1 -0
  988. package/dist/sessions/AuthenticationAuthority.d.mts +31 -0
  989. package/dist/sessions/AuthenticationAuthority.mjs +8 -0
  990. package/dist/sessions/AuthenticationAuthority.mjs.map +1 -0
  991. package/dist/sessions/PendingAuthentication.d.mts +108 -0
  992. package/dist/sessions/PendingAuthentication.mjs +40 -0
  993. package/dist/sessions/PendingAuthentication.mjs.map +1 -0
  994. package/dist/sessions/SessionStepUpPersistence.d.mts +152 -0
  995. package/dist/sessions/SessionStepUpPersistence.mjs +63 -0
  996. package/dist/sessions/SessionStepUpPersistence.mjs.map +1 -0
  997. package/dist/sessions/assurance.d.mts +163 -0
  998. package/dist/sessions/assurance.mjs +95 -0
  999. package/dist/sessions/assurance.mjs.map +1 -0
  1000. package/dist/sessions/commit.d.mts +13 -0
  1001. package/dist/sessions/configuration.d.mts +46 -0
  1002. package/dist/sessions/configuration.mjs +55 -0
  1003. package/dist/sessions/configuration.mjs.map +1 -0
  1004. package/dist/sessions/contract.d.mts +663 -0
  1005. package/dist/sessions/contract.mjs +174 -0
  1006. package/dist/sessions/contract.mjs.map +1 -0
  1007. package/dist/sessions/crypto.d.mts +24 -0
  1008. package/dist/sessions/crypto.mjs +106 -0
  1009. package/dist/sessions/crypto.mjs.map +1 -0
  1010. package/dist/sessions/definition.d.mts +11 -0
  1011. package/dist/sessions/definition.mjs +10 -0
  1012. package/dist/sessions/definition.mjs.map +1 -0
  1013. package/dist/sessions/errors.d.mts +35 -0
  1014. package/dist/sessions/errors.mjs +34 -0
  1015. package/dist/sessions/errors.mjs.map +1 -0
  1016. package/dist/sessions/invalidation.d.mts +23 -0
  1017. package/dist/sessions/invalidation.mjs +33 -0
  1018. package/dist/sessions/invalidation.mjs.map +1 -0
  1019. package/dist/sessions/models.d.mts +143 -0
  1020. package/dist/sessions/models.mjs +94 -0
  1021. package/dist/sessions/models.mjs.map +1 -0
  1022. package/dist/sessions/module.d.mts +1091 -0
  1023. package/dist/sessions/module.mjs +943 -0
  1024. package/dist/sessions/module.mjs.map +1 -0
  1025. package/dist/sessions/persistence.d.mts +93 -0
  1026. package/dist/sessions/policy.d.mts +80 -0
  1027. package/dist/sessions/policy.mjs +66 -0
  1028. package/dist/sessions/policy.mjs.map +1 -0
  1029. package/dist/testing/conformance/AuthStore.d.mts +11 -0
  1030. package/dist/testing/conformance/AuthStore.mjs +173 -0
  1031. package/dist/testing/conformance/AuthStore.mjs.map +1 -0
  1032. package/dist/testing/conformance/OAuthConnectionStore.d.mts +11 -0
  1033. package/dist/testing/conformance/OAuthConnectionStore.mjs +102 -0
  1034. package/dist/testing/conformance/OAuthConnectionStore.mjs.map +1 -0
  1035. package/dist/testing/conformance/OAuthStateStore.d.mts +11 -0
  1036. package/dist/testing/conformance/OAuthStateStore.mjs +45 -0
  1037. package/dist/testing/conformance/OAuthStateStore.mjs.map +1 -0
  1038. package/dist/testing/conformance/PasswordCredentialStore.d.mts +20 -0
  1039. package/dist/testing/conformance/PasswordCredentialStore.mjs +103 -0
  1040. package/dist/testing/conformance/PasswordCredentialStore.mjs.map +1 -0
  1041. package/dist/testing/conformance/support.mjs +17 -0
  1042. package/dist/testing/conformance/support.mjs.map +1 -0
  1043. package/dist/testing/crypto.d.mts +11 -0
  1044. package/dist/testing/crypto.mjs +41 -0
  1045. package/dist/testing/crypto.mjs.map +1 -0
  1046. package/dist/testing/keyring.d.mts +9 -0
  1047. package/dist/testing/keyring.mjs +17 -0
  1048. package/dist/testing/keyring.mjs.map +1 -0
  1049. package/dist/totp/TotpActionEvidence.d.mts +18 -0
  1050. package/dist/totp/TotpActionEvidence.mjs +8 -0
  1051. package/dist/totp/TotpActionEvidence.mjs.map +1 -0
  1052. package/dist/totp/TotpPersistence.d.mts +19 -0
  1053. package/dist/totp/TotpPersistence.mjs +8 -0
  1054. package/dist/totp/TotpPersistence.mjs.map +1 -0
  1055. package/dist/totp/TotpSecretKeys.d.mts +15 -0
  1056. package/dist/totp/TotpSecretKeys.mjs +8 -0
  1057. package/dist/totp/TotpSecretKeys.mjs.map +1 -0
  1058. package/dist/totp/crypto.mjs +96 -0
  1059. package/dist/totp/crypto.mjs.map +1 -0
  1060. package/dist/totp/definition.d.mts +764 -0
  1061. package/dist/totp/definition.mjs +24 -0
  1062. package/dist/totp/definition.mjs.map +1 -0
  1063. package/dist/totp/errors.d.mts +16 -0
  1064. package/dist/totp/errors.mjs +18 -0
  1065. package/dist/totp/errors.mjs.map +1 -0
  1066. package/dist/totp/models.d.mts +377 -0
  1067. package/dist/totp/models.mjs +137 -0
  1068. package/dist/totp/models.mjs.map +1 -0
  1069. package/dist/totp/module.d.mts +737 -0
  1070. package/dist/totp/module.mjs +355 -0
  1071. package/dist/totp/module.mjs.map +1 -0
  1072. package/package.json +1 -0
  1073. package/src/Atom.ts +4 -0
  1074. package/src/Auth.ts +16 -0
  1075. package/src/AuthContract.ts +17 -0
  1076. package/src/AuthSession.ts +298 -0
  1077. package/src/AuthStore.ts +367 -0
  1078. package/src/AuthTokenCodec.ts +226 -0
  1079. package/src/Client.ts +9 -0
  1080. package/src/Cloudflare.ts +345 -0
  1081. package/src/Drizzle.ts +378 -0
  1082. package/src/DrizzleD1.ts +136 -0
  1083. package/src/DrizzleLibsql.ts +288 -0
  1084. package/src/DrizzleMysql2.ts +184 -0
  1085. package/src/DrizzlePglite.ts +160 -0
  1086. package/src/DrizzlePostgres.ts +160 -0
  1087. package/src/DrizzleSqliteBun.ts +244 -0
  1088. package/src/DrizzleSqliteDo.ts +473 -0
  1089. package/src/DrizzleSqliteNode.ts +245 -0
  1090. package/src/DrizzleSqliteWasm.ts +245 -0
  1091. package/src/Email.ts +55 -0
  1092. package/src/EmailOtp.ts +250 -0
  1093. package/src/EmailOtpSender.ts +28 -0
  1094. package/src/Errors.ts +103 -0
  1095. package/src/GitHub.ts +16 -0
  1096. package/src/Hooks.ts +50 -0
  1097. package/src/Http.ts +47 -0
  1098. package/src/HttpServer.ts +742 -0
  1099. package/src/Identity.ts +53 -0
  1100. package/src/IdentityResolver.ts +18 -0
  1101. package/src/OAuth.ts +242 -0
  1102. package/src/OpenIdClient.ts +13 -0
  1103. package/src/OpenIdClientConnected.ts +18 -0
  1104. package/src/OperationHttp.ts +14 -0
  1105. package/src/OperationHttpClient.ts +6 -0
  1106. package/src/OperationHttpServer.ts +15 -0
  1107. package/src/Operations.ts +69 -0
  1108. package/src/Passkey.ts +81 -0
  1109. package/src/PasskeyBrowser.ts +19 -0
  1110. package/src/PasskeyContract.ts +212 -0
  1111. package/src/PasskeyPassword.ts +319 -0
  1112. package/src/PasskeySimpleWebAuthn.ts +6 -0
  1113. package/src/Password.ts +113 -0
  1114. package/src/PasswordAuth.ts +197 -0
  1115. package/src/PasswordCredentialStore.ts +140 -0
  1116. package/src/PasswordHasher.ts +147 -0
  1117. package/src/PhoneOtp.ts +32 -0
  1118. package/src/Policy.ts +95 -0
  1119. package/src/Proofs.ts +71 -0
  1120. package/src/Rpc.ts +15 -0
  1121. package/src/Schema.ts +235 -0
  1122. package/src/SessionContract.ts +2 -0
  1123. package/src/Sessions.ts +105 -0
  1124. package/src/Testing.ts +24 -0
  1125. package/src/Totp.ts +28 -0
  1126. package/src/TotpContract.ts +147 -0
  1127. package/src/WebCrypto.ts +61 -0
  1128. package/src/Workflows.ts +12 -0
  1129. package/src/atom/AuthAtomLifetime.ts +87 -0
  1130. package/src/atom/AuthAtomWorkflow.ts +27 -0
  1131. package/src/atom/client.ts +364 -0
  1132. package/src/atom/operations.ts +183 -0
  1133. package/src/atom/scoped-runtime.ts +249 -0
  1134. package/src/auth/Auth.ts +482 -0
  1135. package/src/auth/AuthConfigurationError.ts +9 -0
  1136. package/src/auth/AuthRequest.ts +21 -0
  1137. package/src/auth/AuthStrategy.ts +116 -0
  1138. package/src/auth/ConsumeDecision.ts +4 -0
  1139. package/src/auth/actions.ts +220 -0
  1140. package/src/auth/defaults.ts +23 -0
  1141. package/src/auth/definition.ts +88 -0
  1142. package/src/auth/session.ts +146 -0
  1143. package/src/drizzle/D1BatchStatements.ts +10 -0
  1144. package/src/drizzle/PasswordPreparedPostconditions.ts +30 -0
  1145. package/src/drizzle/SuppliedService.ts +10 -0
  1146. package/src/drizzle/d1-emails.ts +1808 -0
  1147. package/src/drizzle/d1-generated-statement.ts +129 -0
  1148. package/src/drizzle/d1-identity.ts +374 -0
  1149. package/src/drizzle/d1-oauth.ts +338 -0
  1150. package/src/drizzle/d1-passkey.ts +371 -0
  1151. package/src/drizzle/d1-password-prepared.ts +1273 -0
  1152. package/src/drizzle/d1-passwords.ts +2661 -0
  1153. package/src/drizzle/d1-phone.ts +94 -0
  1154. package/src/drizzle/d1-planning.ts +105 -0
  1155. package/src/drizzle/d1-proofs.ts +2305 -0
  1156. package/src/drizzle/d1-sessions.ts +2867 -0
  1157. package/src/drizzle/d1-totp.ts +79 -0
  1158. package/src/drizzle/email-model.ts +512 -0
  1159. package/src/drizzle/email-registration.ts +696 -0
  1160. package/src/drizzle/email-sql.ts +1468 -0
  1161. package/src/drizzle/email-target.ts +243 -0
  1162. package/src/drizzle/model.ts +492 -0
  1163. package/src/drizzle/mysql-emails.ts +323 -0
  1164. package/src/drizzle/mysql-identity.ts +323 -0
  1165. package/src/drizzle/mysql-password-prepared.ts +206 -0
  1166. package/src/drizzle/mysql-passwords.ts +341 -0
  1167. package/src/drizzle/mysql-proofs.ts +183 -0
  1168. package/src/drizzle/mysql-sessions.ts +742 -0
  1169. package/src/drizzle/mysql.ts +686 -0
  1170. package/src/drizzle/oauth-accounts.ts +801 -0
  1171. package/src/drizzle/oauth-connected-access.ts +354 -0
  1172. package/src/drizzle/oauth-connected-collection.ts +324 -0
  1173. package/src/drizzle/oauth-connected-custody.ts +277 -0
  1174. package/src/drizzle/oauth-connected-drivers.ts +463 -0
  1175. package/src/drizzle/oauth-connected-flow.ts +439 -0
  1176. package/src/drizzle/oauth-connected-input.ts +128 -0
  1177. package/src/drizzle/oauth-connected-maintenance.ts +345 -0
  1178. package/src/drizzle/oauth-connected-management.ts +365 -0
  1179. package/src/drizzle/oauth-connected-model.ts +347 -0
  1180. package/src/drizzle/oauth-connected-reference.ts +112 -0
  1181. package/src/drizzle/oauth-connected-settlement.ts +226 -0
  1182. package/src/drizzle/oauth-connected-state.ts +846 -0
  1183. package/src/drizzle/oauth-connected-target.ts +264 -0
  1184. package/src/drizzle/oauth-drivers.ts +567 -0
  1185. package/src/drizzle/oauth-flow.ts +461 -0
  1186. package/src/drizzle/oauth-input.ts +205 -0
  1187. package/src/drizzle/oauth-model.ts +610 -0
  1188. package/src/drizzle/oauth-mysql.ts +10 -0
  1189. package/src/drizzle/oauth-owner.ts +29 -0
  1190. package/src/drizzle/oauth-registration.ts +638 -0
  1191. package/src/drizzle/oauth-state.ts +213 -0
  1192. package/src/drizzle/oauth-target.ts +751 -0
  1193. package/src/drizzle/passkey-admission.ts +333 -0
  1194. package/src/drizzle/passkey-credentials.ts +465 -0
  1195. package/src/drizzle/passkey-drivers.ts +385 -0
  1196. package/src/drizzle/passkey-enrollment.ts +280 -0
  1197. package/src/drizzle/passkey-flow.ts +983 -0
  1198. package/src/drizzle/passkey-management.ts +369 -0
  1199. package/src/drizzle/passkey-model.ts +350 -0
  1200. package/src/drizzle/passkey-registration-ceremony-model.ts +69 -0
  1201. package/src/drizzle/passkey-registration-ceremony.ts +254 -0
  1202. package/src/drizzle/passkey-registration-custody.ts +82 -0
  1203. package/src/drizzle/passkey-registration-write.ts +378 -0
  1204. package/src/drizzle/passkey-state.ts +307 -0
  1205. package/src/drizzle/passkey-target.ts +528 -0
  1206. package/src/drizzle/passkey-write-drivers.ts +396 -0
  1207. package/src/drizzle/passkey-write-model.ts +265 -0
  1208. package/src/drizzle/passkey-write-state.ts +627 -0
  1209. package/src/drizzle/passkey-write-target.ts +406 -0
  1210. package/src/drizzle/password-model.ts +491 -0
  1211. package/src/drizzle/password-prepared-model.ts +259 -0
  1212. package/src/drizzle/password-prepared-sql.ts +1198 -0
  1213. package/src/drizzle/password-prepared-state.ts +232 -0
  1214. package/src/drizzle/password-prepared-target.ts +158 -0
  1215. package/src/drizzle/password-registration.ts +372 -0
  1216. package/src/drizzle/password-sql.ts +2082 -0
  1217. package/src/drizzle/password-target.ts +223 -0
  1218. package/src/drizzle/pg-emails.ts +323 -0
  1219. package/src/drizzle/pg-password-prepared.ts +207 -0
  1220. package/src/drizzle/pg-passwords.ts +340 -0
  1221. package/src/drizzle/pg-proofs.ts +193 -0
  1222. package/src/drizzle/pg-sessions.ts +751 -0
  1223. package/src/drizzle/pg.ts +982 -0
  1224. package/src/drizzle/phone-model.ts +185 -0
  1225. package/src/drizzle/phone-state.ts +802 -0
  1226. package/src/drizzle/phone-target.ts +471 -0
  1227. package/src/drizzle/proof-model.ts +398 -0
  1228. package/src/drizzle/proof-sql.ts +1912 -0
  1229. package/src/drizzle/proof-target.ts +120 -0
  1230. package/src/drizzle/session-model.ts +368 -0
  1231. package/src/drizzle/session-sql.ts +2152 -0
  1232. package/src/drizzle/session-target.ts +335 -0
  1233. package/src/drizzle/sqlite-emails.ts +368 -0
  1234. package/src/drizzle/sqlite-identity.ts +343 -0
  1235. package/src/drizzle/sqlite-password-prepared.ts +262 -0
  1236. package/src/drizzle/sqlite-passwords.ts +499 -0
  1237. package/src/drizzle/sqlite-proofs.ts +204 -0
  1238. package/src/drizzle/sqlite-sessions.ts +972 -0
  1239. package/src/drizzle/sqlite.ts +704 -0
  1240. package/src/drizzle/standalone-guard.ts +38 -0
  1241. package/src/drizzle/step-up-model.ts +129 -0
  1242. package/src/drizzle/step-up-state.ts +141 -0
  1243. package/src/drizzle/totp-model.ts +91 -0
  1244. package/src/drizzle/totp-state.ts +520 -0
  1245. package/src/drizzle/totp-target.ts +304 -0
  1246. package/src/drizzle/transaction-execution.ts +290 -0
  1247. package/src/drizzle/transaction-mysql.ts +104 -0
  1248. package/src/drizzle/transaction-owner.ts +570 -0
  1249. package/src/email/EmailActionEvidence.ts +37 -0
  1250. package/src/email/EmailAddressPersistence.ts +71 -0
  1251. package/src/email/EmailIdentifierNotifier.ts +48 -0
  1252. package/src/email/EmailReturnTargets.ts +50 -0
  1253. package/src/email/EmailSignInTargets.ts +20 -0
  1254. package/src/email/addresses.ts +630 -0
  1255. package/src/email/definition.ts +309 -0
  1256. package/src/email/errors.ts +23 -0
  1257. package/src/email/magicLink.ts +84 -0
  1258. package/src/email/models.ts +50 -0
  1259. package/src/email/module.ts +664 -0
  1260. package/src/email/registration.ts +415 -0
  1261. package/src/email/snapshot.ts +51 -0
  1262. package/src/hooks/LifecycleHooks.ts +136 -0
  1263. package/src/hooks/commit.ts +271 -0
  1264. package/src/hooks/models.ts +111 -0
  1265. package/src/hooks/plugins.ts +87 -0
  1266. package/src/hooks/transactions.ts +51 -0
  1267. package/src/http/auth-api.ts +17 -0
  1268. package/src/http/auth-contract.ts +148 -0
  1269. package/src/http/auth-http.ts +467 -0
  1270. package/src/http/endpoints/get-session.ts +9 -0
  1271. package/src/http/endpoints/password-sign-in.ts +19 -0
  1272. package/src/http/endpoints/request-email-otp.ts +10 -0
  1273. package/src/http/endpoints/set-password.ts +18 -0
  1274. package/src/http/endpoints/sign-out.ts +5 -0
  1275. package/src/http/endpoints/verify-email-otp.ts +15 -0
  1276. package/src/http/models.ts +80 -0
  1277. package/src/http/security.ts +102 -0
  1278. package/src/http/session-contract.ts +92 -0
  1279. package/src/http-operation/OperationHttpInvocation.ts +39 -0
  1280. package/src/http-operation/OperationHttpServerConfig.ts +124 -0
  1281. package/src/http-operation/auth-client.ts +273 -0
  1282. package/src/http-operation/client.ts +453 -0
  1283. package/src/http-operation/configuration-schema.ts +19 -0
  1284. package/src/http-operation/contract.ts +116 -0
  1285. package/src/http-operation/errors.ts +38 -0
  1286. package/src/http-operation/models.ts +42 -0
  1287. package/src/http-operation/private.ts +50 -0
  1288. package/src/http-operation/security.ts +93 -0
  1289. package/src/http-operation/server.ts +544 -0
  1290. package/src/identity/ExternalIdentityMutation.ts +18 -0
  1291. package/src/identity/IdentityMutation.ts +41 -0
  1292. package/src/identity/IdentityRepository.ts +37 -0
  1293. package/src/identity/SubjectLifecycle.ts +80 -0
  1294. package/src/identity/SubjectProvisioner.ts +40 -0
  1295. package/src/identity/codecs.ts +54 -0
  1296. package/src/identity/models.ts +82 -0
  1297. package/src/identity/operations.ts +182 -0
  1298. package/src/index.ts +23 -0
  1299. package/src/internal/AuthStoreDecisions.ts +23 -0
  1300. package/src/internal/CurrentSession.ts +8 -0
  1301. package/src/internal/diagnostics.ts +71 -0
  1302. package/src/oauth/GithubOAuthProvider.ts +106 -0
  1303. package/src/oauth/OAuth.ts +436 -0
  1304. package/src/oauth/OAuthAccountsPersistence.ts +142 -0
  1305. package/src/oauth/OAuthActionEvidence.ts +31 -0
  1306. package/src/oauth/OAuthConnectedActionEvidence.ts +28 -0
  1307. package/src/oauth/OAuthConnectedPersistence.ts +163 -0
  1308. package/src/oauth/OAuthConnectedProtocol.ts +54 -0
  1309. package/src/oauth/OAuthConnectedRevocations.ts +48 -0
  1310. package/src/oauth/OAuthConnectedTokenProtector.ts +240 -0
  1311. package/src/oauth/OAuthConnectedTransactionProtector.ts +56 -0
  1312. package/src/oauth/OAuthConnectedUseAuthority.ts +26 -0
  1313. package/src/oauth/OAuthConnectionStore.ts +59 -0
  1314. package/src/oauth/OAuthLinkTransactionProtector.ts +58 -0
  1315. package/src/oauth/OAuthProtocol.ts +39 -0
  1316. package/src/oauth/OAuthProvider.ts +126 -0
  1317. package/src/oauth/OAuthProviders.ts +53 -0
  1318. package/src/oauth/OAuthRegistrationIntents.ts +42 -0
  1319. package/src/oauth/OAuthReturnTargets.ts +44 -0
  1320. package/src/oauth/OAuthSignInPersistence.ts +91 -0
  1321. package/src/oauth/OAuthStateDecisions.ts +16 -0
  1322. package/src/oauth/OAuthStateStore.ts +102 -0
  1323. package/src/oauth/OAuthTransactionProtector.ts +103 -0
  1324. package/src/oauth/accounts.ts +987 -0
  1325. package/src/oauth/accountsModels.ts +214 -0
  1326. package/src/oauth/connected.ts +995 -0
  1327. package/src/oauth/connectedAccess.ts +644 -0
  1328. package/src/oauth/connectedMaintenance.ts +248 -0
  1329. package/src/oauth/connectedModels.ts +495 -0
  1330. package/src/oauth/definition.ts +414 -0
  1331. package/src/oauth/errors.ts +78 -0
  1332. package/src/oauth/github/identity.ts +26 -0
  1333. package/src/oauth/github/models.ts +37 -0
  1334. package/src/oauth/github/protocol.ts +329 -0
  1335. package/src/oauth/openid-client/ProviderRevocation.ts +22 -0
  1336. package/src/oauth/openid-client/compatibility.ts +47 -0
  1337. package/src/oauth/openid-client/configuration.ts +472 -0
  1338. package/src/oauth/openid-client/connected/configuration.ts +565 -0
  1339. package/src/oauth/openid-client/connected/models.ts +58 -0
  1340. package/src/oauth/openid-client/connected/protocol.ts +866 -0
  1341. package/src/oauth/openid-client/models.ts +78 -0
  1342. package/src/oauth/openid-client/protocol.ts +437 -0
  1343. package/src/oauth/openid-client/transport.ts +67 -0
  1344. package/src/oauth/policy.ts +26 -0
  1345. package/src/oauth/registration.ts +410 -0
  1346. package/src/oauth/registrationModels.ts +115 -0
  1347. package/src/oauth/registrationSecrets.ts +127 -0
  1348. package/src/oauth/schema.ts +102 -0
  1349. package/src/oauth/signInErrors.ts +23 -0
  1350. package/src/oauth/signInModels.ts +266 -0
  1351. package/src/oauth/signInModule.ts +875 -0
  1352. package/src/oauth/signInSnapshot.ts +37 -0
  1353. package/src/oauth/transactionEncryption.ts +198 -0
  1354. package/src/operations/RequestBindingConfig.ts +12 -0
  1355. package/src/operations/actions.ts +342 -0
  1356. package/src/operations/context.ts +130 -0
  1357. package/src/operations/credentials.ts +121 -0
  1358. package/src/operations/errors.ts +53 -0
  1359. package/src/operations/operation.ts +740 -0
  1360. package/src/operations/requestBinding.ts +237 -0
  1361. package/src/operations/requestBindingModels.ts +18 -0
  1362. package/src/operations/reveals.ts +147 -0
  1363. package/src/passkey/PasskeyActionEvidence.ts +25 -0
  1364. package/src/passkey/PasskeyCredentials.ts +16 -0
  1365. package/src/passkey/PasskeyEnrollmentContext.ts +26 -0
  1366. package/src/passkey/PasskeyManagementPersistence.ts +124 -0
  1367. package/src/passkey/PasskeyPersistence.ts +85 -0
  1368. package/src/passkey/PasskeyProtocol.ts +48 -0
  1369. package/src/passkey/actions.ts +905 -0
  1370. package/src/passkey/browser/PasskeyBrowser.ts +26 -0
  1371. package/src/passkey/browser/models.ts +67 -0
  1372. package/src/passkey/browser/simplewebauthn.ts +621 -0
  1373. package/src/passkey/definition.ts +386 -0
  1374. package/src/passkey/errors.ts +39 -0
  1375. package/src/passkey/management.ts +552 -0
  1376. package/src/passkey/models.ts +414 -0
  1377. package/src/passkey/module.ts +367 -0
  1378. package/src/passkey/pending.ts +203 -0
  1379. package/src/passkey/policy.ts +88 -0
  1380. package/src/passkey/registration.ts +251 -0
  1381. package/src/passkey/simplewebauthn/configuration.ts +97 -0
  1382. package/src/passkey/simplewebauthn/models.ts +9 -0
  1383. package/src/passkey/simplewebauthn/protocol.ts +729 -0
  1384. package/src/passkey/snapshot.ts +48 -0
  1385. package/src/passkey/stepUp.ts +212 -0
  1386. package/src/password/CompromisedPasswords.ts +36 -0
  1387. package/src/password/NewPasswordCheck.ts +89 -0
  1388. package/src/password/PasswordHashing.ts +209 -0
  1389. package/src/password/PasswordKdfAdmission.ts +44 -0
  1390. package/src/password/configuration.ts +52 -0
  1391. package/src/password/defaults.ts +15 -0
  1392. package/src/password/encoding.ts +137 -0
  1393. package/src/password/errors.ts +43 -0
  1394. package/src/password/methods/PasswordActionEvidence.ts +41 -0
  1395. package/src/password/methods/PasswordPersistence.ts +128 -0
  1396. package/src/password/methods/PasswordPreparedPersistence.ts +123 -0
  1397. package/src/password/methods/contracts.ts +47 -0
  1398. package/src/password/methods/definition.ts +199 -0
  1399. package/src/password/methods/errors.ts +26 -0
  1400. package/src/password/methods/models.ts +80 -0
  1401. package/src/password/methods/module.ts +986 -0
  1402. package/src/password/methods/policy.ts +68 -0
  1403. package/src/password/methods/preparation.ts +73 -0
  1404. package/src/password/methods/prepared.ts +1199 -0
  1405. package/src/password/methods/preparedModels.ts +496 -0
  1406. package/src/password/methods/signIn.ts +136 -0
  1407. package/src/password/methods/snapshot.ts +53 -0
  1408. package/src/password/methods/verification.ts +266 -0
  1409. package/src/password/models.ts +15 -0
  1410. package/src/password/policy.ts +41 -0
  1411. package/src/phone/PhoneActionEvidence.ts +26 -0
  1412. package/src/phone/PhoneAdmission.ts +29 -0
  1413. package/src/phone/PhoneDeliveryEligibility.ts +9 -0
  1414. package/src/phone/PhonePersistence.ts +43 -0
  1415. package/src/phone/PhoneRequestContext.ts +7 -0
  1416. package/src/phone/PhoneSignInTargets.ts +19 -0
  1417. package/src/phone/definition.ts +87 -0
  1418. package/src/phone/failure.ts +40 -0
  1419. package/src/phone/lifecycle.ts +662 -0
  1420. package/src/phone/lifecycleModels.ts +108 -0
  1421. package/src/phone/models.ts +41 -0
  1422. package/src/phone/module.ts +433 -0
  1423. package/src/proofs/EmailProofDelivery.ts +19 -0
  1424. package/src/proofs/HostIngressLimiter.ts +20 -0
  1425. package/src/proofs/ProofPersistence.ts +172 -0
  1426. package/src/proofs/SmsProofDelivery.ts +19 -0
  1427. package/src/proofs/abuse.ts +23 -0
  1428. package/src/proofs/completion.ts +23 -0
  1429. package/src/proofs/crypto.ts +326 -0
  1430. package/src/proofs/definition.ts +39 -0
  1431. package/src/proofs/delivery.ts +73 -0
  1432. package/src/proofs/dispatch.ts +99 -0
  1433. package/src/proofs/errors.ts +46 -0
  1434. package/src/proofs/models.ts +131 -0
  1435. package/src/proofs/module.ts +620 -0
  1436. package/src/proofs/policy.ts +77 -0
  1437. package/src/sessions/AuthenticationAuthority.ts +51 -0
  1438. package/src/sessions/PendingAuthentication.ts +121 -0
  1439. package/src/sessions/SessionStepUpPersistence.ts +164 -0
  1440. package/src/sessions/assurance.ts +192 -0
  1441. package/src/sessions/commit.ts +13 -0
  1442. package/src/sessions/configuration.ts +133 -0
  1443. package/src/sessions/contract.ts +203 -0
  1444. package/src/sessions/crypto.ts +181 -0
  1445. package/src/sessions/definition.ts +25 -0
  1446. package/src/sessions/errors.ts +68 -0
  1447. package/src/sessions/invalidation.ts +46 -0
  1448. package/src/sessions/models.ts +138 -0
  1449. package/src/sessions/module.ts +1991 -0
  1450. package/src/sessions/persistence.ts +135 -0
  1451. package/src/sessions/policy.ts +103 -0
  1452. package/src/testing/conformance/AuthStore.ts +314 -0
  1453. package/src/testing/conformance/OAuthConnectionStore.ts +167 -0
  1454. package/src/testing/conformance/OAuthStateStore.ts +105 -0
  1455. package/src/testing/conformance/PasswordCredentialStore.ts +205 -0
  1456. package/src/testing/conformance/support.ts +38 -0
  1457. package/src/testing/crypto.ts +55 -0
  1458. package/src/testing/keyring.ts +17 -0
  1459. package/src/totp/TotpActionEvidence.ts +18 -0
  1460. package/src/totp/TotpPersistence.ts +26 -0
  1461. package/src/totp/TotpSecretKeys.ts +15 -0
  1462. package/src/totp/crypto.ts +160 -0
  1463. package/src/totp/definition.ts +78 -0
  1464. package/src/totp/errors.ts +25 -0
  1465. package/src/totp/models.ts +164 -0
  1466. package/src/totp/module.ts +717 -0
@@ -0,0 +1,2867 @@
1
+ /* oxlint-disable no-explicit-any -- D1 batch planning bridges dynamic consumer Drizzle tables to Effect SQL statements. */
2
+ import { and, eq, getTableColumns, gt, inArray, not, or, sql, type SQL } from "drizzle-orm";
3
+ import type { EffectDrizzleQueryError } from "drizzle-orm/effect-core";
4
+ import type { AnySQLiteTable } from "drizzle-orm/sqlite-core";
5
+ import { Cause, Context, Data, DateTime, Effect, Schema } from "effect";
6
+ import type * as SqlError from "effect/unstable/sql/SqlError";
7
+ import type { Statement } from "effect/unstable/sql/Statement";
8
+
9
+ import {
10
+ coordinateCommit,
11
+ CurrentCommitJournal,
12
+ hasCommitScope,
13
+ type PreparedCommit,
14
+ } from "../hooks/commit";
15
+ import { LifecycleHooks } from "../hooks/LifecycleHooks";
16
+ import type { HookConfigurationError } from "../hooks/models";
17
+ import { reportPersistenceFailure } from "../internal/diagnostics";
18
+ import type { SubjectId, TokenDigest } from "../Schema";
19
+ import {
20
+ assessAuthentication,
21
+ snapshotSessionAuthenticationProvenance,
22
+ } from "../sessions/assurance";
23
+ import { AuthenticationAuthority } from "../sessions/AuthenticationAuthority";
24
+ import type { PrepareSessionCommit } from "../sessions/commit";
25
+ import {
26
+ PendingAuthenticationInvalid,
27
+ SessionConflict,
28
+ type SessionConfigurationError,
29
+ SessionInvalid,
30
+ SessionStepUpInvalid,
31
+ SessionUnavailable,
32
+ StaleAuthentication,
33
+ } from "../sessions/errors";
34
+ import {
35
+ SessionMetadata,
36
+ type AuthenticationEvidence,
37
+ type AuthenticationRequirement,
38
+ type AuthenticationRevision,
39
+ type PendingConsumption,
40
+ type SecurityRevision,
41
+ } from "../sessions/models";
42
+ import {
43
+ pendingAuthenticationContext,
44
+ snapshotPendingAuthenticationContext,
45
+ type PendingAuthentication,
46
+ type PendingAuthenticationRecord,
47
+ type PendingAuthenticationState,
48
+ } from "../sessions/PendingAuthentication";
49
+ import type {
50
+ SessionRepository,
51
+ SignedSessionValidity,
52
+ StatefulSessionPersistence,
53
+ } from "../sessions/persistence";
54
+ import type {
55
+ SessionStepUpIntent,
56
+ SessionStepUpCompletionPlan,
57
+ SessionStepUpPersistence,
58
+ } from "../sessions/SessionStepUpPersistence";
59
+ import { compactD1GeneratedStatement } from "./d1-generated-statement";
60
+ import {
61
+ CurrentD1PlanningDatabase,
62
+ makeD1Owner,
63
+ type D1Owner,
64
+ type D1PlanningDatabase,
65
+ } from "./d1-planning";
66
+ import { D1BatchStatements } from "./D1BatchStatements";
67
+ import { column, DrizzleMappingError, isMappedConstraintConflict, updateValues } from "./model";
68
+ import type {
69
+ D1AuthenticationAuthorityMapping,
70
+ D1PendingAuthenticationMapping,
71
+ D1SignedSessionValidityMapping,
72
+ D1StatefulSessionMapping,
73
+ } from "./session-model";
74
+ import type { D1SessionStepUpMapping } from "./step-up-model";
75
+ import {
76
+ decodeStepUpIntent,
77
+ encodeStepUpIntent,
78
+ stepUpIntentLive,
79
+ validateStepUpPlan,
80
+ } from "./step-up-state";
81
+ import type { SuppliedService } from "./SuppliedService";
82
+
83
+ type Database = D1PlanningDatabase;
84
+ type AnyD1StepUpMapping = D1SessionStepUpMapping<any, any, any, any, any, any, any, any>;
85
+ type D1DomainError =
86
+ | SessionStepUpInvalid
87
+ | PendingAuthenticationInvalid
88
+ | SessionConflict
89
+ | SessionInvalid
90
+ | SessionUnavailable
91
+ | StaleAuthentication;
92
+ type D1PlanError =
93
+ | D1DomainError
94
+ | SessionConfigurationError
95
+ | DrizzleMappingError
96
+ | EffectDrizzleQueryError
97
+ | Schema.SchemaError;
98
+ type D1AdapterFailure = DrizzleMappingError | EffectDrizzleQueryError | Schema.SchemaError;
99
+ type NormalizedD1Error<E> = Extract<E, D1DomainError> | SessionUnavailable;
100
+ type PreparedValue<Method extends (...args: any[]) => any> =
101
+ Parameters<Method>[1] extends PrepareSessionCommit<infer Value, any> ? Value : never;
102
+ interface Planned<A> {
103
+ readonly receipt: A;
104
+ readonly statements: ReadonlyArray<Statement<any>>;
105
+ readonly isConstraintConflict?: (cause: unknown) => boolean;
106
+ readonly recoverGuard?: Effect.Effect<never, D1PlanError, CurrentD1PlanningDatabase>;
107
+ readonly journalGuard?: PreparedCommit<void>;
108
+ }
109
+ interface D1SessionBatch {
110
+ readonly owner: D1Owner<SessionUnavailable>;
111
+ readonly append: (planned: Planned<any>) => Effect.Effect<void, SessionUnavailable>;
112
+ }
113
+ class CurrentD1SessionBatch extends Context.Service<CurrentD1SessionBatch, D1SessionBatch>()(
114
+ "effect-auth/drizzle/CurrentD1SessionBatch",
115
+ ) {}
116
+ class D1BatchFailure extends Data.TaggedError("D1BatchFailure")<{
117
+ readonly cause: Cause.Cause<SqlError.SqlError>;
118
+ readonly mutation?: Planned<any>;
119
+ }> {}
120
+
121
+ const unavailable = () => SessionUnavailable.make({});
122
+ const stale = () => StaleAuthentication.make({});
123
+ const invalidPending = () => PendingAuthenticationInvalid.make({});
124
+ const invalidSession = () => SessionInvalid.make({});
125
+
126
+ const mapFailureCause = <A, E, R, E2>(
127
+ effect: Effect.Effect<A, E, R>,
128
+ map: (error: E) => E2,
129
+ ): Effect.Effect<A, E2, R> =>
130
+ Effect.catchCause(effect, (cause) => Effect.failCause(Cause.map(cause, map)));
131
+
132
+ const isD1DomainError = (error: unknown): error is D1DomainError => {
133
+ const tag = typeof error === "object" && error !== null ? Reflect.get(error, "_tag") : undefined;
134
+
135
+ return (
136
+ tag === "SessionStepUpInvalid" ||
137
+ tag === "PendingAuthenticationInvalid" ||
138
+ tag === "SessionConflict" ||
139
+ tag === "SessionInvalid" ||
140
+ tag === "SessionUnavailable" ||
141
+ tag === "StaleAuthentication"
142
+ );
143
+ };
144
+
145
+ const normalizeD1Failure = <A, E, R>(
146
+ effect: Effect.Effect<A, E, R>,
147
+ isExpected: (error: E) => boolean,
148
+ ): Effect.Effect<A, NormalizedD1Error<E>, R> =>
149
+ reportPersistenceFailure(effect, isExpected).pipe(
150
+ Effect.catchCause((cause) =>
151
+ Effect.failCause(
152
+ Cause.map(cause, (error): NormalizedD1Error<E> =>
153
+ isD1DomainError(error) ? (error as Extract<E, D1DomainError>) : unavailable(),
154
+ ),
155
+ ),
156
+ ),
157
+ );
158
+
159
+ const terminalD1 = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
160
+ normalizeD1Failure(effect, isD1DomainError);
161
+
162
+ const containsFailure = (failure: unknown, predicate: (value: unknown) => boolean): boolean => {
163
+ const seen = new Set<unknown>();
164
+ const pending: Array<unknown> = [failure];
165
+
166
+ for (let inspected = 0; inspected < 24 && pending.length > 0; inspected++) {
167
+ const current = pending.shift();
168
+
169
+ if (current === undefined || current === null || seen.has(current)) continue;
170
+ seen.add(current);
171
+ if (predicate(current)) return true;
172
+ if (Cause.isCause(current)) {
173
+ for (const reason of current.reasons) {
174
+ if (Cause.isFailReason(reason)) pending.push(reason.error);
175
+ else if (Cause.isDieReason(reason)) pending.push(reason.defect);
176
+ }
177
+ continue;
178
+ }
179
+ if (typeof current !== "object") continue;
180
+
181
+ const wrapped = current as {
182
+ readonly cause?: unknown;
183
+ readonly reason?: unknown;
184
+ readonly message?: unknown;
185
+ };
186
+
187
+ if (wrapped.cause !== undefined) pending.push(wrapped.cause);
188
+ if (wrapped.reason !== undefined) pending.push(wrapped.reason);
189
+ if (wrapped.message !== undefined) pending.push(wrapped.message);
190
+ }
191
+
192
+ return false;
193
+ };
194
+
195
+ const isGuardFailure = (failure: unknown): boolean =>
196
+ containsFailure(
197
+ failure,
198
+ (value) => typeof value === "string" && value.includes("effect-auth-session-guard"),
199
+ );
200
+
201
+ const recoverBatchFailure = (
202
+ failure: D1BatchFailure,
203
+ ): Effect.Effect<never, D1PlanError | SqlError.SqlError, CurrentD1PlanningDatabase> => {
204
+ const { cause, mutation } = failure;
205
+ const onlyFailures = cause.reasons.length > 0 && cause.reasons.every(Cause.isFailReason);
206
+
207
+ if (mutation === undefined) return Effect.failCause(cause);
208
+ if (
209
+ onlyFailures &&
210
+ mutation.isConstraintConflict !== undefined &&
211
+ cause.reasons.every(
212
+ (reason) =>
213
+ Cause.isFailReason(reason) &&
214
+ isMappedConstraintConflict(mutation.isConstraintConflict!, reason.error),
215
+ )
216
+ )
217
+ return Effect.fail(SessionConflict.make({}));
218
+ if (
219
+ onlyFailures &&
220
+ mutation.recoverGuard !== undefined &&
221
+ cause.reasons.every((reason) => Cause.isFailReason(reason) && isGuardFailure(reason.error))
222
+ )
223
+ return mutation.recoverGuard;
224
+
225
+ return Effect.failCause(cause);
226
+ };
227
+
228
+ const splitD1BatchFailure = <E>(cause: Cause.Cause<E | D1BatchFailure>) => {
229
+ const marker = cause.reasons.find(
230
+ (reason) => Cause.isFailReason(reason) && reason.error instanceof D1BatchFailure,
231
+ );
232
+
233
+ if (marker === undefined || !Cause.isFailReason(marker)) return undefined;
234
+ const remaining = Cause.fromReasons(cause.reasons.filter((reason) => reason !== marker));
235
+
236
+ return {
237
+ failure: marker.error as D1BatchFailure,
238
+ // The private marker is removed by identity; every retained reason belongs to E.
239
+ remaining: remaining as Cause.Cause<E>,
240
+ };
241
+ };
242
+
243
+ const recoverD1BatchCause = <E>(
244
+ cause: Cause.Cause<E | D1BatchFailure>,
245
+ ): Effect.Effect<never, E | D1PlanError | SqlError.SqlError, CurrentD1PlanningDatabase> => {
246
+ const split = splitD1BatchFailure(cause);
247
+
248
+ if (split === undefined) {
249
+ // No private marker remains, so this is the original E Cause.
250
+ return Effect.failCause(cause as Cause.Cause<E>);
251
+ }
252
+
253
+ return recoverBatchFailure(split.failure).pipe(
254
+ Effect.catchCause((recovered) => Effect.failCause(Cause.combine(recovered, split.remaining))),
255
+ );
256
+ };
257
+
258
+ const recoverCoordinatedD1BatchCause = <E>(
259
+ cause: Cause.Cause<E | D1BatchFailure>,
260
+ ): Effect.Effect<never, E | D1DomainError, CurrentD1PlanningDatabase> => {
261
+ const split = splitD1BatchFailure(cause);
262
+
263
+ if (split === undefined) {
264
+ // No private marker remains, so this is the original E Cause.
265
+ return Effect.failCause(cause as Cause.Cause<E>);
266
+ }
267
+
268
+ return terminalD1(recoverBatchFailure(split.failure)).pipe(
269
+ Effect.catchCause((recovered) => Effect.failCause(Cause.combine(recovered, split.remaining))),
270
+ );
271
+ };
272
+
273
+ const statement = (query: { readonly toSQL: () => { sql: string; params: unknown[] } }) =>
274
+ Effect.map(CurrentD1PlanningDatabase, (database) => {
275
+ const rendered = query.toSQL();
276
+
277
+ return compactD1GeneratedStatement(
278
+ database.$client,
279
+ database.$client.unsafe(rendered.sql, rendered.params),
280
+ unavailable,
281
+ );
282
+ });
283
+
284
+ const assertion = (
285
+ condition: SQL,
286
+ ): Effect.Effect<Statement<any>, never, CurrentD1PlanningDatabase> =>
287
+ Effect.gen(function* () {
288
+ const database = yield* CurrentD1PlanningDatabase;
289
+
290
+ return yield* statement(
291
+ database
292
+ .select({
293
+ ok: sql`case when ${condition} then 1 else json_extract('[]', '$[effect-auth-session-guard]') end`.as(
294
+ "ok",
295
+ ),
296
+ })
297
+ .from(sql`(select 1)`),
298
+ );
299
+ });
300
+
301
+ const conditionMatches = (condition: SQL) =>
302
+ Effect.flatMap(CurrentD1PlanningDatabase, (database) =>
303
+ database
304
+ .select({ ok: sql<number>`1` })
305
+ .from(sql`(select 1)`)
306
+ .where(condition)
307
+ .limit(1)
308
+ .pipe(Effect.map((rows) => rows.length > 0)),
309
+ );
310
+
311
+ function runPlanned<A, E>(
312
+ plan: Effect.Effect<Planned<A>, E, CurrentD1PlanningDatabase | CurrentCommitJournal>,
313
+ ): Effect.Effect<
314
+ A,
315
+ NormalizedD1Error<E | HookConfigurationError | SqlError.SqlError>,
316
+ CurrentD1PlanningDatabase | LifecycleHooks
317
+ >;
318
+ function runPlanned<A, E>(
319
+ plan: Effect.Effect<Planned<A>, E, CurrentD1PlanningDatabase | CurrentCommitJournal>,
320
+ isConstraintConflict: (cause: unknown) => boolean,
321
+ ): Effect.Effect<
322
+ A,
323
+ NormalizedD1Error<E | SessionConflict | HookConfigurationError | SqlError.SqlError>,
324
+ CurrentD1PlanningDatabase | LifecycleHooks
325
+ >;
326
+ function runPlanned<A, E, GuardE extends D1PlanError>(
327
+ plan: Effect.Effect<Planned<A>, E, CurrentD1PlanningDatabase | CurrentCommitJournal>,
328
+ isConstraintConflict: undefined,
329
+ recoverGuard: Effect.Effect<never, GuardE, CurrentD1PlanningDatabase>,
330
+ ): Effect.Effect<
331
+ A,
332
+ NormalizedD1Error<E | GuardE | HookConfigurationError | SqlError.SqlError>,
333
+ CurrentD1PlanningDatabase | LifecycleHooks
334
+ >;
335
+ function runPlanned<A, E, GuardE extends D1PlanError>(
336
+ plan: Effect.Effect<Planned<A>, E, CurrentD1PlanningDatabase | CurrentCommitJournal>,
337
+ isConstraintConflict: (cause: unknown) => boolean,
338
+ recoverGuard: Effect.Effect<never, GuardE, CurrentD1PlanningDatabase>,
339
+ ): Effect.Effect<
340
+ A,
341
+ NormalizedD1Error<E | GuardE | SessionConflict | HookConfigurationError | SqlError.SqlError>,
342
+ CurrentD1PlanningDatabase | LifecycleHooks
343
+ >;
344
+ function runPlanned<A, E, GuardE extends D1PlanError = never>(
345
+ plan: Effect.Effect<Planned<A>, E, CurrentD1PlanningDatabase | CurrentCommitJournal>,
346
+ isConstraintConflict?: (cause: unknown) => boolean,
347
+ recoverGuard?: Effect.Effect<never, GuardE, CurrentD1PlanningDatabase>,
348
+ ) {
349
+ const planned = plan.pipe(
350
+ Effect.map((value) => ({ ...value, isConstraintConflict, recoverGuard })),
351
+ );
352
+
353
+ const execution = Effect.gen(function* () {
354
+ const batch = yield* Effect.serviceOption(CurrentD1SessionBatch);
355
+
356
+ if (batch._tag === "Some") {
357
+ const owned = batch.value;
358
+
359
+ const result = yield* coordinateCommit(
360
+ () =>
361
+ Effect.gen(function* () {
362
+ yield* owned.owner.check;
363
+ const journal = yield* CurrentCommitJournal;
364
+ const value = yield* planned;
365
+
366
+ yield* owned.owner.check;
367
+ const guarded = { ...value, journalGuard: journal.prepare(undefined) };
368
+
369
+ yield* owned.append(guarded);
370
+
371
+ return guarded.receipt;
372
+ }),
373
+ { mode: "batch" },
374
+ );
375
+
376
+ return result.value;
377
+ }
378
+
379
+ const database = yield* CurrentD1PlanningDatabase;
380
+
381
+ const result = yield* coordinateCommit(
382
+ () =>
383
+ Effect.gen(function* () {
384
+ const prepared = yield* planned;
385
+
386
+ yield* database.$client
387
+ .batch(prepared.statements)
388
+ .pipe(
389
+ Effect.catchCause((cause) =>
390
+ Effect.fail(new D1BatchFailure({ cause, mutation: prepared })),
391
+ ),
392
+ );
393
+
394
+ return prepared.receipt;
395
+ }),
396
+ { mode: "batch" },
397
+ );
398
+
399
+ return result.value;
400
+ });
401
+
402
+ return normalizeD1Failure(
403
+ execution.pipe(Effect.catchCause(recoverD1BatchCause)),
404
+ isD1DomainError,
405
+ );
406
+ }
407
+
408
+ const subjectColumns = (mapping: any) => ({
409
+ id: column(mapping.subject.table, mapping.subject.id),
410
+ status: column(mapping.subject.table, mapping.subject.status),
411
+ revision: column(mapping.subject.table, mapping.subject.securityRevision),
412
+ });
413
+
414
+ const credentialColumns = (mapping: any) => ({
415
+ subjectId: column(mapping.credential.table, mapping.credential.subjectId),
416
+ id: column(mapping.credential.table, mapping.credential.credentialId),
417
+ revision: column(mapping.credential.table, mapping.credential.revision),
418
+ ...(mapping.credential.status === undefined
419
+ ? {}
420
+ : { status: column(mapping.credential.table, mapping.credential.status) }),
421
+ });
422
+
423
+ const flowColumns = (mapping: any) => ({
424
+ flowId: column(mapping.flow.table, mapping.flow.flowId),
425
+ subjectId: column(mapping.flow.table, mapping.flow.subjectId),
426
+ state: column(mapping.flow.table, mapping.flow.state),
427
+ pendingDigest: column(mapping.flow.table, mapping.flow.pendingDigest),
428
+ dedupUntil: column(mapping.flow.table, mapping.flow.dedupUntil),
429
+ });
430
+
431
+ const hasActiveFlow = Effect.fn("D1Session.hasActiveFlow")(function* (
432
+ mapping: any,
433
+ flowId: string,
434
+ ) {
435
+ const database = yield* CurrentD1PlanningDatabase;
436
+ const f = flowColumns(mapping);
437
+
438
+ return yield* database
439
+ .select({ flowId: f.flowId })
440
+ .from(mapping.flow.table)
441
+ .where(and(eq(f.flowId, flowId), gt(f.dedupUntil, mapping.d1.engineNow)))
442
+ .limit(1)
443
+ .pipe(Effect.map((rows) => rows.length > 0));
444
+ });
445
+
446
+ const recoverFlowOrStale = (
447
+ mapping: any,
448
+ flowId: string,
449
+ ): Effect.Effect<
450
+ never,
451
+ SessionConflict | StaleAuthentication | D1AdapterFailure,
452
+ CurrentD1PlanningDatabase
453
+ > =>
454
+ hasActiveFlow(mapping, flowId).pipe(
455
+ Effect.flatMap((active) =>
456
+ Effect.fail(active ? SessionConflict.make({}) : StaleAuthentication.make({})),
457
+ ),
458
+ );
459
+
460
+ const pendingColumns = (mapping: any) => ({
461
+ digest: column(mapping.pending.table, mapping.pending.digest),
462
+ version: column(mapping.pending.table, mapping.pending.version),
463
+ flowId: column(mapping.pending.table, mapping.pending.flowId),
464
+ subjectId: column(mapping.pending.table, mapping.pending.subjectId),
465
+ bindingDigest: column(mapping.pending.table, mapping.pending.bindingDigest),
466
+ expiresAt: column(mapping.pending.table, mapping.pending.expiresAt),
467
+ attemptLimit: column(mapping.pending.table, mapping.pending.attemptLimit),
468
+ failedAttempts: column(mapping.pending.table, mapping.pending.failedAttempts),
469
+ consumed: column(mapping.pending.table, mapping.pending.consumed),
470
+ });
471
+
472
+ const sessionColumns = (mapping: any) => ({
473
+ sessionId: column(mapping.session.table, mapping.session.sessionId),
474
+ subjectId: column(mapping.session.table, mapping.session.subjectId),
475
+ digest: column(mapping.session.table, mapping.session.digest),
476
+ version: column(mapping.session.table, mapping.session.version),
477
+ securityRevision: column(mapping.session.table, mapping.session.securityRevision),
478
+ issuedAt: column(mapping.session.table, mapping.session.issuedAt),
479
+ expiresAt: column(mapping.session.table, mapping.session.expiresAt),
480
+ absoluteExpiresAt: column(mapping.session.table, mapping.session.absoluteExpiresAt),
481
+ });
482
+
483
+ const captureDetails = Effect.fn("DrizzleD1Session.captureDetails")(function* (
484
+ mapping: any,
485
+ subjectId: SubjectId,
486
+ credentialIds: ReadonlyArray<string>,
487
+ ): Effect.fn.Return<
488
+ { readonly subject: any; readonly revision: AuthenticationRevision },
489
+ StaleAuthentication | D1AdapterFailure,
490
+ CurrentD1PlanningDatabase
491
+ > {
492
+ const database = yield* CurrentD1PlanningDatabase;
493
+ const requested = [...new Set(credentialIds)].sort();
494
+
495
+ if (requested.length !== credentialIds.length) return yield* stale();
496
+ const nativeSubjectId = yield* mapping.subjectId.toNative(subjectId);
497
+ const sc = subjectColumns(mapping);
498
+ const cc = credentialColumns(mapping);
499
+
500
+ const rows: any[] = yield* requested.length === 0
501
+ ? database
502
+ .select({ subject: getTableColumns(mapping.subject.table) })
503
+ .from(mapping.subject.table)
504
+ .where(eq(sc.id, nativeSubjectId))
505
+ .limit(1)
506
+ .pipe(
507
+ Effect.map((selected: any[]) =>
508
+ selected.map((row: any) => ({ subject: row.subject, credential: undefined })),
509
+ ),
510
+ )
511
+ : database
512
+ .select({
513
+ subject: getTableColumns(mapping.subject.table),
514
+ credential: getTableColumns(mapping.credential.table),
515
+ })
516
+ .from(mapping.subject.table)
517
+ .innerJoin(
518
+ mapping.credential.table,
519
+ and(eq(cc.subjectId, sc.id), inArray(cc.id, requested)),
520
+ )
521
+ .where(eq(sc.id, nativeSubjectId));
522
+
523
+ const subject = rows[0]?.subject;
524
+
525
+ if (subject === undefined || !mapping.subject.isActiveStatus(subject[mapping.subject.status]))
526
+ return yield* stale();
527
+
528
+ const credentials = rows.flatMap((row: any) =>
529
+ row.credential === undefined || row.credential === null ? [] : [row.credential],
530
+ );
531
+
532
+ if (
533
+ credentials.length !== requested.length ||
534
+ credentials.some(
535
+ (row: any) =>
536
+ mapping.credential.status !== undefined &&
537
+ mapping.credential.isActiveStatus?.(row[mapping.credential.status]) !== true,
538
+ )
539
+ )
540
+ return yield* stale();
541
+
542
+ return {
543
+ subject,
544
+ revision: {
545
+ subjectId,
546
+ securityRevision: subject[mapping.subject.securityRevision],
547
+ credentials: credentials
548
+ .map((row: any) => ({
549
+ credentialId: row[mapping.credential.credentialId],
550
+ revision: row[mapping.credential.revision],
551
+ }))
552
+ .sort((a: any, b: any) => a.credentialId.localeCompare(b.credentialId)),
553
+ } satisfies AuthenticationRevision,
554
+ };
555
+ });
556
+
557
+ const capture = Effect.fn("DrizzleD1Session.capture")(function* (
558
+ mapping: any,
559
+ subjectId: SubjectId,
560
+ credentialIds: ReadonlyArray<string>,
561
+ ): Effect.fn.Return<
562
+ AuthenticationRevision,
563
+ StaleAuthentication | D1AdapterFailure,
564
+ CurrentD1PlanningDatabase
565
+ > {
566
+ const details = yield* captureDetails(mapping, subjectId, credentialIds);
567
+
568
+ return details.revision;
569
+ });
570
+
571
+ const requirement = Effect.fn("DrizzleD1Session.requirement")(function* (
572
+ mapping: any,
573
+ evidence: AuthenticationEvidence,
574
+ ): Effect.fn.Return<
575
+ AuthenticationRequirement,
576
+ StaleAuthentication | D1AdapterFailure,
577
+ CurrentD1PlanningDatabase
578
+ > {
579
+ const current = yield* captureDetails(
580
+ mapping,
581
+ evidence.revision.subjectId,
582
+ evidence.revision.credentials.map((item) => item.credentialId),
583
+ );
584
+
585
+ const expected = new Map(
586
+ evidence.revision.credentials.map((item) => [item.credentialId, item.revision]),
587
+ );
588
+
589
+ if (
590
+ current.revision.securityRevision !== evidence.revision.securityRevision ||
591
+ current.revision.credentials.some((item) => expected.get(item.credentialId) !== item.revision)
592
+ )
593
+ return yield* stale();
594
+
595
+ return yield* mapping.subject.decodeRequirement(current.subject);
596
+ });
597
+
598
+ const authorityCondition = (
599
+ mapping: any,
600
+ nativeSubjectId: unknown,
601
+ evidence: Pick<AuthenticationEvidence, "revision">,
602
+ ): SQL => {
603
+ const sc = subjectColumns(mapping);
604
+ const cc = credentialColumns(mapping);
605
+ const subject = sql`exists(select 1 from ${mapping.subject.table} where ${sc.id} = ${sql.param(nativeSubjectId, sc.id)} and ${sc.status} = ${sql.param(mapping.d1.activeSubjectStatusValue, sc.status)} and ${sc.revision} = ${sql.param(evidence.revision.securityRevision, sc.revision)})`;
606
+
607
+ const credentials = evidence.revision.credentials.map(
608
+ (item) =>
609
+ sql`exists(select 1 from ${mapping.credential.table} where ${cc.subjectId} = ${sql.param(nativeSubjectId, cc.subjectId)} and ${cc.id} = ${sql.param(item.credentialId, cc.id)} and ${cc.revision} = ${sql.param(item.revision, cc.revision)}${
610
+ mapping.credential.status === undefined
611
+ ? sql``
612
+ : sql` and ${cc.status} = ${sql.param(mapping.d1.activeCredentialStatusValue, cc.status)}`
613
+ })`,
614
+ );
615
+
616
+ return and(subject, ...credentials)!;
617
+ };
618
+
619
+ const subjectRevisionCondition = (
620
+ mapping: any,
621
+ nativeSubjectId: unknown,
622
+ revision: SecurityRevision,
623
+ ) => {
624
+ const sc = subjectColumns(mapping);
625
+
626
+ return sql`exists(select 1 from ${mapping.subject.table} where ${sc.id} = ${sql.param(nativeSubjectId, sc.id)} and ${sc.status} = ${sql.param(mapping.d1.activeSubjectStatusValue, sc.status)} and ${sc.revision} = ${sql.param(revision, sc.revision)})`;
627
+ };
628
+
629
+ /** Engine-time counterpart of assessAuthentication. Complete transitions must
630
+ * satisfy an entire alternative; incomplete pending flows need one eligible proof. */
631
+ const freshnessCondition = (
632
+ mapping: any,
633
+ evidence: AuthenticationEvidence,
634
+ requirement: AuthenticationRequirement,
635
+ complete: boolean,
636
+ ): SQL => {
637
+ const fresh = evidence.proofs.map((proof) => {
638
+ const verified = DateTime.toEpochMillis(proof.verifiedAt);
639
+
640
+ return and(
641
+ sql`${mapping.d1.engineNowMillis} >= ${verified}`,
642
+ sql`${mapping.d1.engineNowMillis} - ${verified} < ${requirement.maximumAgeMillis}`,
643
+ )!;
644
+ });
645
+
646
+ const any = (conditions: ReadonlyArray<SQL>): SQL =>
647
+ conditions.length === 0 ? sql`false` : or(...conditions)!;
648
+
649
+ const notFuture = evidence.proofs.map(
650
+ (proof) => sql`${mapping.d1.engineNowMillis} >= ${DateTime.toEpochMillis(proof.verifiedAt)}`,
651
+ );
652
+
653
+ if (!complete) return and(...notFuture, any(fresh))!;
654
+ const byCredential = new Map<string, SQL[]>();
655
+
656
+ evidence.proofs.forEach((proof, index) => {
657
+ const previous = byCredential.get(proof.credentialId) ?? [];
658
+
659
+ previous.push(fresh[index]);
660
+ byCredential.set(proof.credentialId, previous);
661
+ });
662
+
663
+ const credentialCount = sql.join(
664
+ [...byCredential.values()].map((proofs) => sql`case when ${any(proofs)} then 1 else 0 end`),
665
+ sql` + `,
666
+ );
667
+
668
+ const alternatives = requirement.alternatives.map((alternative) =>
669
+ and(
670
+ ...alternative.factors.map((factor) =>
671
+ any(fresh.filter((_, index) => evidence.proofs[index].factors.includes(factor))),
672
+ ),
673
+ sql`(${credentialCount}) >= ${alternative.minimumCredentials}`,
674
+ any(
675
+ fresh.filter(
676
+ (_, index) =>
677
+ (!alternative.userVerified || evidence.proofs[index].userVerified) &&
678
+ (!alternative.phishingResistant || evidence.proofs[index].phishingResistant),
679
+ ),
680
+ ),
681
+ )!,
682
+ );
683
+
684
+ return and(...notFuture, any(alternatives))!;
685
+ };
686
+
687
+ const allocate = <A>(
688
+ asynchronous: Effect.Effect<A, DrizzleMappingError> | undefined,
689
+ synchronous: (() => A) | undefined,
690
+ ): Effect.Effect<A, D1AdapterFailure | SessionUnavailable> =>
691
+ asynchronous !== undefined
692
+ ? asynchronous
693
+ : synchronous === undefined
694
+ ? Effect.fail(unavailable())
695
+ : Effect.try({
696
+ try: synchronous,
697
+ catch: (cause) => DrizzleMappingError.make({ operation: "allocate", cause }),
698
+ });
699
+
700
+ const sameOriginalRevision = (
701
+ completed: AuthenticationEvidence,
702
+ original: AuthenticationEvidence,
703
+ ) => {
704
+ const current = new Map(
705
+ completed.revision.credentials.map((item) => [item.credentialId, item.revision]),
706
+ );
707
+
708
+ return (
709
+ completed.flowId === original.flowId &&
710
+ completed.bindingDigest === original.bindingDigest &&
711
+ completed.revision.subjectId === original.revision.subjectId &&
712
+ completed.revision.securityRevision === original.revision.securityRevision &&
713
+ original.revision.credentials.every(
714
+ (item) => current.get(item.credentialId) === item.revision,
715
+ ) &&
716
+ original.proofs.every((expected) =>
717
+ completed.proofs.some(
718
+ (proof) =>
719
+ proof.method === expected.method &&
720
+ proof.credentialId === expected.credentialId &&
721
+ proof.userVerified === expected.userVerified &&
722
+ proof.phishingResistant === expected.phishingResistant &&
723
+ DateTime.toEpochMillis(proof.verifiedAt) ===
724
+ DateTime.toEpochMillis(expected.verifiedAt) &&
725
+ proof.factors.length === expected.factors.length &&
726
+ proof.factors.every((factor, index) => factor === expected.factors[index]),
727
+ ),
728
+ )
729
+ );
730
+ };
731
+
732
+ type PendingProjection = "record" | "context";
733
+
734
+ const readPendingWith = Effect.fn("D1Session.readPendingWith")(function* <
735
+ Record extends PendingAuthenticationState,
736
+ >(
737
+ mapping: any,
738
+ digest: TokenDigest,
739
+ projection: PendingProjection,
740
+ ): Effect.fn.Return<Record | undefined, D1AdapterFailure, CurrentD1PlanningDatabase> {
741
+ const database = yield* CurrentD1PlanningDatabase;
742
+
743
+ const row = (yield* database
744
+ .select()
745
+ .from(mapping.pending.table)
746
+ .where(eq(pendingColumns(mapping).digest, digest))
747
+ .limit(1))[0];
748
+
749
+ if (row === undefined) return undefined;
750
+
751
+ const decode: (row: any) => Effect.Effect<Record, DrizzleMappingError> =
752
+ projection === "context" ? mapping.pending.decodeContext : mapping.pending.decode;
753
+
754
+ return yield* decode(row);
755
+ });
756
+
757
+ const readPending = <Claims>(mapping: any, digest: TokenDigest) =>
758
+ readPendingWith<PendingAuthenticationRecord<Claims>>(mapping, digest, "record");
759
+
760
+ const pendingCondition = (
761
+ mapping: any,
762
+ input: PendingConsumption,
763
+ nativeSubjectId: unknown,
764
+ ): SQL => {
765
+ const p = pendingColumns(mapping);
766
+ const f = flowColumns(mapping);
767
+
768
+ return and(
769
+ sql`exists(select 1 from ${mapping.pending.table} where ${p.digest} = ${sql.param(input.digest, p.digest)} and ${p.version} = ${sql.param(input.version, p.version)} and ${p.flowId} = ${sql.param(input.flowId, p.flowId)} and ${p.subjectId} = ${sql.param(nativeSubjectId, p.subjectId)} and ${p.bindingDigest} = ${sql.param(input.bindingDigest, p.bindingDigest)} and ${p.consumed} = ${sql.param(false, p.consumed)} and ${p.failedAttempts} < ${p.attemptLimit} and ${p.expiresAt} > ${mapping.d1.engineNow})`,
770
+ sql`exists(select 1 from ${mapping.flow.table} where ${f.flowId} = ${sql.param(input.flowId, f.flowId)} and ${f.subjectId} = ${sql.param(nativeSubjectId, f.subjectId)} and ${f.state} = ${sql.param(mapping.flow.pendingStateValue, f.state)} and ${f.pendingDigest} = ${sql.param(input.digest, f.pendingDigest)} and ${f.dedupUntil} > ${mapping.d1.engineNow})`,
771
+ )!;
772
+ };
773
+
774
+ const recoverPendingOrStale = (
775
+ mapping: any,
776
+ input: PendingConsumption,
777
+ subjectId: SubjectId,
778
+ ): Effect.Effect<
779
+ never,
780
+ PendingAuthenticationInvalid | StaleAuthentication | D1AdapterFailure,
781
+ CurrentD1PlanningDatabase
782
+ > =>
783
+ mapping.subjectId.toNative(subjectId).pipe(
784
+ Effect.flatMap((nativeSubjectId: unknown) =>
785
+ conditionMatches(pendingCondition(mapping, input, nativeSubjectId)),
786
+ ),
787
+ Effect.flatMap((pendingIsCurrent) =>
788
+ Effect.fail(
789
+ pendingIsCurrent ? StaleAuthentication.make({}) : PendingAuthenticationInvalid.make({}),
790
+ ),
791
+ ),
792
+ );
793
+
794
+ const consumePendingStatements = Effect.fn("D1Session.consumePendingStatements")(function* (
795
+ mapping: any,
796
+ input: PendingConsumption,
797
+ absoluteExpiresAt: DateTime.Utc,
798
+ ): Effect.fn.Return<ReadonlyArray<Statement<any>>, never, CurrentD1PlanningDatabase> {
799
+ const database = yield* CurrentD1PlanningDatabase;
800
+
801
+ return [
802
+ yield* statement(
803
+ database
804
+ .update(mapping.pending.table)
805
+ .set(updateValues<any>([[mapping.pending.consumed, true]]))
806
+ .where(
807
+ and(
808
+ eq(pendingColumns(mapping).digest, input.digest),
809
+ eq(pendingColumns(mapping).version, input.version),
810
+ ),
811
+ ),
812
+ ),
813
+ yield* statement(
814
+ database
815
+ .update(mapping.flow.table)
816
+ .set(
817
+ updateValues<any>([
818
+ [mapping.flow.state, mapping.flow.establishedStateValue],
819
+ [mapping.flow.pendingDigest, null],
820
+ [mapping.flow.dedupUntil, mapping.flow.encodeInstant(absoluteExpiresAt)],
821
+ ]),
822
+ )
823
+ .where(eq(flowColumns(mapping).flowId, input.flowId)),
824
+ ),
825
+ ];
826
+ });
827
+
828
+ export const makeD1AuthenticationAuthority = <Claims>(
829
+ mapping: D1AuthenticationAuthorityMapping<Claims, any, any, any, any, any>,
830
+ ) => ({
831
+ capture: (
832
+ subjectId: Parameters<AuthenticationAuthority["Service"]["capture"]>[0],
833
+ credentialIds: Parameters<AuthenticationAuthority["Service"]["capture"]>[1],
834
+ ) => capture(mapping, subjectId, credentialIds).pipe(terminalD1),
835
+ requirements: (evidence: AuthenticationEvidence) =>
836
+ requirement(mapping, evidence).pipe(terminalD1),
837
+ approve: <A>(
838
+ input: Parameters<AuthenticationAuthority["Service"]["approve"]>[0],
839
+ prepare: PrepareSessionCommit<void, A>,
840
+ ) =>
841
+ runPlanned(
842
+ Effect.gen(function* () {
843
+ const journal = yield* CurrentCommitJournal;
844
+ const policy = yield* requirement(mapping, input.evidence);
845
+ const assessed = yield* assessAuthentication(input.evidence, policy);
846
+
847
+ if (!assessed.satisfied) return yield* stale();
848
+
849
+ const nativeSubjectId = yield* mapping.subjectId.toNative(
850
+ input.evidence.revision.subjectId,
851
+ );
852
+
853
+ let condition = and(
854
+ authorityCondition(mapping, nativeSubjectId, input.evidence),
855
+ freshnessCondition(mapping, input.evidence, policy, true),
856
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(input.expiresAt)}`,
857
+ sql`${DateTime.toEpochMillis(input.expiresAt)} <= ${DateTime.toEpochMillis(input.absoluteExpiresAt)}`,
858
+ )!;
859
+
860
+ const statements: Statement<any>[] = [];
861
+
862
+ if (input.pending !== undefined) {
863
+ if (mapping.pending === undefined) return yield* invalidPending();
864
+ const pendingMapping = { ...mapping, ...mapping.pending };
865
+ const stored = yield* readPending(pendingMapping, input.pending.digest);
866
+
867
+ if (stored === undefined || !sameOriginalRevision(input.evidence, stored.evidence))
868
+ return yield* invalidPending();
869
+ condition = and(
870
+ condition,
871
+ pendingCondition(pendingMapping, input.pending, nativeSubjectId),
872
+ )!;
873
+ statements.push(
874
+ ...(yield* consumePendingStatements(
875
+ pendingMapping,
876
+ input.pending,
877
+ input.absoluteExpiresAt,
878
+ )),
879
+ );
880
+ }
881
+ const receipt = prepare(undefined, journal);
882
+
883
+ return { receipt, statements: [yield* assertion(condition), ...statements] };
884
+ }),
885
+ undefined,
886
+ Effect.suspend(() =>
887
+ input.pending === undefined || mapping.pending === undefined
888
+ ? Effect.fail(stale())
889
+ : recoverPendingOrStale(
890
+ { ...mapping, ...mapping.pending },
891
+ input.pending,
892
+ input.evidence.revision.subjectId,
893
+ ),
894
+ ),
895
+ ),
896
+ });
897
+
898
+ /** D1's last authoritative statement checks the original record version and
899
+ * security state together. A later race is still rejected by final consumption. */
900
+ const readAuthenticatedPending = Effect.fn("D1Session.readAuthenticatedPending")(function* <
901
+ Record extends PendingAuthenticationState,
902
+ >(
903
+ mapping: any,
904
+ input: { readonly digest: TokenDigest; readonly bindingDigest?: TokenDigest },
905
+ projection: PendingProjection,
906
+ ): Effect.fn.Return<
907
+ Record,
908
+ PendingAuthenticationInvalid | D1AdapterFailure,
909
+ CurrentD1PlanningDatabase
910
+ > {
911
+ const record = yield* readPendingWith<Record>(mapping, input.digest, projection);
912
+
913
+ if (
914
+ record === undefined ||
915
+ (input.bindingDigest !== undefined && record.evidence.bindingDigest !== input.bindingDigest)
916
+ )
917
+ return yield* invalidPending();
918
+
919
+ const policy = yield* mapFailureCause(requirement(mapping, record.evidence), (error) =>
920
+ error._tag === "StaleAuthentication" ? invalidPending() : error,
921
+ );
922
+
923
+ yield* assessAuthentication(record.evidence, policy).pipe(
924
+ Effect.mapError(() => invalidPending()),
925
+ );
926
+ const nativeSubjectId = yield* mapping.subjectId.toNative(record.evidence.revision.subjectId);
927
+
928
+ const current = yield* conditionMatches(
929
+ and(
930
+ authorityCondition(mapping, nativeSubjectId, record.evidence),
931
+ freshnessCondition(mapping, record.evidence, policy, false),
932
+ pendingCondition(
933
+ mapping,
934
+ {
935
+ digest: input.digest,
936
+ bindingDigest: record.evidence.bindingDigest,
937
+ flowId: record.evidence.flowId,
938
+ version: record.version,
939
+ },
940
+ nativeSubjectId,
941
+ ),
942
+ )!,
943
+ );
944
+
945
+ if (!current) return yield* invalidPending();
946
+
947
+ return record;
948
+ });
949
+
950
+ export const makeD1PendingAuthentication = <Claims>(
951
+ mapping: D1PendingAuthenticationMapping<Claims, any, any, any, any, any>,
952
+ ) => ({
953
+ create: <A>(
954
+ input: Parameters<PendingAuthentication<Claims>["create"]>[0],
955
+ _now: DateTime.Utc,
956
+ prepare: PrepareSessionCommit<PendingAuthenticationRecord<Claims>, A>,
957
+ ) =>
958
+ runPlanned(
959
+ Effect.gen(function* () {
960
+ const database = yield* CurrentD1PlanningDatabase;
961
+ const journal = yield* CurrentCommitJournal;
962
+ const policy = yield* requirement(mapping, input.evidence);
963
+
964
+ yield* assessAuthentication(input.evidence, policy);
965
+
966
+ const nativeSubjectId = yield* mapping.subjectId.toNative(
967
+ input.evidence.revision.subjectId,
968
+ );
969
+
970
+ if (yield* hasActiveFlow(mapping, input.evidence.flowId))
971
+ return yield* SessionConflict.make({});
972
+
973
+ const version = yield* allocate(
974
+ mapping.pending.allocateVersion,
975
+ mapping.pending.allocateVersionSync,
976
+ );
977
+
978
+ const record = { ...input, version };
979
+ const f = flowColumns(mapping);
980
+
981
+ const condition = and(
982
+ authorityCondition(mapping, nativeSubjectId, input.evidence),
983
+ freshnessCondition(mapping, input.evidence, policy, false),
984
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(input.expiresAt)}`,
985
+ not(
986
+ sql`exists(select 1 from ${mapping.flow.table} where ${f.flowId} = ${sql.param(input.evidence.flowId, f.flowId)} and ${f.dedupUntil} > ${mapping.d1.engineNow})`,
987
+ ),
988
+ )!;
989
+
990
+ const cleanupPending = database
991
+ .delete(mapping.pending.table)
992
+ .where(
993
+ sql`${pendingColumns(mapping).flowId} in (select ${f.flowId} from ${mapping.flow.table} where ${f.flowId} = ${sql.param(input.evidence.flowId, f.flowId)} and ${f.dedupUntil} <= ${mapping.d1.engineNow})`,
994
+ );
995
+
996
+ const cleanupFlow = database
997
+ .delete(mapping.flow.table)
998
+ .where(
999
+ and(
1000
+ eq(f.flowId, input.evidence.flowId),
1001
+ sql`${f.dedupUntil} <= ${mapping.d1.engineNow}`,
1002
+ ),
1003
+ );
1004
+
1005
+ const insertFlow = database.insert(mapping.flow.table).values(
1006
+ mapping.flow.encodePendingInsert({
1007
+ evidence: input.evidence,
1008
+ subjectId: nativeSubjectId,
1009
+ pendingDigest: input.digest,
1010
+ dedupUntil: input.expiresAt,
1011
+ }),
1012
+ );
1013
+
1014
+ const insertPending = database.insert(mapping.pending.table).values(
1015
+ mapping.pending.encodeInsert(record, {
1016
+ subjectId: nativeSubjectId,
1017
+ failedAttempts: 0,
1018
+ consumed: false,
1019
+ }),
1020
+ );
1021
+
1022
+ const receipt = prepare(record, journal);
1023
+
1024
+ return {
1025
+ receipt,
1026
+ statements: [
1027
+ yield* assertion(condition),
1028
+ yield* statement(cleanupPending),
1029
+ yield* statement(cleanupFlow),
1030
+ yield* statement(insertFlow),
1031
+ yield* statement(insertPending),
1032
+ ],
1033
+ };
1034
+ }),
1035
+ mapping.isConstraintConflict,
1036
+ recoverFlowOrStale(mapping, input.evidence.flowId),
1037
+ ),
1038
+ context: (input: Parameters<PendingAuthentication<Claims>["context"]>[0]) =>
1039
+ readAuthenticatedPending<PendingAuthenticationState>(mapping, input, "context").pipe(
1040
+ Effect.flatMap(pendingAuthenticationContext),
1041
+ terminalD1,
1042
+ ),
1043
+ read: (input: Parameters<PendingAuthentication<Claims>["read"]>[0]) =>
1044
+ readAuthenticatedPending<PendingAuthenticationRecord<Claims>>(mapping, input, "record").pipe(
1045
+ terminalD1,
1046
+ ),
1047
+ reject: <A>(
1048
+ input: Parameters<PendingAuthentication<Claims>["reject"]>[0],
1049
+ prepare: PrepareSessionCommit<{ readonly _tag: "Rejected" }, A>,
1050
+ ) =>
1051
+ runPlanned(
1052
+ Effect.gen(function* () {
1053
+ const database = yield* CurrentD1PlanningDatabase;
1054
+ const journal = yield* CurrentCommitJournal;
1055
+
1056
+ const record = yield* readPendingWith<PendingAuthenticationState>(
1057
+ mapping,
1058
+ input.digest,
1059
+ "context",
1060
+ );
1061
+
1062
+ if (record === undefined)
1063
+ return {
1064
+ receipt: prepare({ _tag: "Rejected" }, journal),
1065
+ statements: [yield* assertion(sql`true`)],
1066
+ };
1067
+
1068
+ const nativeSubjectId = yield* mapping.subjectId.toNative(
1069
+ record.evidence.revision.subjectId,
1070
+ );
1071
+
1072
+ const p = pendingColumns(mapping);
1073
+
1074
+ const condition = and(
1075
+ authorityCondition(mapping, nativeSubjectId, record.evidence),
1076
+ eq(p.digest, input.digest),
1077
+ eq(p.bindingDigest, input.bindingDigest),
1078
+ eq(p.consumed, false),
1079
+ gt(p.expiresAt, mapping.d1.engineNow),
1080
+ )!;
1081
+
1082
+ const update = database
1083
+ .update(mapping.pending.table)
1084
+ .set(
1085
+ updateValues<any>([
1086
+ [
1087
+ mapping.pending.failedAttempts,
1088
+ sql`case when ${p.failedAttempts} < ${p.attemptLimit} then ${p.failedAttempts} + 1 else ${p.failedAttempts} end`,
1089
+ ],
1090
+ ]),
1091
+ )
1092
+ .where(condition);
1093
+
1094
+ const receipt = prepare({ _tag: "Rejected" }, journal);
1095
+
1096
+ return { receipt, statements: [yield* statement(update)] };
1097
+ }),
1098
+ ),
1099
+ });
1100
+
1101
+ export const makeD1StatefulSessions = <Claims>(
1102
+ mapping: D1StatefulSessionMapping<Claims, any, any, any, any, any, any, any>,
1103
+ ) => {
1104
+ const s = sessionColumns(mapping);
1105
+
1106
+ const persistence = {
1107
+ establish: <A>(
1108
+ input: Parameters<StatefulSessionPersistence<Claims>["establish"]>[0],
1109
+ prepare: PrepareSessionCommit<
1110
+ PreparedValue<StatefulSessionPersistence<Claims>["establish"]>,
1111
+ A
1112
+ >,
1113
+ ) =>
1114
+ runPlanned(
1115
+ Effect.gen(function* () {
1116
+ const database = yield* CurrentD1PlanningDatabase;
1117
+ const journal = yield* CurrentCommitJournal;
1118
+ const policy = yield* requirement(mapping, input.evidence);
1119
+ const assessed = yield* assessAuthentication(input.evidence, policy);
1120
+
1121
+ if (!assessed.satisfied) return yield* stale();
1122
+
1123
+ const nativeSubjectId = yield* mapping.subjectId.toNative(
1124
+ input.evidence.revision.subjectId,
1125
+ );
1126
+
1127
+ if (input.pending === undefined && (yield* hasActiveFlow(mapping, input.evidence.flowId)))
1128
+ return yield* SessionConflict.make({});
1129
+
1130
+ const nativeSessionId = yield* allocate(
1131
+ mapping.session.allocateId,
1132
+ mapping.session.allocateIdSync,
1133
+ );
1134
+
1135
+ const sessionId = yield* mapping.sessionId.toSession(nativeSessionId);
1136
+
1137
+ const version = yield* allocate(
1138
+ mapping.session.allocateVersion,
1139
+ mapping.session.allocateVersionSync,
1140
+ );
1141
+
1142
+ const record = {
1143
+ ...input.session,
1144
+ sessionId,
1145
+ version,
1146
+ subjectId: input.evidence.revision.subjectId,
1147
+ securityRevision: input.evidence.revision.securityRevision,
1148
+ assurance: assessed.assurance,
1149
+ provenance: yield* snapshotSessionAuthenticationProvenance({
1150
+ evidence: input.evidence,
1151
+ }),
1152
+ // Ordered D1 batches cannot expose the engine timestamp to the
1153
+ // prepare callback. Persist the core's trusted planned time and
1154
+ // guard it against the engine clock in the final batch.
1155
+ issuedAt: DateTime.makeUnsafe(DateTime.toEpochMillis(input.session.issuedAt)),
1156
+ };
1157
+
1158
+ let condition = and(
1159
+ authorityCondition(mapping, nativeSubjectId, input.evidence),
1160
+ freshnessCondition(mapping, input.evidence, policy, true),
1161
+ sql`${DateTime.toEpochMillis(record.issuedAt)} <= ${mapping.d1.engineNowMillis}`,
1162
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(record.expiresAt)}`,
1163
+ sql`${DateTime.toEpochMillis(record.expiresAt)} <= ${DateTime.toEpochMillis(record.absoluteExpiresAt)}`,
1164
+ )!;
1165
+
1166
+ const statements: Statement<any>[] = [];
1167
+
1168
+ if (input.pending === undefined) {
1169
+ const f = flowColumns(mapping);
1170
+
1171
+ condition = and(
1172
+ condition,
1173
+ not(
1174
+ sql`exists(select 1 from ${mapping.flow.table} where ${f.flowId} = ${sql.param(input.evidence.flowId, f.flowId)} and ${f.dedupUntil} > ${mapping.d1.engineNow})`,
1175
+ ),
1176
+ )!;
1177
+ if (mapping.pending !== undefined)
1178
+ statements.push(
1179
+ yield* statement(
1180
+ database
1181
+ .delete(mapping.pending.table)
1182
+ .where(
1183
+ eq(
1184
+ column(mapping.pending.table, mapping.pending.flowId),
1185
+ input.evidence.flowId,
1186
+ ),
1187
+ ),
1188
+ ),
1189
+ );
1190
+ statements.push(
1191
+ yield* statement(
1192
+ database.delete(mapping.flow.table).where(eq(f.flowId, input.evidence.flowId)),
1193
+ ),
1194
+ yield* statement(
1195
+ database.insert(mapping.flow.table).values(
1196
+ mapping.flow.encodeEstablishedInsert({
1197
+ evidence: input.evidence,
1198
+ subjectId: nativeSubjectId,
1199
+ dedupUntil: record.absoluteExpiresAt,
1200
+ }),
1201
+ ),
1202
+ ),
1203
+ );
1204
+ } else {
1205
+ if (mapping.pending === undefined) return yield* invalidPending();
1206
+ const stored = yield* readPending(mapping, input.pending.digest);
1207
+
1208
+ if (stored === undefined || !sameOriginalRevision(input.evidence, stored.evidence))
1209
+ return yield* invalidPending();
1210
+ condition = and(condition, pendingCondition(mapping, input.pending, nativeSubjectId))!;
1211
+ statements.push(
1212
+ ...(yield* consumePendingStatements(
1213
+ mapping,
1214
+ input.pending,
1215
+ record.absoluteExpiresAt,
1216
+ )),
1217
+ );
1218
+ }
1219
+ statements.push(
1220
+ yield* statement(
1221
+ database.insert(mapping.session.table).values(
1222
+ mapping.session.encodeInsert(record, {
1223
+ subjectId: nativeSubjectId,
1224
+ sessionId: nativeSessionId,
1225
+ }),
1226
+ ),
1227
+ ),
1228
+ );
1229
+ const receipt = prepare(record, journal);
1230
+
1231
+ return { receipt, statements: [yield* assertion(condition), ...statements] };
1232
+ }),
1233
+ mapping.isConstraintConflict,
1234
+ Effect.suspend<
1235
+ never,
1236
+ SessionConflict | PendingAuthenticationInvalid | StaleAuthentication | D1AdapterFailure,
1237
+ CurrentD1PlanningDatabase
1238
+ >(() =>
1239
+ input.pending === undefined
1240
+ ? recoverFlowOrStale(mapping, input.evidence.flowId)
1241
+ : recoverPendingOrStale(mapping, input.pending, input.evidence.revision.subjectId),
1242
+ ),
1243
+ ),
1244
+ verify: (input: Parameters<StatefulSessionPersistence<Claims>["verify"]>[0]) =>
1245
+ Effect.gen(function* () {
1246
+ const database = yield* CurrentD1PlanningDatabase;
1247
+
1248
+ const rows = yield* database
1249
+ .select({ ...getTableColumns(mapping.session.table) })
1250
+ .from(mapping.session.table)
1251
+ .innerJoin(
1252
+ mapping.subject.table,
1253
+ and(
1254
+ eq(s.subjectId, subjectColumns(mapping).id),
1255
+ eq(s.securityRevision, subjectColumns(mapping).revision),
1256
+ eq(subjectColumns(mapping).status, mapping.d1.activeSubjectStatusValue),
1257
+ ),
1258
+ )
1259
+ .where(
1260
+ and(
1261
+ eq(s.digest, input.digest),
1262
+ gt(s.expiresAt, mapping.d1.engineNow),
1263
+ gt(s.absoluteExpiresAt, mapping.d1.engineNow),
1264
+ ),
1265
+ )
1266
+ .limit(1);
1267
+
1268
+ if (rows[0] === undefined) return yield* invalidSession();
1269
+
1270
+ return yield* mapping.session.decode(rows[0]);
1271
+ }).pipe(terminalD1),
1272
+ rotate: <A>(
1273
+ input: Parameters<StatefulSessionPersistence<Claims>["rotate"]>[0],
1274
+ prepare: PrepareSessionCommit<PreparedValue<StatefulSessionPersistence<Claims>["rotate"]>, A>,
1275
+ ) =>
1276
+ runPlanned(
1277
+ Effect.gen(function* () {
1278
+ const database = yield* CurrentD1PlanningDatabase;
1279
+ const journal = yield* CurrentCommitJournal;
1280
+ const nativeSessionId = yield* mapping.sessionId.toNative(input.sessionId);
1281
+
1282
+ const row = (yield* database
1283
+ .select()
1284
+ .from(mapping.session.table)
1285
+ .where(eq(s.sessionId, nativeSessionId))
1286
+ .limit(1))[0];
1287
+
1288
+ if (row === undefined) return yield* SessionConflict.make({});
1289
+ const current = yield* mapping.session.decode(row);
1290
+ const nativeSubjectId = yield* mapping.subjectId.toNative(current.subjectId);
1291
+
1292
+ const version = yield* allocate(
1293
+ mapping.session.allocateVersion,
1294
+ mapping.session.allocateVersionSync,
1295
+ );
1296
+
1297
+ const next = {
1298
+ ...current,
1299
+ digest: input.nextDigest,
1300
+ credentialVersion: input.nextCredentialVersion,
1301
+ version,
1302
+ issuedAt: DateTime.makeUnsafe(DateTime.toEpochMillis(input.now)),
1303
+ expiresAt: input.nextExpiresAt,
1304
+ };
1305
+
1306
+ const sessionCondition = and(
1307
+ eq(s.sessionId, nativeSessionId),
1308
+ eq(s.digest, input.expectedDigest),
1309
+ eq(s.version, input.expectedVersion),
1310
+ eq(s.securityRevision, input.expectedSecurityRevision),
1311
+ gt(s.expiresAt, mapping.d1.engineNow),
1312
+ gt(s.absoluteExpiresAt, mapping.d1.engineNow),
1313
+ )!;
1314
+
1315
+ const timeCondition = and(
1316
+ sql`${DateTime.toEpochMillis(next.issuedAt)} <= ${mapping.d1.engineNowMillis}`,
1317
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(input.nextExpiresAt)}`,
1318
+ sql`${DateTime.toEpochMillis(input.nextExpiresAt)} <= ${DateTime.toEpochMillis(current.absoluteExpiresAt)}`,
1319
+ )!;
1320
+
1321
+ const authority = subjectRevisionCondition(
1322
+ mapping,
1323
+ nativeSubjectId,
1324
+ input.expectedSecurityRevision,
1325
+ );
1326
+
1327
+ const assertionCondition = and(
1328
+ authority,
1329
+ sql`exists(select 1 from ${mapping.session.table} where ${sessionCondition})`,
1330
+ timeCondition,
1331
+ )!;
1332
+
1333
+ const update = database
1334
+ .update(mapping.session.table)
1335
+ .set(mapping.session.encodeRotation(next))
1336
+ .where(and(authority, sessionCondition, timeCondition));
1337
+
1338
+ const receipt = prepare(next, journal);
1339
+
1340
+ return {
1341
+ receipt,
1342
+ statements: [yield* assertion(assertionCondition), yield* statement(update)],
1343
+ };
1344
+ }),
1345
+ undefined,
1346
+ Effect.fail(SessionConflict.make({})),
1347
+ ),
1348
+ revokeDigest: <A>(
1349
+ digest: Parameters<StatefulSessionPersistence<Claims>["revokeDigest"]>[0],
1350
+ prepare: PrepareSessionCommit<boolean, A>,
1351
+ ) =>
1352
+ runPlanned(
1353
+ Effect.gen(function* () {
1354
+ const database = yield* CurrentD1PlanningDatabase;
1355
+ const journal = yield* CurrentCommitJournal;
1356
+
1357
+ const row = (yield* database
1358
+ .select()
1359
+ .from(mapping.session.table)
1360
+ .where(eq(s.digest, digest))
1361
+ .limit(1))[0];
1362
+
1363
+ const statements =
1364
+ row === undefined
1365
+ ? [yield* assertion(sql`true`)]
1366
+ : [
1367
+ yield* statement(
1368
+ database.delete(mapping.session.table).where(eq(s.digest, digest)),
1369
+ ),
1370
+ ];
1371
+
1372
+ return { receipt: prepare(row !== undefined, journal), statements };
1373
+ }),
1374
+ ),
1375
+ revoke: <A>(
1376
+ input: Parameters<StatefulSessionPersistence<Claims>["revoke"]>[0],
1377
+ prepare: PrepareSessionCommit<void, A>,
1378
+ ) =>
1379
+ runPlanned(
1380
+ Effect.gen(function* () {
1381
+ const database = yield* CurrentD1PlanningDatabase;
1382
+ const journal = yield* CurrentCommitJournal;
1383
+ const nativeSubjectId = yield* mapping.subjectId.toNative(input.subjectId);
1384
+ const nativeSessionId = yield* mapping.sessionId.toNative(input.sessionId);
1385
+
1386
+ const condition = subjectRevisionCondition(
1387
+ mapping,
1388
+ nativeSubjectId,
1389
+ input.expectedSecurityRevision,
1390
+ );
1391
+
1392
+ const remove = database
1393
+ .delete(mapping.session.table)
1394
+ .where(and(eq(s.subjectId, nativeSubjectId), eq(s.sessionId, nativeSessionId)));
1395
+
1396
+ const receipt = prepare(undefined, journal);
1397
+
1398
+ return {
1399
+ receipt,
1400
+ statements: [yield* assertion(condition), yield* statement(remove)],
1401
+ };
1402
+ }),
1403
+ undefined,
1404
+ Effect.fail(stale()),
1405
+ ),
1406
+ revokeAll: <A>(
1407
+ input: Parameters<StatefulSessionPersistence<Claims>["revokeAll"]>[0],
1408
+ prepare: PrepareSessionCommit<void, A>,
1409
+ ) =>
1410
+ runPlanned(
1411
+ Effect.gen(function* () {
1412
+ const database = yield* CurrentD1PlanningDatabase;
1413
+ const journal = yield* CurrentCommitJournal;
1414
+ const nativeSubjectId = yield* mapping.subjectId.toNative(input.subjectId);
1415
+
1416
+ const next = yield* allocate(
1417
+ mapping.subject.nextSecurityRevision?.(input.expectedSecurityRevision),
1418
+ mapping.subject.nextSecurityRevisionSync === undefined
1419
+ ? undefined
1420
+ : () => mapping.subject.nextSecurityRevisionSync!(input.expectedSecurityRevision),
1421
+ );
1422
+
1423
+ const sc = subjectColumns(mapping);
1424
+
1425
+ const condition = and(
1426
+ eq(sc.id, nativeSubjectId),
1427
+ eq(sc.status, mapping.d1.activeSubjectStatusValue),
1428
+ eq(sc.revision, input.expectedSecurityRevision),
1429
+ )!;
1430
+
1431
+ const updateSubject = database
1432
+ .update(mapping.subject.table)
1433
+ .set(updateValues<any>([[mapping.subject.securityRevision, next]]))
1434
+ .where(condition);
1435
+
1436
+ const removeSessions = database
1437
+ .delete(mapping.session.table)
1438
+ .where(eq(s.subjectId, nativeSubjectId));
1439
+
1440
+ const receipt = prepare(undefined, journal);
1441
+
1442
+ return {
1443
+ receipt,
1444
+ statements: [
1445
+ yield* assertion(
1446
+ sql`exists(select 1 from ${mapping.subject.table} where ${condition})`,
1447
+ ),
1448
+ yield* statement(updateSubject),
1449
+ yield* statement(removeSessions),
1450
+ ],
1451
+ };
1452
+ }),
1453
+ undefined,
1454
+ Effect.fail(stale()),
1455
+ ),
1456
+ };
1457
+
1458
+ const repository = {
1459
+ list: (input: Parameters<SessionRepository["list"]>[0]) =>
1460
+ Effect.gen(function* () {
1461
+ const database = yield* CurrentD1PlanningDatabase;
1462
+ const nativeSubjectId = yield* mapping.subjectId.toNative(input.subjectId);
1463
+
1464
+ const cursor =
1465
+ input.cursor === undefined
1466
+ ? undefined
1467
+ : yield* mapping.sessionId.toNative(input.cursor as any);
1468
+
1469
+ const rows = yield* database
1470
+ .select({ ...getTableColumns(mapping.session.table) })
1471
+ .from(mapping.session.table)
1472
+ .innerJoin(
1473
+ mapping.subject.table,
1474
+ and(
1475
+ eq(s.subjectId, subjectColumns(mapping).id),
1476
+ eq(s.securityRevision, subjectColumns(mapping).revision),
1477
+ eq(subjectColumns(mapping).status, mapping.d1.activeSubjectStatusValue),
1478
+ ),
1479
+ )
1480
+ .where(
1481
+ and(
1482
+ eq(s.subjectId, nativeSubjectId),
1483
+ gt(s.expiresAt, mapping.d1.engineNow),
1484
+ gt(s.absoluteExpiresAt, mapping.d1.engineNow),
1485
+ cursor === undefined ? undefined : gt(s.sessionId, cursor),
1486
+ ),
1487
+ )
1488
+ .orderBy(s.sessionId)
1489
+ .limit(input.limit + 1);
1490
+
1491
+ const decoded = yield* Effect.forEach(rows, (row) => mapping.session.decode(row));
1492
+ const codec = Schema.toCodecJson(Schema.toType(SessionMetadata));
1493
+
1494
+ const sessions = yield* Effect.forEach(decoded.slice(0, input.limit), (record) =>
1495
+ Schema.encodeEffect(codec)(record).pipe(Effect.flatMap(Schema.decodeEffect(codec))),
1496
+ );
1497
+
1498
+ return {
1499
+ sessions,
1500
+ ...(decoded.length <= input.limit ? {} : { nextCursor: sessions.at(-1)?.sessionId }),
1501
+ };
1502
+ }).pipe(terminalD1),
1503
+ };
1504
+
1505
+ return { persistence, repository };
1506
+ };
1507
+
1508
+ export const makeD1SignedValidity = (
1509
+ mapping: D1SignedSessionValidityMapping<any, any, any, any>,
1510
+ ) => {
1511
+ const sc = subjectColumns(mapping);
1512
+
1513
+ const t = {
1514
+ subjectId: column(mapping.tombstone.table, mapping.tombstone.subjectId),
1515
+ sessionId: column(mapping.tombstone.table, mapping.tombstone.sessionId),
1516
+ absoluteExpiresAt: column(mapping.tombstone.table, mapping.tombstone.absoluteExpiresAt),
1517
+ };
1518
+
1519
+ return {
1520
+ verify: (session: Parameters<SignedSessionValidity["verify"]>[0], _now: DateTime.Utc) =>
1521
+ Effect.gen(function* () {
1522
+ const database = yield* CurrentD1PlanningDatabase;
1523
+ const nativeSubjectId = yield* mapping.subjectId.toNative(session.subjectId);
1524
+ const nativeSessionId = yield* mapping.sessionId.toNative(session.sessionId);
1525
+
1526
+ const rows = yield* database
1527
+ .select({ subjectId: sc.id })
1528
+ .from(mapping.subject.table)
1529
+ .where(
1530
+ and(
1531
+ eq(sc.id, nativeSubjectId),
1532
+ eq(sc.status, mapping.d1.activeSubjectStatusValue),
1533
+ eq(sc.revision, session.securityRevision),
1534
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(session.expiresAt)}`,
1535
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(session.absoluteExpiresAt)}`,
1536
+ not(
1537
+ sql`exists(select 1 from ${mapping.tombstone.table} where ${t.subjectId} = ${sql.param(nativeSubjectId, t.subjectId)} and ${t.sessionId} = ${sql.param(nativeSessionId, t.sessionId)} and ${t.absoluteExpiresAt} > ${mapping.d1.engineNow})`,
1538
+ ),
1539
+ ),
1540
+ )
1541
+ .limit(1);
1542
+
1543
+ if (rows.length === 0) return yield* invalidSession();
1544
+ }).pipe(terminalD1),
1545
+ revoke: <A>(
1546
+ input: Parameters<SignedSessionValidity["revoke"]>[0],
1547
+ prepare: PrepareSessionCommit<void, A>,
1548
+ ) =>
1549
+ runPlanned(
1550
+ Effect.gen(function* () {
1551
+ const database = yield* CurrentD1PlanningDatabase;
1552
+ const journal = yield* CurrentCommitJournal;
1553
+ const nativeSubjectId = yield* mapping.subjectId.toNative(input.subjectId);
1554
+ const nativeSessionId = yield* mapping.sessionId.toNative(input.sessionId);
1555
+ const condition = sql`exists(select 1 from ${mapping.subject.table} where ${sc.id} = ${sql.param(nativeSubjectId, sc.id)} and ${sc.status} = ${sql.param(mapping.d1.activeSubjectStatusValue, sc.status)} and ${sc.revision} = ${sql.param(input.expectedSecurityRevision, sc.revision)})`;
1556
+ const encodedExpiry = mapping.tombstone.encodeInstant(input.absoluteExpiresAt);
1557
+ const desiredExpiry = sql.param(encodedExpiry, t.absoluteExpiresAt);
1558
+
1559
+ const write = database
1560
+ .insert(mapping.tombstone.table)
1561
+ .values(
1562
+ mapping.tombstone.encodeInsert({
1563
+ subjectId: nativeSubjectId,
1564
+ sessionId: nativeSessionId,
1565
+ absoluteExpiresAt: input.absoluteExpiresAt,
1566
+ }),
1567
+ )
1568
+ .onConflictDoUpdate({
1569
+ target: [t.subjectId, t.sessionId],
1570
+ set: updateValues<any>([
1571
+ [
1572
+ mapping.tombstone.absoluteExpiresAt,
1573
+ sql`case when ${t.absoluteExpiresAt} < ${desiredExpiry} then ${desiredExpiry} else ${t.absoluteExpiresAt} end`,
1574
+ ],
1575
+ ]),
1576
+ });
1577
+
1578
+ const receipt = prepare(undefined, journal);
1579
+
1580
+ return {
1581
+ receipt,
1582
+ statements: [yield* assertion(condition), yield* statement(write)],
1583
+ };
1584
+ }),
1585
+ undefined,
1586
+ Effect.fail(stale()),
1587
+ ),
1588
+ revokeAll: <A>(
1589
+ input: Parameters<SignedSessionValidity["revokeAll"]>[0],
1590
+ prepare: PrepareSessionCommit<void, A>,
1591
+ ) =>
1592
+ runPlanned(
1593
+ Effect.gen(function* () {
1594
+ const database = yield* CurrentD1PlanningDatabase;
1595
+ const journal = yield* CurrentCommitJournal;
1596
+ const nativeSubjectId = yield* mapping.subjectId.toNative(input.subjectId);
1597
+
1598
+ const next = yield* allocate(
1599
+ mapping.subject.nextSecurityRevision?.(input.expectedSecurityRevision),
1600
+ mapping.subject.nextSecurityRevisionSync === undefined
1601
+ ? undefined
1602
+ : () => mapping.subject.nextSecurityRevisionSync!(input.expectedSecurityRevision),
1603
+ );
1604
+
1605
+ const condition = and(
1606
+ eq(sc.id, nativeSubjectId),
1607
+ eq(sc.status, mapping.d1.activeSubjectStatusValue),
1608
+ eq(sc.revision, input.expectedSecurityRevision),
1609
+ )!;
1610
+
1611
+ const updateSubject = database
1612
+ .update(mapping.subject.table)
1613
+ .set(updateValues<any>([[mapping.subject.securityRevision, next]]))
1614
+ .where(condition);
1615
+
1616
+ const receipt = prepare(undefined, journal);
1617
+
1618
+ return {
1619
+ receipt,
1620
+ statements: [
1621
+ yield* assertion(
1622
+ sql`exists(select 1 from ${mapping.subject.table} where ${condition})`,
1623
+ ),
1624
+ yield* statement(updateSubject),
1625
+ ],
1626
+ };
1627
+ }),
1628
+ undefined,
1629
+ Effect.fail(stale()),
1630
+ ),
1631
+ };
1632
+ };
1633
+
1634
+ export const makeD1SessionServiceEffects = {
1635
+ authority: <Claims>(database: Database, mapping: any) =>
1636
+ Effect.gen(function* () {
1637
+ const hooks = yield* LifecycleHooks;
1638
+ const raw = makeD1AuthenticationAuthority<Claims>(mapping);
1639
+
1640
+ const run = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
1641
+ Effect.gen(function* () {
1642
+ if (
1643
+ (yield* Effect.serviceOption(CurrentD1SessionBatch))._tag === "Some" ||
1644
+ (yield* hasCommitScope)
1645
+ )
1646
+ return yield* unavailable();
1647
+
1648
+ return yield* effect.pipe(
1649
+ Effect.provideService(CurrentD1PlanningDatabase, database),
1650
+ Effect.provideService(LifecycleHooks, hooks),
1651
+ );
1652
+ });
1653
+
1654
+ const authenticationAuthority: AuthenticationAuthority["Service"] = {
1655
+ capture: (subjectId, credentialIds) => run(raw.capture(subjectId, credentialIds)),
1656
+ requirements: (evidence) => run(raw.requirements(evidence)),
1657
+ approve: (input, prepare) => run(raw.approve(input, prepare)),
1658
+ };
1659
+
1660
+ return { authenticationAuthority };
1661
+ }),
1662
+ pending: <Claims>(database: Database, mapping: any) =>
1663
+ Effect.gen(function* () {
1664
+ const hooks = yield* LifecycleHooks;
1665
+ const raw = makeD1PendingAuthentication<Claims>(mapping);
1666
+
1667
+ const run = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
1668
+ Effect.gen(function* () {
1669
+ if (
1670
+ (yield* Effect.serviceOption(CurrentD1SessionBatch))._tag === "Some" ||
1671
+ (yield* hasCommitScope)
1672
+ )
1673
+ return yield* unavailable();
1674
+
1675
+ return yield* effect.pipe(
1676
+ Effect.provideService(CurrentD1PlanningDatabase, database),
1677
+ Effect.provideService(LifecycleHooks, hooks),
1678
+ );
1679
+ });
1680
+
1681
+ const pendingAuthentication: PendingAuthentication<Claims> = {
1682
+ create: (input, now, prepare) => run(raw.create(input, now, prepare)),
1683
+ context: (input) => run(raw.context(input)),
1684
+ read: (input) => run(raw.read(input)),
1685
+ reject: (input, prepare) => run(raw.reject(input, prepare)),
1686
+ };
1687
+
1688
+ return { pendingAuthentication };
1689
+ }),
1690
+ stateful: <Claims>(database: Database, mapping: any) =>
1691
+ Effect.gen(function* () {
1692
+ const hooks = yield* LifecycleHooks;
1693
+ const raw = makeD1StatefulSessions<Claims>(mapping);
1694
+
1695
+ const run = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
1696
+ Effect.gen(function* () {
1697
+ if (
1698
+ (yield* Effect.serviceOption(CurrentD1SessionBatch))._tag === "Some" ||
1699
+ (yield* hasCommitScope)
1700
+ )
1701
+ return yield* unavailable();
1702
+
1703
+ return yield* effect.pipe(
1704
+ Effect.provideService(CurrentD1PlanningDatabase, database),
1705
+ Effect.provideService(LifecycleHooks, hooks),
1706
+ );
1707
+ });
1708
+
1709
+ const statefulSessionPersistence: StatefulSessionPersistence<Claims> = {
1710
+ establish: (input, prepare) => run(raw.persistence.establish(input, prepare)),
1711
+ verify: (input) => run(raw.persistence.verify(input)),
1712
+ rotate: (input, prepare) => run(raw.persistence.rotate(input, prepare)),
1713
+ revokeDigest: (digest, prepare) => run(raw.persistence.revokeDigest(digest, prepare)),
1714
+ revoke: (input, prepare) => run(raw.persistence.revoke(input, prepare)),
1715
+ revokeAll: (input, prepare) => run(raw.persistence.revokeAll(input, prepare)),
1716
+ };
1717
+
1718
+ const sessionRepository: SessionRepository = {
1719
+ list: (input) => run(raw.repository.list(input)),
1720
+ };
1721
+
1722
+ return { statefulSessionPersistence, sessionRepository };
1723
+ }),
1724
+ validity: (database: Database, mapping: any) =>
1725
+ Effect.gen(function* () {
1726
+ const hooks = yield* LifecycleHooks;
1727
+ const raw = makeD1SignedValidity(mapping);
1728
+
1729
+ const run = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
1730
+ Effect.gen(function* () {
1731
+ if (
1732
+ (yield* Effect.serviceOption(CurrentD1SessionBatch))._tag === "Some" ||
1733
+ (yield* hasCommitScope)
1734
+ )
1735
+ return yield* unavailable();
1736
+
1737
+ return yield* effect.pipe(
1738
+ Effect.provideService(CurrentD1PlanningDatabase, database),
1739
+ Effect.provideService(LifecycleHooks, hooks),
1740
+ );
1741
+ });
1742
+
1743
+ const signedSessionValidity: SignedSessionValidity = {
1744
+ verify: (session, now) => run(raw.verify(session, now)),
1745
+ revoke: (input, prepare) => run(raw.revoke(input, prepare)),
1746
+ revokeAll: (input, prepare) => run(raw.revokeAll(input, prepare)),
1747
+ };
1748
+
1749
+ return { signedSessionValidity };
1750
+ }),
1751
+ };
1752
+
1753
+ type D1CoordinatorError<E> = E | D1DomainError | HookConfigurationError;
1754
+
1755
+ /**
1756
+ * Owns one atomic D1 persistence transition together with any number of
1757
+ * application statements appended by `owner`. Keeping one persistence
1758
+ * transition makes a failed batch's domain guard recoverable without exposing
1759
+ * a prepared value. Compose additional transitions in later root batches.
1760
+ * Interruption or owner failure before `$client.batch` discards the journal;
1761
+ * the adapter performs no hidden retry and a retry must re-plan the whole owner.
1762
+ * Caller failures remain in the error channel. D1 batch/transport failures that
1763
+ * cannot be tied to this adapter's reserved guard become `SessionUnavailable`.
1764
+ */
1765
+ export const coordinateD1SessionBatch = <Services, A, E, R>(
1766
+ database: Database,
1767
+ make: (batch: D1SessionBatch) => Effect.Effect<Services, never, LifecycleHooks>,
1768
+ owner: (services: Services, batch: D1SessionBatch) => Effect.Effect<A, E, R>,
1769
+ ): Effect.Effect<A, D1CoordinatorError<E>, R | LifecycleHooks> =>
1770
+ Effect.gen(function* (): Effect.fn.Return<A, D1CoordinatorError<E>, R | LifecycleHooks> {
1771
+ if (yield* hasCommitScope) return yield* unavailable();
1772
+
1773
+ const result = yield* coordinateCommit(
1774
+ () =>
1775
+ Effect.gen(function* () {
1776
+ const statements: Statement<any>[] = [];
1777
+ let mutation: Planned<any> | undefined;
1778
+
1779
+ const nativeCollector = D1BatchStatements.of({
1780
+ append: (statement) => Effect.sync(() => statements.push(statement)),
1781
+ });
1782
+
1783
+ const d1Owner = yield* makeD1Owner(unavailable()).pipe(
1784
+ Effect.provideService(D1BatchStatements, nativeCollector),
1785
+ );
1786
+
1787
+ let batch!: D1SessionBatch;
1788
+
1789
+ const appendMutation = (input: Planned<any>) =>
1790
+ d1Owner.run(
1791
+ Effect.suspend(() => {
1792
+ // Guard recovery is unambiguous only for one persistence transition.
1793
+ // The owner may append any number of application statements around it.
1794
+ if (mutation !== undefined) return Effect.fail(unavailable());
1795
+ mutation = input;
1796
+ statements.push(...input.statements);
1797
+
1798
+ return Effect.void;
1799
+ }),
1800
+ );
1801
+
1802
+ batch = { owner: d1Owner, append: appendMutation };
1803
+ const services = yield* make(batch);
1804
+
1805
+ const value = yield* d1Owner.close(
1806
+ Effect.provideService(owner(services, batch), D1BatchStatements, d1Owner.collector),
1807
+ );
1808
+
1809
+ if (mutation?.journalGuard !== undefined) {
1810
+ const status = yield* Effect.result(mutation.journalGuard.read);
1811
+
1812
+ if (status._tag === "Success" || status.failure._tag !== "CommitPending")
1813
+ return yield* unavailable();
1814
+ }
1815
+
1816
+ yield* database.$client
1817
+ .batch(statements)
1818
+ .pipe(
1819
+ Effect.catchCause((cause) =>
1820
+ Effect.fail(
1821
+ new D1BatchFailure({ cause, ...(mutation === undefined ? {} : { mutation }) }),
1822
+ ),
1823
+ ),
1824
+ );
1825
+
1826
+ return value;
1827
+ }),
1828
+ { mode: "batch" },
1829
+ ).pipe(
1830
+ Effect.catchCause(recoverCoordinatedD1BatchCause),
1831
+ Effect.provideService(CurrentD1PlanningDatabase, database),
1832
+ );
1833
+
1834
+ return result.value;
1835
+ });
1836
+
1837
+ export const makeD1AuthenticationAuthorityServices = <
1838
+ Claims,
1839
+ Subject extends AnySQLiteTable,
1840
+ Credential extends AnySQLiteTable,
1841
+ Flow extends AnySQLiteTable,
1842
+ Pending extends AnySQLiteTable,
1843
+ NativeSubjectId,
1844
+ >(
1845
+ database: Database,
1846
+ mapping: D1AuthenticationAuthorityMapping<
1847
+ Claims,
1848
+ Subject,
1849
+ Credential,
1850
+ Flow,
1851
+ Pending,
1852
+ NativeSubjectId
1853
+ >,
1854
+ ) => makeD1SessionServiceEffects.authority<Claims>(database, mapping as any);
1855
+
1856
+ export const makeD1PendingAuthenticationServices = <
1857
+ Claims,
1858
+ Subject extends AnySQLiteTable,
1859
+ Credential extends AnySQLiteTable,
1860
+ Pending extends AnySQLiteTable,
1861
+ Flow extends AnySQLiteTable,
1862
+ NativeSubjectId,
1863
+ >(
1864
+ database: Database,
1865
+ mapping: D1PendingAuthenticationMapping<
1866
+ Claims,
1867
+ Subject,
1868
+ Credential,
1869
+ Pending,
1870
+ Flow,
1871
+ NativeSubjectId
1872
+ >,
1873
+ ) => makeD1SessionServiceEffects.pending<Claims>(database, mapping as any);
1874
+
1875
+ export const makeD1StatefulSessionServices = <
1876
+ Claims,
1877
+ Subject extends AnySQLiteTable,
1878
+ Credential extends AnySQLiteTable,
1879
+ Session extends AnySQLiteTable,
1880
+ Flow extends AnySQLiteTable,
1881
+ Pending extends AnySQLiteTable,
1882
+ NativeSubjectId,
1883
+ NativeSessionId,
1884
+ >(
1885
+ database: Database,
1886
+ mapping: D1StatefulSessionMapping<
1887
+ Claims,
1888
+ Subject,
1889
+ Credential,
1890
+ Session,
1891
+ Flow,
1892
+ Pending,
1893
+ NativeSubjectId,
1894
+ NativeSessionId
1895
+ >,
1896
+ ) => makeD1SessionServiceEffects.stateful<Claims>(database, mapping as any);
1897
+
1898
+ export const makeD1SignedSessionValidityServices = <
1899
+ Subject extends AnySQLiteTable,
1900
+ Tombstone extends AnySQLiteTable,
1901
+ NativeSubjectId,
1902
+ NativeSessionId,
1903
+ >(
1904
+ database: Database,
1905
+ mapping: D1SignedSessionValidityMapping<Subject, Tombstone, NativeSubjectId, NativeSessionId>,
1906
+ ) => makeD1SessionServiceEffects.validity(database, mapping as any);
1907
+
1908
+ export function coordinateD1AuthenticationAuthority<
1909
+ Claims,
1910
+ Subject extends AnySQLiteTable,
1911
+ Credential extends AnySQLiteTable,
1912
+ Flow extends AnySQLiteTable,
1913
+ Pending extends AnySQLiteTable,
1914
+ NativeSubjectId,
1915
+ A,
1916
+ E,
1917
+ R,
1918
+ DatabaseError,
1919
+ DatabaseRequirements,
1920
+ >(
1921
+ acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
1922
+ options: {
1923
+ readonly mapping: D1AuthenticationAuthorityMapping<
1924
+ Claims,
1925
+ Subject,
1926
+ Credential,
1927
+ Flow,
1928
+ Pending,
1929
+ NativeSubjectId
1930
+ >;
1931
+ },
1932
+ body: Effect.Effect<A, E, R>,
1933
+ ): Effect.Effect<
1934
+ A,
1935
+ D1CoordinatorError<E> | DatabaseError,
1936
+ Exclude<R, AuthenticationAuthority | D1BatchStatements> | LifecycleHooks | DatabaseRequirements
1937
+ > {
1938
+ return Effect.flatMap(acquire, (database) =>
1939
+ coordinateD1SessionBatch(
1940
+ database,
1941
+ (batch) =>
1942
+ Effect.gen(function* () {
1943
+ const hooks = yield* LifecycleHooks;
1944
+ const raw = makeD1AuthenticationAuthority<Claims>(options.mapping as any);
1945
+
1946
+ const run = <Out, Failure, Requirements>(
1947
+ effect: Effect.Effect<Out, Failure, Requirements>,
1948
+ ) =>
1949
+ batch.owner.run(
1950
+ effect.pipe(
1951
+ Effect.provideService(CurrentD1PlanningDatabase, database),
1952
+ Effect.provideService(LifecycleHooks, hooks),
1953
+ Effect.provideService(CurrentD1SessionBatch, batch),
1954
+ ),
1955
+ );
1956
+
1957
+ const authenticationAuthority: AuthenticationAuthority["Service"] = {
1958
+ capture: (subjectId, credentialIds) => run(raw.capture(subjectId, credentialIds)),
1959
+ requirements: (evidence) => run(raw.requirements(evidence)),
1960
+ approve: (input, prepare) => run(raw.approve(input, prepare)),
1961
+ };
1962
+
1963
+ return { authenticationAuthority };
1964
+ }),
1965
+ (
1966
+ ownedServices: { readonly authenticationAuthority: AuthenticationAuthority["Service"] },
1967
+ batch,
1968
+ ) => {
1969
+ const provided = Context.make(
1970
+ AuthenticationAuthority,
1971
+ ownedServices.authenticationAuthority,
1972
+ ).pipe(Context.add(D1BatchStatements, batch.owner.collector));
1973
+
1974
+ return Effect.provideContext(body, provided);
1975
+ },
1976
+ ),
1977
+ );
1978
+ }
1979
+
1980
+ export function coordinateD1PendingAuthentication<
1981
+ TargetId,
1982
+ Claims,
1983
+ Subject extends AnySQLiteTable,
1984
+ Credential extends AnySQLiteTable,
1985
+ Pending extends AnySQLiteTable,
1986
+ Flow extends AnySQLiteTable,
1987
+ NativeSubjectId,
1988
+ A,
1989
+ E,
1990
+ R,
1991
+ DatabaseError,
1992
+ DatabaseRequirements,
1993
+ >(
1994
+ acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
1995
+ options: {
1996
+ readonly mapping: D1PendingAuthenticationMapping<
1997
+ NoInfer<Claims>,
1998
+ Subject,
1999
+ Credential,
2000
+ Pending,
2001
+ Flow,
2002
+ NativeSubjectId
2003
+ >;
2004
+ readonly target: SuppliedService<TargetId, PendingAuthentication<Claims>>;
2005
+ },
2006
+ body: Effect.Effect<A, E, R>,
2007
+ ): Effect.Effect<
2008
+ A,
2009
+ D1CoordinatorError<E> | DatabaseError,
2010
+ Exclude<R, TargetId | D1BatchStatements> | LifecycleHooks | DatabaseRequirements
2011
+ > {
2012
+ return Effect.flatMap(acquire, (database) =>
2013
+ coordinateD1SessionBatch(
2014
+ database,
2015
+ (batch) =>
2016
+ Effect.gen(function* () {
2017
+ const hooks = yield* LifecycleHooks;
2018
+ const raw = makeD1PendingAuthentication<Claims>(options.mapping as any);
2019
+
2020
+ const run = <Out, Failure, Requirements>(
2021
+ effect: Effect.Effect<Out, Failure, Requirements>,
2022
+ ) =>
2023
+ batch.owner.run(
2024
+ effect.pipe(
2025
+ Effect.provideService(CurrentD1PlanningDatabase, database),
2026
+ Effect.provideService(LifecycleHooks, hooks),
2027
+ Effect.provideService(CurrentD1SessionBatch, batch),
2028
+ ),
2029
+ );
2030
+
2031
+ const pendingAuthentication: PendingAuthentication<Claims> = {
2032
+ create: (input, now, prepare) => run(raw.create(input, now, prepare)),
2033
+ context: (input) => run(raw.context(input)),
2034
+ read: (input) => run(raw.read(input)),
2035
+ reject: (input, prepare) => run(raw.reject(input, prepare)),
2036
+ };
2037
+
2038
+ return { pendingAuthentication };
2039
+ }),
2040
+ (ownedServices: { readonly pendingAuthentication: PendingAuthentication<Claims> }, batch) => {
2041
+ const provided = Context.make(options.target, ownedServices.pendingAuthentication).pipe(
2042
+ Context.add(D1BatchStatements, batch.owner.collector),
2043
+ );
2044
+
2045
+ return Effect.provideContext(body, provided);
2046
+ },
2047
+ ),
2048
+ );
2049
+ }
2050
+
2051
+ export function coordinateD1StatefulSessions<
2052
+ PersistenceId,
2053
+ RepositoryId,
2054
+ Claims,
2055
+ Subject extends AnySQLiteTable,
2056
+ Credential extends AnySQLiteTable,
2057
+ Session extends AnySQLiteTable,
2058
+ Flow extends AnySQLiteTable,
2059
+ Pending extends AnySQLiteTable,
2060
+ NativeSubjectId,
2061
+ NativeSessionId,
2062
+ A,
2063
+ E,
2064
+ R,
2065
+ DatabaseError,
2066
+ DatabaseRequirements,
2067
+ >(
2068
+ acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
2069
+ options: {
2070
+ readonly mapping: D1StatefulSessionMapping<
2071
+ NoInfer<Claims>,
2072
+ Subject,
2073
+ Credential,
2074
+ Session,
2075
+ Flow,
2076
+ Pending,
2077
+ NativeSubjectId,
2078
+ NativeSessionId
2079
+ >;
2080
+ readonly persistence: SuppliedService<PersistenceId, StatefulSessionPersistence<Claims>>;
2081
+ readonly repository: SuppliedService<RepositoryId, SessionRepository>;
2082
+ },
2083
+ body: Effect.Effect<A, E, R>,
2084
+ ): Effect.Effect<
2085
+ A,
2086
+ D1CoordinatorError<E> | DatabaseError,
2087
+ | Exclude<R, PersistenceId | RepositoryId | D1BatchStatements>
2088
+ | LifecycleHooks
2089
+ | DatabaseRequirements
2090
+ > {
2091
+ return Effect.flatMap(acquire, (database) =>
2092
+ coordinateD1SessionBatch(
2093
+ database,
2094
+ (batch) =>
2095
+ Effect.gen(function* () {
2096
+ const hooks = yield* LifecycleHooks;
2097
+ const raw = makeD1StatefulSessions<Claims>(options.mapping as any);
2098
+
2099
+ const run = <Out, Failure, Requirements>(
2100
+ effect: Effect.Effect<Out, Failure, Requirements>,
2101
+ ) =>
2102
+ batch.owner.run(
2103
+ effect.pipe(
2104
+ Effect.provideService(CurrentD1PlanningDatabase, database),
2105
+ Effect.provideService(LifecycleHooks, hooks),
2106
+ Effect.provideService(CurrentD1SessionBatch, batch),
2107
+ ),
2108
+ );
2109
+
2110
+ const statefulSessionPersistence: StatefulSessionPersistence<Claims> = {
2111
+ establish: (input, prepare) => run(raw.persistence.establish(input, prepare)),
2112
+ verify: (input) => run(raw.persistence.verify(input)),
2113
+ rotate: (input, prepare) => run(raw.persistence.rotate(input, prepare)),
2114
+ revokeDigest: (digest, prepare) => run(raw.persistence.revokeDigest(digest, prepare)),
2115
+ revoke: (input, prepare) => run(raw.persistence.revoke(input, prepare)),
2116
+ revokeAll: (input, prepare) => run(raw.persistence.revokeAll(input, prepare)),
2117
+ };
2118
+
2119
+ const sessionRepository: SessionRepository = {
2120
+ list: (input) => run(raw.repository.list(input)),
2121
+ };
2122
+
2123
+ return { statefulSessionPersistence, sessionRepository };
2124
+ }),
2125
+ (
2126
+ ownedServices: {
2127
+ readonly statefulSessionPersistence: StatefulSessionPersistence<Claims>;
2128
+ readonly sessionRepository: SessionRepository;
2129
+ },
2130
+ batch,
2131
+ ) => {
2132
+ const provided = Context.make(
2133
+ options.persistence,
2134
+ ownedServices.statefulSessionPersistence,
2135
+ ).pipe(
2136
+ Context.add(options.repository, ownedServices.sessionRepository),
2137
+ Context.add(D1BatchStatements, batch.owner.collector),
2138
+ );
2139
+
2140
+ return Effect.provideContext(body, provided);
2141
+ },
2142
+ ),
2143
+ );
2144
+ }
2145
+
2146
+ export function coordinateD1SignedSessionValidity<
2147
+ TargetId,
2148
+ Subject extends AnySQLiteTable,
2149
+ Tombstone extends AnySQLiteTable,
2150
+ NativeSubjectId,
2151
+ NativeSessionId,
2152
+ A,
2153
+ E,
2154
+ R,
2155
+ DatabaseError,
2156
+ DatabaseRequirements,
2157
+ >(
2158
+ acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
2159
+ options: {
2160
+ readonly mapping: D1SignedSessionValidityMapping<
2161
+ Subject,
2162
+ Tombstone,
2163
+ NativeSubjectId,
2164
+ NativeSessionId
2165
+ >;
2166
+ readonly target: SuppliedService<TargetId, SignedSessionValidity>;
2167
+ },
2168
+ body: Effect.Effect<A, E, R>,
2169
+ ): Effect.Effect<
2170
+ A,
2171
+ D1CoordinatorError<E> | DatabaseError,
2172
+ Exclude<R, TargetId | D1BatchStatements> | LifecycleHooks | DatabaseRequirements
2173
+ > {
2174
+ return Effect.flatMap(acquire, (database) =>
2175
+ coordinateD1SessionBatch(
2176
+ database,
2177
+ (batch) =>
2178
+ Effect.gen(function* () {
2179
+ const hooks = yield* LifecycleHooks;
2180
+ const raw = makeD1SignedValidity(options.mapping as any);
2181
+
2182
+ const run = <Out, Failure, Requirements>(
2183
+ effect: Effect.Effect<Out, Failure, Requirements>,
2184
+ ) =>
2185
+ batch.owner.run(
2186
+ effect.pipe(
2187
+ Effect.provideService(CurrentD1PlanningDatabase, database),
2188
+ Effect.provideService(LifecycleHooks, hooks),
2189
+ Effect.provideService(CurrentD1SessionBatch, batch),
2190
+ ),
2191
+ );
2192
+
2193
+ const signedSessionValidity: SignedSessionValidity = {
2194
+ verify: (session, now) => run(raw.verify(session, now)),
2195
+ revoke: (input, prepare) => run(raw.revoke(input, prepare)),
2196
+ revokeAll: (input, prepare) => run(raw.revokeAll(input, prepare)),
2197
+ };
2198
+
2199
+ return { signedSessionValidity };
2200
+ }),
2201
+ (ownedServices: { readonly signedSessionValidity: SignedSessionValidity }, batch) => {
2202
+ const provided = Context.make(options.target, ownedServices.signedSessionValidity).pipe(
2203
+ Context.add(D1BatchStatements, batch.owner.collector),
2204
+ );
2205
+
2206
+ return Effect.provideContext(body, provided);
2207
+ },
2208
+ ),
2209
+ );
2210
+ }
2211
+
2212
+ const stepUpColumns = (mapping: any) =>
2213
+ Object.fromEntries(
2214
+ [
2215
+ "digest",
2216
+ "version",
2217
+ "flowId",
2218
+ "subjectId",
2219
+ "bindingDigest",
2220
+ "snapshot",
2221
+ "expiresAt",
2222
+ "attemptLimit",
2223
+ "failedAttempts",
2224
+ "consumed",
2225
+ ].map((key) => [key, column(mapping.intent.table, mapping.intent[key])]),
2226
+ );
2227
+
2228
+ const stepUpSourceCondition = (
2229
+ mapping: any,
2230
+ intent: SessionStepUpIntent,
2231
+ nativeSubjectId: unknown,
2232
+ nativeSessionId: unknown,
2233
+ plan?: SessionStepUpCompletionPlan<unknown>,
2234
+ ): SQL => {
2235
+ const source = mapping.source;
2236
+
2237
+ if (source.kind !== intent.sourceKind) return sql`false`;
2238
+
2239
+ const time = and(
2240
+ sql`${mapping.d1.engineNowMillis} >= ${DateTime.toEpochMillis(intent.sourceAuthenticatedAt)}`,
2241
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(intent.sourceExpiresAt)}`,
2242
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(intent.sourceAbsoluteExpiresAt)}`,
2243
+ )!;
2244
+
2245
+ if (source.kind === "StatelessSigned") return time;
2246
+ if (source.kind === "StateAssistedSigned") {
2247
+ const t = source.tombstone,
2248
+ owner = column(t.table, t.subjectId),
2249
+ id = column(t.table, t.sessionId),
2250
+ expiry = column(t.table, t.absoluteExpiresAt);
2251
+
2252
+ return and(
2253
+ time,
2254
+ not(
2255
+ sql`exists(select 1 from ${t.table} where ${owner}=${sql.param(nativeSubjectId, owner)} and ${id}=${sql.param(nativeSessionId, id)} and ${expiry}>${mapping.d1.engineNow})`,
2256
+ ),
2257
+ )!;
2258
+ }
2259
+
2260
+ const s = source.session,
2261
+ c = sessionColumns(source);
2262
+
2263
+ const condition = and(
2264
+ eq(c.sessionId, nativeSessionId),
2265
+ eq(c.subjectId, nativeSubjectId),
2266
+ eq(c.securityRevision, intent.revision.securityRevision),
2267
+ eq(column(s.table, s.credentialVersion), intent.sourceCredentialVersion),
2268
+ eq(column(s.table, s.authenticatedAt), s.encodeInstant(intent.sourceAuthenticatedAt)),
2269
+ eq(c.expiresAt, s.encodeInstant(intent.sourceExpiresAt)),
2270
+ eq(c.absoluteExpiresAt, s.encodeInstant(intent.sourceAbsoluteExpiresAt)),
2271
+ gt(c.expiresAt, mapping.d1.engineNow),
2272
+ gt(c.absoluteExpiresAt, mapping.d1.engineNow),
2273
+ plan?.replacement._tag === "Stateful"
2274
+ ? eq(c.digest, plan.replacement.expectedDigest)
2275
+ : undefined,
2276
+ plan?.replacement._tag === "Stateful"
2277
+ ? eq(c.version, plan.replacement.expectedRowVersion)
2278
+ : undefined,
2279
+ )!;
2280
+
2281
+ return and(time, sql`exists(select 1 from ${s.table} where ${condition})`)!;
2282
+ };
2283
+
2284
+ const stepUpRowCondition = (
2285
+ mapping: any,
2286
+ row: any,
2287
+ intent: SessionStepUpIntent,
2288
+ nativeSubjectId: unknown,
2289
+ ): SQL => {
2290
+ const c = stepUpColumns(mapping),
2291
+ m = mapping.intent;
2292
+
2293
+ return and(
2294
+ eq(c.digest, intent.digest),
2295
+ eq(c.version, intent.version),
2296
+ eq(c.flowId, intent.flowId),
2297
+ eq(c.subjectId, nativeSubjectId),
2298
+ eq(c.bindingDigest, intent.bindingDigest),
2299
+ eq(c.snapshot, row[m.snapshot]),
2300
+ eq(c.expiresAt, m.encodeInstant(intent.expiresAt)),
2301
+ eq(c.attemptLimit, intent.attemptLimit),
2302
+ eq(c.consumed, false),
2303
+ eq(c.failedAttempts, row[m.failedAttempts]),
2304
+ sql`${c.failedAttempts} >= 0`,
2305
+ sql`${c.failedAttempts} < ${c.attemptLimit}`,
2306
+ gt(c.expiresAt, mapping.d1.engineNow),
2307
+ )!;
2308
+ };
2309
+
2310
+ const readD1StepUp = Effect.fn("DrizzleD1StepUp.read")(function* (
2311
+ mapping: AnyD1StepUpMapping,
2312
+ digest: TokenDigest,
2313
+ ) {
2314
+ const database = yield* CurrentD1PlanningDatabase;
2315
+
2316
+ const m = mapping.intent,
2317
+ c = stepUpColumns(mapping);
2318
+
2319
+ const row = (yield* database.select().from(m.table).where(eq(c.digest, digest)).limit(1))[0];
2320
+
2321
+ if (row === undefined) return yield* SessionStepUpInvalid.make({});
2322
+ const intent = yield* decodeStepUpIntent(row[m.snapshot]);
2323
+
2324
+ if (
2325
+ intent.digest !== digest ||
2326
+ !stepUpIntentLive(intent, mapping.source.kind, yield* DateTime.now) ||
2327
+ !Schema.is(Schema.Natural)(row[m.failedAttempts])
2328
+ )
2329
+ return yield* SessionStepUpInvalid.make({});
2330
+ const nativeSubjectId = yield* mapping.subjectId.toNative(intent.revision.subjectId);
2331
+
2332
+ const nativeSessionId =
2333
+ mapping.source.kind === "StatelessSigned"
2334
+ ? undefined
2335
+ : yield* mapping.source.sessionId.toNative(intent.sourceSessionId);
2336
+
2337
+ const condition = and(
2338
+ authorityCondition(mapping, nativeSubjectId, intent),
2339
+ stepUpSourceCondition(mapping, intent, nativeSubjectId, nativeSessionId),
2340
+ sql`exists(select 1 from ${m.table} where ${stepUpRowCondition(mapping, row, intent, nativeSubjectId)})`,
2341
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(intent.expiresAt)}`,
2342
+ )!;
2343
+
2344
+ if (!(yield* conditionMatches(condition))) return yield* SessionStepUpInvalid.make({});
2345
+
2346
+ return { row, intent, nativeSubjectId, nativeSessionId };
2347
+ });
2348
+
2349
+ const isD1StepUpRejectAbsence = (error: unknown): error is SessionStepUpInvalid =>
2350
+ typeof error === "object" &&
2351
+ error !== null &&
2352
+ Reflect.get(error, "_tag") === "SessionStepUpInvalid";
2353
+
2354
+ type D1StepUpReadFailure = D1AdapterFailure | SessionStepUpInvalid | SessionUnavailable;
2355
+
2356
+ const recoverD1StepUpRejectAbsence = <A, B, R>(
2357
+ effect: Effect.Effect<A, D1StepUpReadFailure, R>,
2358
+ rejected: B,
2359
+ ): Effect.Effect<A | B, D1AdapterFailure | SessionUnavailable, R> =>
2360
+ effect.pipe(
2361
+ Effect.catchCause((cause) => {
2362
+ if (
2363
+ cause.reasons.length > 0 &&
2364
+ cause.reasons.every(
2365
+ (reason) => Cause.isFailReason(reason) && isD1StepUpRejectAbsence(reason.error),
2366
+ )
2367
+ )
2368
+ return Effect.succeed(rejected);
2369
+
2370
+ return Effect.failCause(
2371
+ Cause.map(cause, (error) =>
2372
+ isD1StepUpRejectAbsence(error) ? SessionUnavailable.make({}) : error,
2373
+ ),
2374
+ );
2375
+ }),
2376
+ );
2377
+
2378
+ export const makeD1SessionStepUp = <Claims>(
2379
+ mapping: D1SessionStepUpMapping<Claims, any, any, any, any, any, any, any>,
2380
+ ) => {
2381
+ const m = mapping.intent,
2382
+ c = stepUpColumns(mapping);
2383
+
2384
+ const recover = Effect.fail(SessionStepUpInvalid.make({}));
2385
+
2386
+ return {
2387
+ create: <A>(
2388
+ input: Parameters<SessionStepUpPersistence<Claims>["create"]>[0],
2389
+ _now: DateTime.Utc,
2390
+ prepare: PrepareSessionCommit<SessionStepUpIntent, A>,
2391
+ ) =>
2392
+ runPlanned(
2393
+ Effect.gen(function* () {
2394
+ const database = yield* CurrentD1PlanningDatabase;
2395
+ const journal = yield* CurrentCommitJournal;
2396
+
2397
+ const version = yield* allocate(m.allocateVersion, m.allocateVersionSync),
2398
+ record: SessionStepUpIntent = { ...input, version };
2399
+
2400
+ if (!stepUpIntentLive(record, mapping.source.kind, yield* DateTime.now))
2401
+ return yield* stale();
2402
+ const nativeSubjectId = yield* mapping.subjectId.toNative(input.revision.subjectId);
2403
+
2404
+ const nativeSessionId =
2405
+ mapping.source.kind === "StatelessSigned"
2406
+ ? undefined
2407
+ : yield* mapping.source.sessionId.toNative(input.sourceSessionId);
2408
+
2409
+ const existing = yield* database
2410
+ .select()
2411
+ .from(m.table)
2412
+ .where(or(eq(c.digest, input.digest), eq(c.flowId, input.flowId)))
2413
+ .limit(1);
2414
+
2415
+ if (existing.length > 0) return yield* SessionConflict.make({});
2416
+
2417
+ const condition = and(
2418
+ authorityCondition(mapping, nativeSubjectId, record),
2419
+ stepUpSourceCondition(mapping, record, nativeSubjectId, nativeSessionId),
2420
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(input.expiresAt)}`,
2421
+ )!;
2422
+
2423
+ if (!(yield* conditionMatches(condition))) return yield* stale();
2424
+ const snapshot = yield* encodeStepUpIntent(record);
2425
+
2426
+ const values = {
2427
+ ...m.encodeInsert(record, { subjectId: nativeSubjectId }),
2428
+ ...updateValues<any>([
2429
+ [m.digest, record.digest],
2430
+ [m.version, version],
2431
+ [m.flowId, record.flowId],
2432
+ [m.subjectId, nativeSubjectId],
2433
+ [m.bindingDigest, record.bindingDigest],
2434
+ [m.snapshot, snapshot],
2435
+ [m.expiresAt, m.encodeInstant(record.expiresAt)],
2436
+ [m.attemptLimit, record.attemptLimit],
2437
+ [m.failedAttempts, 0],
2438
+ [m.consumed, false],
2439
+ ]),
2440
+ };
2441
+
2442
+ const receipt = prepare(record, journal);
2443
+
2444
+ const exact = and(
2445
+ eq(c.digest, record.digest),
2446
+ eq(c.version, version),
2447
+ eq(c.flowId, record.flowId),
2448
+ eq(c.subjectId, nativeSubjectId),
2449
+ eq(c.bindingDigest, record.bindingDigest),
2450
+ eq(c.snapshot, snapshot),
2451
+ eq(c.expiresAt, m.encodeInstant(record.expiresAt)),
2452
+ eq(c.attemptLimit, record.attemptLimit),
2453
+ eq(c.failedAttempts, 0),
2454
+ eq(c.consumed, false),
2455
+ )!;
2456
+
2457
+ return {
2458
+ receipt,
2459
+ statements: [
2460
+ yield* assertion(condition),
2461
+ yield* statement(database.insert(m.table).values(values)),
2462
+ yield* assertion(sql`changes() = 1`),
2463
+ yield* assertion(
2464
+ and(condition, sql`exists(select 1 from ${m.table} where ${exact})`)!,
2465
+ ),
2466
+ ],
2467
+ };
2468
+ }),
2469
+ mapping.isConstraintConflict,
2470
+ Effect.fail(stale()),
2471
+ ),
2472
+ context: (input: Parameters<SessionStepUpPersistence<Claims>["context"]>[0]) =>
2473
+ mapFailureCause(
2474
+ readD1StepUp(mapping, input.digest).pipe(
2475
+ Effect.flatMap(({ intent }) =>
2476
+ snapshotPendingAuthenticationContext({
2477
+ flowId: intent.flowId,
2478
+ bindingDigest: intent.bindingDigest,
2479
+ revision: intent.revision,
2480
+ expiresAtMillis: DateTime.toEpochMillis(intent.expiresAt),
2481
+ }),
2482
+ ),
2483
+ ),
2484
+ (error) => (error._tag === "PendingAuthenticationInvalid" ? unavailable() : error),
2485
+ ).pipe(terminalD1),
2486
+ read: (input: Parameters<SessionStepUpPersistence<Claims>["read"]>[0]) =>
2487
+ readD1StepUp(mapping, input.digest).pipe(
2488
+ Effect.flatMap(({ intent }) =>
2489
+ intent.bindingDigest === input.bindingDigest
2490
+ ? Effect.succeed(intent)
2491
+ : Effect.fail(SessionStepUpInvalid.make({})),
2492
+ ),
2493
+ terminalD1,
2494
+ ),
2495
+ reject: <A>(
2496
+ input: Parameters<SessionStepUpPersistence<Claims>["reject"]>[0],
2497
+ prepare: PrepareSessionCommit<{ readonly _tag: "Rejected" }, A>,
2498
+ ) =>
2499
+ runPlanned(
2500
+ Effect.gen(function* () {
2501
+ const database = yield* CurrentD1PlanningDatabase;
2502
+ const journal = yield* CurrentCommitJournal;
2503
+
2504
+ const selected = yield* recoverD1StepUpRejectAbsence(
2505
+ readD1StepUp(mapping, input.digest).pipe(
2506
+ Effect.map((value) => ({ _tag: "Found" as const, value })),
2507
+ ),
2508
+ { _tag: "Rejected" as const },
2509
+ );
2510
+
2511
+ if (selected._tag === "Rejected")
2512
+ return { receipt: prepare({ _tag: "Rejected" }, journal), statements: [] };
2513
+ const { row, intent, nativeSubjectId, nativeSessionId } = selected.value;
2514
+
2515
+ // Rejection does not replace immutable intent identity. Concurrent contenders
2516
+ // increment the authoritative counter under the same cap; completion pins it.
2517
+ const condition = and(
2518
+ eq(c.digest, intent.digest),
2519
+ eq(c.version, intent.version),
2520
+ eq(c.snapshot, row[m.snapshot]),
2521
+ eq(c.subjectId, nativeSubjectId),
2522
+ eq(c.bindingDigest, intent.bindingDigest),
2523
+ eq(c.flowId, intent.flowId),
2524
+ eq(c.expiresAt, m.encodeInstant(intent.expiresAt)),
2525
+ eq(c.attemptLimit, intent.attemptLimit),
2526
+ eq(c.consumed, false),
2527
+ sql`${c.failedAttempts} >= 0`,
2528
+ sql`${c.failedAttempts} < ${c.attemptLimit}`,
2529
+ gt(c.expiresAt, mapping.d1.engineNow),
2530
+ authorityCondition(mapping, nativeSubjectId, intent),
2531
+ stepUpSourceCondition(mapping, intent, nativeSubjectId, nativeSessionId),
2532
+ )!;
2533
+
2534
+ const write = database
2535
+ .update(m.table)
2536
+ .set(updateValues<any>([[m.failedAttempts, sql`${c.failedAttempts} + 1`]]))
2537
+ .where(condition);
2538
+
2539
+ // A valid still-chargeable row cannot survive a zero-write trigger. A row
2540
+ // consumed/expired/exhausted while queued legitimately returns Rejected.
2541
+ const settled = sql`changes() = 1 or not exists(select 1 from ${m.table} where ${condition})`;
2542
+
2543
+ return {
2544
+ receipt: prepare({ _tag: "Rejected" }, journal),
2545
+ statements: [yield* statement(write), yield* assertion(settled)],
2546
+ };
2547
+ }),
2548
+ undefined,
2549
+ Effect.fail(unavailable()),
2550
+ ),
2551
+ complete: <A>(
2552
+ plan: SessionStepUpCompletionPlan<Claims>,
2553
+ prepare: PrepareSessionCommit<PreparedValue<SessionStepUpPersistence<Claims>["complete"]>, A>,
2554
+ ) =>
2555
+ runPlanned(
2556
+ Effect.gen(function* () {
2557
+ const database = yield* CurrentD1PlanningDatabase;
2558
+ const journal = yield* CurrentCommitJournal;
2559
+
2560
+ yield* validateStepUpPlan(plan);
2561
+ const stored = yield* readD1StepUp(mapping, plan.intent.digest);
2562
+
2563
+ if (
2564
+ (yield* encodeStepUpIntent(stored.intent)) !== (yield* encodeStepUpIntent(plan.intent))
2565
+ )
2566
+ return yield* SessionStepUpInvalid.make({});
2567
+ const base = yield* requirement(mapping, plan.evidence);
2568
+
2569
+ if (
2570
+ !(yield* assessAuthentication(plan.evidence, base)).satisfied ||
2571
+ !(yield* assessAuthentication(plan.evidence, stored.intent.requirement)).satisfied
2572
+ )
2573
+ return yield* stale();
2574
+
2575
+ const { row, intent, nativeSubjectId, nativeSessionId } = stored,
2576
+ replacement = plan.replacement;
2577
+
2578
+ const target = replacement.inspection.session;
2579
+
2580
+ if (
2581
+ DateTime.toEpochMillis(target.expiresAt) >
2582
+ DateTime.toEpochMillis(intent.sourceAbsoluteExpiresAt)
2583
+ )
2584
+ return yield* SessionStepUpInvalid.make({});
2585
+
2586
+ const live = and(
2587
+ authorityCondition(mapping, nativeSubjectId, plan.evidence),
2588
+ freshnessCondition(mapping, plan.evidence, base, true),
2589
+ freshnessCondition(mapping, plan.evidence, intent.requirement, true),
2590
+ sql`${mapping.d1.engineNowMillis} >= ${DateTime.toEpochMillis(intent.sourceAuthenticatedAt)}`,
2591
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(intent.expiresAt)}`,
2592
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(intent.sourceExpiresAt)}`,
2593
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(intent.sourceAbsoluteExpiresAt)}`,
2594
+ sql`${mapping.d1.engineNowMillis} >= ${DateTime.toEpochMillis(target.issuedAt)}`,
2595
+ sql`${mapping.d1.engineNowMillis} < ${DateTime.toEpochMillis(target.expiresAt)}`,
2596
+ )!;
2597
+
2598
+ const source = stepUpSourceCondition(
2599
+ mapping,
2600
+ intent,
2601
+ nativeSubjectId,
2602
+ nativeSessionId,
2603
+ plan,
2604
+ );
2605
+
2606
+ const version = yield* allocate(m.allocateVersion, m.allocateVersionSync);
2607
+
2608
+ if (version === intent.version) return yield* unavailable();
2609
+ const snapshot = yield* encodeStepUpIntent({ ...intent, version });
2610
+
2611
+ const consume = database
2612
+ .update(m.table)
2613
+ .set(
2614
+ updateValues<any>([
2615
+ [m.consumed, true],
2616
+ [m.version, version],
2617
+ [m.snapshot, snapshot],
2618
+ ]),
2619
+ )
2620
+ .where(and(stepUpRowCondition(mapping, row, intent, nativeSubjectId), live, source));
2621
+
2622
+ const marker = sql`exists(select 1 from ${m.table} where ${c.digest}=${sql.param(intent.digest, c.digest)} and ${c.version}=${sql.param(version, c.version)} and ${c.snapshot}=${sql.param(snapshot, c.snapshot)} and ${c.consumed}=${sql.param(true, c.consumed)} and ${c.failedAttempts}=${row[m.failedAttempts]})`;
2623
+
2624
+ const statements: Statement<any>[] = [
2625
+ yield* statement(consume),
2626
+ yield* assertion(sql`changes() = 1`),
2627
+ ];
2628
+
2629
+ let post: SQL = sql`true`;
2630
+
2631
+ if (replacement._tag === "Stateful") {
2632
+ if (mapping.source.kind !== "Stateful") return yield* SessionStepUpInvalid.make({});
2633
+
2634
+ const s = mapping.source.session,
2635
+ sc = sessionColumns(mapping.source);
2636
+
2637
+ const rowVersion = yield* allocate(s.allocateVersion, s.allocateVersionSync);
2638
+
2639
+ const next = {
2640
+ ...target,
2641
+ provenance: replacement.inspection.provenance,
2642
+ credentialVersion: replacement.inspection.credentialVersion,
2643
+ digest: replacement.nextDigest,
2644
+ version: rowVersion,
2645
+ };
2646
+
2647
+ const rotation = {
2648
+ ...s.encodeRotation(next),
2649
+ ...updateValues<any>([
2650
+ [s.version, rowVersion],
2651
+ [s.digest, next.digest],
2652
+ [s.credentialVersion, next.credentialVersion],
2653
+ [s.authenticatedAt, s.encodeInstant(target.assurance.authenticatedAt)],
2654
+ [s.issuedAt, s.encodeInstant(target.issuedAt)],
2655
+ [s.expiresAt, s.encodeInstant(target.expiresAt)],
2656
+ [s.absoluteExpiresAt, s.encodeInstant(target.absoluteExpiresAt)],
2657
+ ]),
2658
+ };
2659
+
2660
+ const write = database
2661
+ .update(s.table)
2662
+ .set(rotation)
2663
+ .where(
2664
+ and(
2665
+ eq(sc.sessionId, nativeSessionId),
2666
+ eq(sc.digest, replacement.expectedDigest),
2667
+ eq(sc.version, replacement.expectedRowVersion),
2668
+ marker,
2669
+ source,
2670
+ live,
2671
+ ),
2672
+ );
2673
+
2674
+ statements.push(yield* statement(write), yield* assertion(sql`changes() = 1`));
2675
+
2676
+ const exact = and(
2677
+ eq(sc.sessionId, nativeSessionId),
2678
+ eq(sc.subjectId, nativeSubjectId),
2679
+ eq(sc.version, rowVersion),
2680
+ eq(sc.digest, next.digest),
2681
+ eq(sc.securityRevision, target.securityRevision),
2682
+ eq(column(s.table, s.credentialVersion), next.credentialVersion),
2683
+ eq(
2684
+ column(s.table, s.authenticatedAt),
2685
+ s.encodeInstant(target.assurance.authenticatedAt),
2686
+ ),
2687
+ eq(sc.issuedAt, s.encodeInstant(target.issuedAt)),
2688
+ eq(sc.expiresAt, s.encodeInstant(target.expiresAt)),
2689
+ eq(sc.absoluteExpiresAt, s.encodeInstant(target.absoluteExpiresAt)),
2690
+ )!;
2691
+
2692
+ post = sql`exists(select 1 from ${s.table} where ${exact})`;
2693
+ } else if (replacement._tag === "StateAssistedSigned") {
2694
+ if (mapping.source.kind !== "StateAssistedSigned")
2695
+ return yield* SessionStepUpInvalid.make({});
2696
+
2697
+ const t = mapping.source.tombstone,
2698
+ owner = column(t.table, t.subjectId),
2699
+ id = column(t.table, t.sessionId),
2700
+ expiry = column(t.table, t.absoluteExpiresAt);
2701
+
2702
+ statements.push(
2703
+ yield* statement(
2704
+ database
2705
+ .delete(t.table)
2706
+ .where(
2707
+ and(
2708
+ eq(owner, nativeSubjectId),
2709
+ eq(id, nativeSessionId),
2710
+ sql`${expiry} <= ${mapping.d1.engineNow}`,
2711
+ marker,
2712
+ ),
2713
+ ),
2714
+ ),
2715
+ );
2716
+
2717
+ const values = t.encodeInsert({
2718
+ subjectId: nativeSubjectId,
2719
+ sessionId: nativeSessionId,
2720
+ absoluteExpiresAt: replacement.tombstoneUntil,
2721
+ });
2722
+
2723
+ statements.push(
2724
+ yield* statement(database.insert(t.table).values(values)),
2725
+ yield* assertion(sql`changes() = 1`),
2726
+ );
2727
+
2728
+ const exact = and(
2729
+ eq(owner, nativeSubjectId),
2730
+ eq(id, nativeSessionId),
2731
+ eq(expiry, t.encodeInstant(replacement.tombstoneUntil)),
2732
+ )!;
2733
+
2734
+ post = sql`exists(select 1 from ${t.table} where ${exact})`;
2735
+ }
2736
+ statements.push(yield* assertion(and(marker, post, live)!));
2737
+
2738
+ return { receipt: prepare(replacement.inspection, journal), statements };
2739
+ }),
2740
+ mapping.isConstraintConflict,
2741
+ recover,
2742
+ ),
2743
+ };
2744
+ };
2745
+
2746
+ export const makeD1SessionStepUpServices = <
2747
+ Claims,
2748
+ Id,
2749
+ S extends AnySQLiteTable,
2750
+ C extends AnySQLiteTable,
2751
+ I extends AnySQLiteTable,
2752
+ Session extends AnySQLiteTable,
2753
+ T extends AnySQLiteTable,
2754
+ NativeId,
2755
+ NativeSessionId,
2756
+ >(
2757
+ database: Database,
2758
+ mapping: D1SessionStepUpMapping<NoInfer<Claims>, S, C, I, Session, T, NativeId, NativeSessionId>,
2759
+ target: Context.Service<Id, SessionStepUpPersistence<Claims>>,
2760
+ ) =>
2761
+ Effect.gen(function* () {
2762
+ const hooks = yield* LifecycleHooks;
2763
+ const raw = makeD1SessionStepUp<Claims>(mapping as any);
2764
+
2765
+ const run = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
2766
+ Effect.gen(function* () {
2767
+ if (
2768
+ (yield* Effect.serviceOption(CurrentD1SessionBatch))._tag === "Some" ||
2769
+ (yield* hasCommitScope)
2770
+ )
2771
+ return yield* unavailable();
2772
+
2773
+ return yield* effect.pipe(
2774
+ Effect.provideService(CurrentD1PlanningDatabase, database),
2775
+ Effect.provideService(LifecycleHooks, hooks),
2776
+ );
2777
+ });
2778
+
2779
+ const sessionStepUpPersistence = target.of({
2780
+ create: (input, now, prepare) => run(raw.create(input, now, prepare)),
2781
+ context: (input) => run(raw.context(input)),
2782
+ read: (input) => run(raw.read(input)),
2783
+ reject: (input, prepare) => run(raw.reject(input, prepare)),
2784
+ complete: (plan, prepare) => run(raw.complete(plan, prepare)),
2785
+ });
2786
+
2787
+ return { sessionStepUpPersistence };
2788
+ });
2789
+
2790
+ export function coordinateD1SessionStepUp<
2791
+ Claims,
2792
+ Id,
2793
+ S extends AnySQLiteTable,
2794
+ C extends AnySQLiteTable,
2795
+ I extends AnySQLiteTable,
2796
+ Session extends AnySQLiteTable,
2797
+ T extends AnySQLiteTable,
2798
+ NativeId,
2799
+ NativeSessionId,
2800
+ A,
2801
+ E,
2802
+ R,
2803
+ DatabaseError,
2804
+ DatabaseRequirements,
2805
+ >(
2806
+ acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
2807
+ options: {
2808
+ readonly mapping: D1SessionStepUpMapping<
2809
+ NoInfer<Claims>,
2810
+ S,
2811
+ C,
2812
+ I,
2813
+ Session,
2814
+ T,
2815
+ NativeId,
2816
+ NativeSessionId
2817
+ >;
2818
+ readonly target: SuppliedService<Id, SessionStepUpPersistence<Claims>>;
2819
+ },
2820
+ body: Effect.Effect<A, E, R>,
2821
+ ): Effect.Effect<
2822
+ A,
2823
+ D1CoordinatorError<E> | DatabaseError,
2824
+ Exclude<R, Id | D1BatchStatements> | LifecycleHooks | DatabaseRequirements
2825
+ > {
2826
+ return Effect.flatMap(acquire, (database) =>
2827
+ coordinateD1SessionBatch(
2828
+ database,
2829
+ (batch) =>
2830
+ Effect.gen(function* () {
2831
+ const hooks = yield* LifecycleHooks;
2832
+ const raw = makeD1SessionStepUp<Claims>(options.mapping as any);
2833
+
2834
+ const run = <Out, Failure, Requirements>(
2835
+ effect: Effect.Effect<Out, Failure, Requirements>,
2836
+ ) =>
2837
+ batch.owner.run(
2838
+ effect.pipe(
2839
+ Effect.provideService(CurrentD1PlanningDatabase, database),
2840
+ Effect.provideService(LifecycleHooks, hooks),
2841
+ Effect.provideService(CurrentD1SessionBatch, batch),
2842
+ ),
2843
+ );
2844
+
2845
+ const sessionStepUpPersistence = options.target.of({
2846
+ create: (input, now, prepare) => run(raw.create(input, now, prepare)),
2847
+ context: (input) => run(raw.context(input)),
2848
+ read: (input) => run(raw.read(input)),
2849
+ reject: (input, prepare) => run(raw.reject(input, prepare)),
2850
+ complete: (plan, prepare) => run(raw.complete(plan, prepare)),
2851
+ });
2852
+
2853
+ return { sessionStepUpPersistence };
2854
+ }),
2855
+ (
2856
+ ownedServices: { readonly sessionStepUpPersistence: SessionStepUpPersistence<Claims> },
2857
+ batch,
2858
+ ) => {
2859
+ const provided = Context.make(options.target, ownedServices.sessionStepUpPersistence).pipe(
2860
+ Context.add(D1BatchStatements, batch.owner.collector),
2861
+ );
2862
+
2863
+ return Effect.provideContext(body, provided);
2864
+ },
2865
+ ),
2866
+ );
2867
+ }