@yielded/auth-persistence 0.1.0-beta.24 → 0.1.0-beta.26

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 (481) hide show
  1. package/README.md +6 -8
  2. package/dist/Adapter.d.mts +47 -33
  3. package/dist/Adapter.mjs +36 -23
  4. package/dist/OAuthPersistence.d.mts +35 -51
  5. package/dist/OAuthPersistence.mjs +60 -68
  6. package/dist/OAuthPersistence.mjs.map +1 -1
  7. package/dist/index.d.mts +2 -2
  8. package/dist/index.mjs +2 -2
  9. package/dist/internal/browser-login.d.mts +1 -1
  10. package/dist/internal/browser-login.mjs +29 -9
  11. package/dist/internal/browser-login.mjs.map +1 -1
  12. package/dist/internal/configuration.d.mts +13 -8
  13. package/dist/internal/configuration.mjs.map +1 -1
  14. package/dist/internal/crypto.d.mts +1 -0
  15. package/dist/internal/crypto.mjs +1 -1
  16. package/dist/internal/d1-planning.mjs +8 -0
  17. package/dist/internal/d1-planning.mjs.map +1 -0
  18. package/dist/internal/email-native-state.mjs +135 -0
  19. package/dist/internal/email-native-state.mjs.map +1 -0
  20. package/dist/internal/email-native.d.mts +17 -0
  21. package/dist/internal/email-native.mjs +245 -0
  22. package/dist/internal/email-native.mjs.map +1 -0
  23. package/dist/internal/email-policy.mjs +92 -0
  24. package/dist/internal/email-policy.mjs.map +1 -0
  25. package/dist/internal/email-registration-native.d.mts +38 -0
  26. package/dist/internal/email-registration-native.mjs +171 -0
  27. package/dist/internal/email-registration-native.mjs.map +1 -0
  28. package/dist/internal/models/email-model.d.mts +40 -104
  29. package/dist/internal/models/email-model.mjs +3 -5
  30. package/dist/internal/models/email-model.mjs.map +1 -1
  31. package/dist/internal/models/oauth-connected-model.d.mts +44 -213
  32. package/dist/internal/models/oauth-connected-model.mjs +6 -14
  33. package/dist/internal/models/oauth-connected-model.mjs.map +1 -1
  34. package/dist/internal/models/oauth-model.d.mts +95 -244
  35. package/dist/internal/models/oauth-model.mjs +28 -22
  36. package/dist/internal/models/oauth-model.mjs.map +1 -1
  37. package/dist/internal/models/passkey-model.d.mts +11 -147
  38. package/dist/internal/models/passkey-model.mjs +5 -24
  39. package/dist/internal/models/passkey-model.mjs.map +1 -1
  40. package/dist/internal/models/passkey-registration-ceremony-model.d.mts +5 -39
  41. package/dist/internal/models/passkey-write-model.d.mts +17 -75
  42. package/dist/internal/models/passkey-write-model.mjs +1 -7
  43. package/dist/internal/models/passkey-write-model.mjs.map +1 -1
  44. package/dist/internal/models/password-model.d.mts +16 -82
  45. package/dist/internal/models/password-model.mjs +1 -4
  46. package/dist/internal/models/password-model.mjs.map +1 -1
  47. package/dist/internal/models/phone-model.d.mts +86 -0
  48. package/dist/internal/models/phone-model.mjs +10 -0
  49. package/dist/internal/models/phone-model.mjs.map +1 -0
  50. package/dist/internal/models/proof-model.d.mts +43 -272
  51. package/dist/internal/models/proof-model.mjs +2 -10
  52. package/dist/internal/models/proof-model.mjs.map +1 -1
  53. package/dist/internal/models/session-model.d.mts +74 -93
  54. package/dist/internal/models/session-model.mjs +3 -11
  55. package/dist/internal/models/session-model.mjs.map +1 -1
  56. package/dist/internal/models/step-up-model.d.mts +12 -50
  57. package/dist/internal/models/step-up-model.mjs +2 -4
  58. package/dist/internal/models/step-up-model.mjs.map +1 -1
  59. package/dist/internal/models/totp-model.d.mts +76 -0
  60. package/dist/internal/models/totp-model.mjs +10 -0
  61. package/dist/internal/models/totp-model.mjs.map +1 -0
  62. package/dist/internal/native-sql-table.d.mts +21 -4
  63. package/dist/internal/native-sql-table.mjs +9 -5
  64. package/dist/internal/native-sql-table.mjs.map +1 -1
  65. package/dist/internal/oauth/native-accounts.d.mts +17 -0
  66. package/dist/internal/oauth/native-accounts.mjs +290 -0
  67. package/dist/internal/oauth/native-accounts.mjs.map +1 -0
  68. package/dist/internal/oauth/native-connected-state.d.mts +11 -0
  69. package/dist/internal/oauth/native-connected-state.mjs +146 -0
  70. package/dist/internal/oauth/native-connected-state.mjs.map +1 -0
  71. package/dist/internal/oauth/native-connected.d.mts +15 -0
  72. package/dist/internal/oauth/native-connected.mjs +462 -0
  73. package/dist/internal/oauth/native-connected.mjs.map +1 -0
  74. package/dist/internal/oauth/native-flow.mjs +138 -0
  75. package/dist/internal/oauth/native-flow.mjs.map +1 -0
  76. package/dist/internal/oauth/native-layers.d.mts +24 -0
  77. package/dist/internal/oauth/native-layers.mjs +13 -0
  78. package/dist/internal/oauth/native-layers.mjs.map +1 -0
  79. package/dist/internal/oauth/native-mutation.mjs +122 -0
  80. package/dist/internal/oauth/native-mutation.mjs.map +1 -0
  81. package/dist/internal/oauth/native-registration.d.mts +24 -0
  82. package/dist/internal/oauth/native-registration.mjs +328 -0
  83. package/dist/internal/oauth/native-registration.mjs.map +1 -0
  84. package/dist/internal/oauth/native-revocations.d.mts +17 -0
  85. package/dist/internal/oauth/native-revocations.mjs +106 -0
  86. package/dist/internal/oauth/native-revocations.mjs.map +1 -0
  87. package/dist/internal/oauth/native-sign-in.d.mts +17 -0
  88. package/dist/internal/oauth/native-sign-in.mjs +50 -0
  89. package/dist/internal/oauth/native-sign-in.mjs.map +1 -0
  90. package/dist/internal/oauth/native-state.d.mts +10 -0
  91. package/dist/internal/oauth/native-state.mjs +214 -0
  92. package/dist/internal/oauth/native-state.mjs.map +1 -0
  93. package/dist/internal/oauth/state.d.mts +10 -0
  94. package/dist/internal/oauth/state.mjs +3 -27
  95. package/dist/internal/oauth/state.mjs.map +1 -1
  96. package/dist/internal/passkey-actions.mjs +55 -0
  97. package/dist/internal/passkey-actions.mjs.map +1 -0
  98. package/dist/internal/passkey-inputs.mjs +73 -0
  99. package/dist/internal/passkey-inputs.mjs.map +1 -0
  100. package/dist/internal/passkey-managed.mjs +224 -0
  101. package/dist/internal/passkey-managed.mjs.map +1 -0
  102. package/dist/internal/passkey-native-ceremony.d.mts +35 -0
  103. package/dist/internal/passkey-native-ceremony.mjs +38 -0
  104. package/dist/internal/passkey-native-ceremony.mjs.map +1 -0
  105. package/dist/internal/passkey-native-flow.mjs +91 -0
  106. package/dist/internal/passkey-native-flow.mjs.map +1 -0
  107. package/dist/internal/passkey-native-registration.d.mts +10 -0
  108. package/dist/internal/passkey-native-registration.mjs +114 -0
  109. package/dist/internal/passkey-native-registration.mjs.map +1 -0
  110. package/dist/internal/passkey-native-state.d.mts +15 -0
  111. package/dist/internal/passkey-native-state.mjs +186 -0
  112. package/dist/internal/passkey-native-state.mjs.map +1 -0
  113. package/dist/internal/passkey-native-write.d.mts +82 -0
  114. package/dist/internal/passkey-native-write.mjs +330 -0
  115. package/dist/internal/passkey-native-write.mjs.map +1 -0
  116. package/dist/internal/passkey-native.d.mts +835 -0
  117. package/dist/internal/passkey-native.mjs +175 -0
  118. package/dist/internal/passkey-native.mjs.map +1 -0
  119. package/dist/internal/passkey-policy.mjs +115 -0
  120. package/dist/internal/passkey-policy.mjs.map +1 -0
  121. package/dist/internal/password-credentials.mjs +38 -9
  122. package/dist/internal/password-credentials.mjs.map +1 -1
  123. package/dist/internal/password-native.d.mts +14 -0
  124. package/dist/internal/password-native.mjs +292 -0
  125. package/dist/internal/password-native.mjs.map +1 -0
  126. package/dist/internal/password-policy.mjs +93 -0
  127. package/dist/internal/password-policy.mjs.map +1 -0
  128. package/dist/internal/password-registration-native.d.mts +22 -0
  129. package/dist/internal/password-registration-native.mjs +142 -0
  130. package/dist/internal/password-registration-native.mjs.map +1 -0
  131. package/dist/internal/persistence.d.mts +6 -19
  132. package/dist/internal/persistence.mjs +199 -166
  133. package/dist/internal/persistence.mjs.map +1 -1
  134. package/dist/internal/phone-composed.mjs +79 -0
  135. package/dist/internal/phone-composed.mjs.map +1 -0
  136. package/dist/internal/phone-native.d.mts +15 -0
  137. package/dist/internal/phone-native.mjs +354 -0
  138. package/dist/internal/phone-native.mjs.map +1 -0
  139. package/dist/internal/proof-native.d.mts +15 -0
  140. package/dist/internal/proof-native.mjs +289 -0
  141. package/dist/internal/proof-native.mjs.map +1 -0
  142. package/dist/internal/registration.mjs +50 -60
  143. package/dist/internal/registration.mjs.map +1 -1
  144. package/dist/internal/session-native-authority.d.mts +15 -0
  145. package/dist/internal/session-native-authority.mjs +91 -0
  146. package/dist/internal/session-native-authority.mjs.map +1 -0
  147. package/dist/internal/session-native-cleanup.d.mts +14 -0
  148. package/dist/internal/session-native-cleanup.mjs +48 -0
  149. package/dist/internal/session-native-cleanup.mjs.map +1 -0
  150. package/dist/internal/session-native-login.d.mts +15 -0
  151. package/dist/internal/session-native-login.mjs +87 -0
  152. package/dist/internal/session-native-login.mjs.map +1 -0
  153. package/dist/internal/session-native-pending-read.mjs +42 -0
  154. package/dist/internal/session-native-pending-read.mjs.map +1 -0
  155. package/dist/internal/session-native-pending.mjs +134 -0
  156. package/dist/internal/session-native-pending.mjs.map +1 -0
  157. package/dist/internal/session-native-record.mjs +79 -0
  158. package/dist/internal/session-native-record.mjs.map +1 -0
  159. package/dist/internal/session-native-state.mjs +130 -0
  160. package/dist/internal/session-native-state.mjs.map +1 -0
  161. package/dist/internal/session-native-stateful.d.mts +16 -0
  162. package/dist/internal/session-native-stateful.mjs +225 -0
  163. package/dist/internal/session-native-stateful.mjs.map +1 -0
  164. package/dist/internal/session-native-step-up.d.mts +15 -0
  165. package/dist/internal/session-native-step-up.mjs +212 -0
  166. package/dist/internal/session-native-step-up.mjs.map +1 -0
  167. package/dist/internal/session-native-validity.d.mts +15 -0
  168. package/dist/internal/session-native-validity.mjs +97 -0
  169. package/dist/internal/session-native-validity.mjs.map +1 -0
  170. package/dist/internal/session-policy.mjs +29 -0
  171. package/dist/internal/session-policy.mjs.map +1 -0
  172. package/dist/internal/sql-authority.d.mts +16 -0
  173. package/dist/internal/sql-authority.mjs +32 -0
  174. package/dist/internal/sql-authority.mjs.map +1 -0
  175. package/dist/internal/sql-change.mjs +21 -0
  176. package/dist/internal/sql-change.mjs.map +1 -0
  177. package/dist/internal/sql-cleanup.mjs +35 -0
  178. package/dist/internal/sql-cleanup.mjs.map +1 -0
  179. package/dist/internal/sql-commit.d.mts +72 -0
  180. package/dist/internal/sql-commit.mjs +176 -0
  181. package/dist/internal/sql-commit.mjs.map +1 -0
  182. package/dist/internal/sql-expression.d.mts +17 -0
  183. package/dist/internal/sql-expression.mjs +49 -0
  184. package/dist/internal/sql-expression.mjs.map +1 -0
  185. package/dist/internal/sql-oauth-connected-model.d.mts +7 -23
  186. package/dist/internal/sql-oauth-model.d.mts +27 -52
  187. package/dist/internal/sql-oauth-model.mjs +3 -4
  188. package/dist/internal/sql-oauth-model.mjs.map +1 -1
  189. package/dist/internal/sql-persistence.mjs +5 -9
  190. package/dist/internal/sql-persistence.mjs.map +1 -1
  191. package/dist/internal/sql-storage-validation.mjs +1 -2
  192. package/dist/internal/sql-storage-validation.mjs.map +1 -1
  193. package/dist/internal/sql-table.d.mts +3 -16
  194. package/dist/internal/sql-table.mjs +21 -42
  195. package/dist/internal/sql-table.mjs.map +1 -1
  196. package/dist/internal/standalone.mjs +2 -3
  197. package/dist/internal/standalone.mjs.map +1 -1
  198. package/dist/internal/step-up-state.mjs +5 -8
  199. package/dist/internal/step-up-state.mjs.map +1 -1
  200. package/dist/internal/storage-clock.mjs +44 -0
  201. package/dist/internal/storage-clock.mjs.map +1 -0
  202. package/dist/internal/storage-mapping.d.mts +11 -8
  203. package/dist/internal/storage-mapping.mjs +88 -302
  204. package/dist/internal/storage-mapping.mjs.map +1 -1
  205. package/dist/internal/storage-plans.mjs +15 -73
  206. package/dist/internal/storage-plans.mjs.map +1 -1
  207. package/dist/internal/storage-tables.d.mts +37 -520
  208. package/dist/internal/storage-tables.mjs +31 -211
  209. package/dist/internal/storage-tables.mjs.map +1 -1
  210. package/dist/internal/storage-validation.d.mts +1 -6
  211. package/dist/internal/storage-validation.mjs +1 -42
  212. package/dist/internal/storage-validation.mjs.map +1 -1
  213. package/dist/internal/table-model.d.mts +21 -0
  214. package/dist/internal/totp-native.d.mts +15 -0
  215. package/dist/internal/totp-native.mjs +401 -0
  216. package/dist/internal/totp-native.mjs.map +1 -0
  217. package/package.json +1 -1
  218. package/src/Adapter.ts +143 -199
  219. package/src/OAuthPersistence.ts +128 -271
  220. package/src/index.ts +1 -1
  221. package/src/internal/browser-login.ts +54 -24
  222. package/src/internal/configuration.ts +16 -31
  223. package/src/internal/d1-planning.ts +7 -0
  224. package/src/internal/email-native-state.ts +247 -0
  225. package/src/internal/email-native.ts +514 -0
  226. package/src/internal/email-policy.ts +235 -0
  227. package/src/internal/email-registration-native.ts +386 -0
  228. package/src/internal/models/email-model.ts +76 -214
  229. package/src/internal/models/oauth-connected-model.ts +50 -288
  230. package/src/internal/models/oauth-model.ts +147 -368
  231. package/src/internal/models/passkey-model.ts +11 -208
  232. package/src/internal/models/passkey-registration-ceremony-model.ts +6 -60
  233. package/src/internal/models/passkey-write-model.ts +14 -95
  234. package/src/internal/models/password-model.ts +28 -148
  235. package/src/internal/models/phone-model.ts +110 -0
  236. package/src/internal/models/proof-model.ts +48 -404
  237. package/src/internal/models/session-model.ts +102 -200
  238. package/src/internal/models/step-up-model.ts +17 -96
  239. package/src/internal/models/totp-model.ts +82 -0
  240. package/src/internal/native-sql-table.ts +32 -11
  241. package/src/internal/oauth/native-accounts.ts +576 -0
  242. package/src/internal/oauth/native-connected-state.ts +288 -0
  243. package/src/internal/oauth/native-connected.ts +888 -0
  244. package/src/internal/oauth/native-flow.ts +253 -0
  245. package/src/internal/oauth/native-layers.ts +83 -0
  246. package/src/internal/oauth/native-mutation.ts +222 -0
  247. package/src/internal/oauth/native-registration.ts +545 -0
  248. package/src/internal/oauth/native-revocations.ts +190 -0
  249. package/src/internal/oauth/native-sign-in.ts +111 -0
  250. package/src/internal/oauth/native-state.ts +346 -0
  251. package/src/internal/oauth/state.ts +2 -70
  252. package/src/internal/passkey-actions.ts +70 -0
  253. package/src/internal/passkey-inputs.ts +56 -0
  254. package/src/internal/passkey-managed.ts +360 -0
  255. package/src/internal/passkey-native-ceremony.ts +66 -0
  256. package/src/internal/passkey-native-flow.ts +140 -0
  257. package/src/internal/passkey-native-registration.ts +221 -0
  258. package/src/internal/passkey-native-state.ts +335 -0
  259. package/src/internal/passkey-native-write.ts +611 -0
  260. package/src/internal/passkey-native.ts +372 -0
  261. package/src/internal/passkey-policy.ts +246 -0
  262. package/src/internal/password-credentials.ts +52 -10
  263. package/src/internal/password-native.ts +571 -0
  264. package/src/internal/password-policy.ts +307 -0
  265. package/src/internal/password-registration-native.ts +322 -0
  266. package/src/internal/persistence.ts +336 -290
  267. package/src/internal/phone-composed.ts +86 -0
  268. package/src/internal/phone-native.ts +659 -0
  269. package/src/internal/proof-native.ts +448 -0
  270. package/src/internal/registration.ts +96 -143
  271. package/src/internal/session-native-authority.ts +247 -0
  272. package/src/internal/session-native-cleanup.ts +65 -0
  273. package/src/internal/session-native-login.ts +205 -0
  274. package/src/internal/session-native-pending-read.ts +68 -0
  275. package/src/internal/session-native-pending.ts +223 -0
  276. package/src/internal/session-native-record.ts +141 -0
  277. package/src/internal/session-native-state.ts +259 -0
  278. package/src/internal/session-native-stateful.ts +512 -0
  279. package/src/internal/session-native-step-up.ts +450 -0
  280. package/src/internal/session-native-validity.ts +208 -0
  281. package/src/internal/session-policy.ts +59 -0
  282. package/src/internal/sql-authority.ts +56 -0
  283. package/src/internal/sql-change.ts +38 -0
  284. package/src/internal/sql-cleanup.ts +56 -0
  285. package/src/internal/sql-commit.ts +435 -0
  286. package/src/internal/sql-expression.ts +94 -0
  287. package/src/internal/sql-metadata.ts +100 -0
  288. package/src/internal/sql-oauth-connected-model.ts +6 -95
  289. package/src/internal/sql-oauth-model.ts +31 -134
  290. package/src/internal/sql-persistence.ts +2 -6
  291. package/src/internal/sql-storage-validation.ts +1 -2
  292. package/src/internal/sql-table.ts +19 -52
  293. package/src/internal/standalone.ts +2 -11
  294. package/src/internal/step-up-state.ts +4 -17
  295. package/src/internal/storage-clock.ts +58 -0
  296. package/src/internal/storage-mapping.ts +125 -340
  297. package/src/internal/storage-plans.ts +14 -80
  298. package/src/internal/storage-tables.ts +28 -212
  299. package/src/internal/storage-validation.ts +0 -58
  300. package/src/internal/table-model.ts +24 -0
  301. package/src/internal/totp-native.ts +701 -0
  302. package/dist/internal/PasswordPreparedPostconditions.d.mts +0 -22
  303. package/dist/internal/PasswordPreparedPostconditions.mjs +0 -12
  304. package/dist/internal/PasswordPreparedPostconditions.mjs.map +0 -1
  305. package/dist/internal/authority-snapshot.mjs +0 -53
  306. package/dist/internal/authority-snapshot.mjs.map +0 -1
  307. package/dist/internal/email-kernel.d.mts +0 -276
  308. package/dist/internal/email-kernel.mjs +0 -497
  309. package/dist/internal/email-kernel.mjs.map +0 -1
  310. package/dist/internal/models/passkey-registration-ceremony-model.mjs +0 -18
  311. package/dist/internal/models/passkey-registration-ceremony-model.mjs.map +0 -1
  312. package/dist/internal/oauth/accounts.d.mts +0 -8
  313. package/dist/internal/oauth/accounts.mjs +0 -379
  314. package/dist/internal/oauth/accounts.mjs.map +0 -1
  315. package/dist/internal/oauth/connected-access.d.mts +0 -9
  316. package/dist/internal/oauth/connected-access.mjs +0 -229
  317. package/dist/internal/oauth/connected-access.mjs.map +0 -1
  318. package/dist/internal/oauth/connected-collection.d.mts +0 -7
  319. package/dist/internal/oauth/connected-collection.mjs +0 -214
  320. package/dist/internal/oauth/connected-collection.mjs.map +0 -1
  321. package/dist/internal/oauth/connected-custody.d.mts +0 -6
  322. package/dist/internal/oauth/connected-custody.mjs +0 -165
  323. package/dist/internal/oauth/connected-custody.mjs.map +0 -1
  324. package/dist/internal/oauth/connected-flow.d.mts +0 -7
  325. package/dist/internal/oauth/connected-flow.mjs +0 -324
  326. package/dist/internal/oauth/connected-flow.mjs.map +0 -1
  327. package/dist/internal/oauth/connected-input.mjs +0 -122
  328. package/dist/internal/oauth/connected-input.mjs.map +0 -1
  329. package/dist/internal/oauth/connected-keys.d.mts +0 -2
  330. package/dist/internal/oauth/connected-keys.mjs +0 -22
  331. package/dist/internal/oauth/connected-keys.mjs.map +0 -1
  332. package/dist/internal/oauth/connected-maintenance.d.mts +0 -9
  333. package/dist/internal/oauth/connected-maintenance.mjs +0 -226
  334. package/dist/internal/oauth/connected-maintenance.mjs.map +0 -1
  335. package/dist/internal/oauth/connected-management.d.mts +0 -9
  336. package/dist/internal/oauth/connected-management.mjs +0 -243
  337. package/dist/internal/oauth/connected-management.mjs.map +0 -1
  338. package/dist/internal/oauth/connected-reference.mjs +0 -63
  339. package/dist/internal/oauth/connected-reference.mjs.map +0 -1
  340. package/dist/internal/oauth/connected-settlement.d.mts +0 -8
  341. package/dist/internal/oauth/connected-settlement.mjs +0 -141
  342. package/dist/internal/oauth/connected-settlement.mjs.map +0 -1
  343. package/dist/internal/oauth/connected-sign-in.d.mts +0 -10
  344. package/dist/internal/oauth/connected-sign-in.mjs +0 -281
  345. package/dist/internal/oauth/connected-sign-in.mjs.map +0 -1
  346. package/dist/internal/oauth/connected-state.d.mts +0 -14
  347. package/dist/internal/oauth/connected-state.mjs +0 -469
  348. package/dist/internal/oauth/connected-state.mjs.map +0 -1
  349. package/dist/internal/oauth/connected-target.d.mts +0 -21
  350. package/dist/internal/oauth/connected-target.mjs +0 -117
  351. package/dist/internal/oauth/connected-target.mjs.map +0 -1
  352. package/dist/internal/oauth/flow.d.mts +0 -5
  353. package/dist/internal/oauth/flow.mjs +0 -279
  354. package/dist/internal/oauth/flow.mjs.map +0 -1
  355. package/dist/internal/oauth/input.mjs +0 -127
  356. package/dist/internal/oauth/input.mjs.map +0 -1
  357. package/dist/internal/oauth/owner.d.mts +0 -10
  358. package/dist/internal/oauth/owner.mjs +0 -10
  359. package/dist/internal/oauth/owner.mjs.map +0 -1
  360. package/dist/internal/oauth/query-compiler.d.mts +0 -7
  361. package/dist/internal/oauth/query-compiler.mjs +0 -9
  362. package/dist/internal/oauth/query-compiler.mjs.map +0 -1
  363. package/dist/internal/oauth/registration.d.mts +0 -7
  364. package/dist/internal/oauth/registration.mjs +0 -393
  365. package/dist/internal/oauth/registration.mjs.map +0 -1
  366. package/dist/internal/oauth/target.d.mts +0 -31
  367. package/dist/internal/oauth/target.mjs +0 -273
  368. package/dist/internal/oauth/target.mjs.map +0 -1
  369. package/dist/internal/oauth-kernel.d.mts +0 -1423
  370. package/dist/internal/oauth-kernel.mjs +0 -187
  371. package/dist/internal/oauth-kernel.mjs.map +0 -1
  372. package/dist/internal/passkey/admission.d.mts +0 -6
  373. package/dist/internal/passkey/admission.mjs +0 -220
  374. package/dist/internal/passkey/admission.mjs.map +0 -1
  375. package/dist/internal/passkey/credentials.d.mts +0 -14
  376. package/dist/internal/passkey/credentials.mjs +0 -249
  377. package/dist/internal/passkey/credentials.mjs.map +0 -1
  378. package/dist/internal/passkey/enrollment.mjs +0 -138
  379. package/dist/internal/passkey/enrollment.mjs.map +0 -1
  380. package/dist/internal/passkey/flow.d.mts +0 -21
  381. package/dist/internal/passkey/flow.mjs +0 -452
  382. package/dist/internal/passkey/flow.mjs.map +0 -1
  383. package/dist/internal/passkey/management.mjs +0 -231
  384. package/dist/internal/passkey/management.mjs.map +0 -1
  385. package/dist/internal/passkey/registration-ceremony.d.mts +0 -9
  386. package/dist/internal/passkey/registration-ceremony.mjs +0 -129
  387. package/dist/internal/passkey/registration-ceremony.mjs.map +0 -1
  388. package/dist/internal/passkey/registration-custody.d.mts +0 -2
  389. package/dist/internal/passkey/registration-custody.mjs +0 -52
  390. package/dist/internal/passkey/registration-custody.mjs.map +0 -1
  391. package/dist/internal/passkey/registration-write.mjs +0 -211
  392. package/dist/internal/passkey/registration-write.mjs.map +0 -1
  393. package/dist/internal/passkey/state.d.mts +0 -10
  394. package/dist/internal/passkey/state.mjs +0 -234
  395. package/dist/internal/passkey/state.mjs.map +0 -1
  396. package/dist/internal/passkey/target.d.mts +0 -20
  397. package/dist/internal/passkey/target.mjs +0 -200
  398. package/dist/internal/passkey/target.mjs.map +0 -1
  399. package/dist/internal/passkey/write-state.d.mts +0 -17
  400. package/dist/internal/passkey/write-state.mjs +0 -346
  401. package/dist/internal/passkey/write-state.mjs.map +0 -1
  402. package/dist/internal/passkey/write-target.mjs +0 -192
  403. package/dist/internal/passkey/write-target.mjs.map +0 -1
  404. package/dist/internal/passkey-kernel.d.mts +0 -6045
  405. package/dist/internal/passkey-kernel.mjs +0 -49
  406. package/dist/internal/passkey-kernel.mjs.map +0 -1
  407. package/dist/internal/passkeys.d.mts +0 -7
  408. package/dist/internal/passkeys.mjs +0 -387
  409. package/dist/internal/passkeys.mjs.map +0 -1
  410. package/dist/internal/password-credentials.d.mts +0 -11
  411. package/dist/internal/password-kernel.d.mts +0 -278
  412. package/dist/internal/password-kernel.mjs +0 -508
  413. package/dist/internal/password-kernel.mjs.map +0 -1
  414. package/dist/internal/phone-kernel.d.mts +0 -162
  415. package/dist/internal/phone-kernel.mjs +0 -437
  416. package/dist/internal/phone-kernel.mjs.map +0 -1
  417. package/dist/internal/proof-kernel.d.mts +0 -94
  418. package/dist/internal/proof-kernel.mjs +0 -624
  419. package/dist/internal/proof-kernel.mjs.map +0 -1
  420. package/dist/internal/query-operations.d.mts +0 -68
  421. package/dist/internal/session-kernel.d.mts +0 -62
  422. package/dist/internal/session-kernel.mjs +0 -820
  423. package/dist/internal/session-kernel.mjs.map +0 -1
  424. package/dist/internal/sql-oauth-connected-model.mjs +0 -7
  425. package/dist/internal/sql-oauth-connected-model.mjs.map +0 -1
  426. package/dist/internal/sql-query.d.mts +0 -12
  427. package/dist/internal/sql-query.mjs +0 -206
  428. package/dist/internal/sql-query.mjs.map +0 -1
  429. package/dist/internal/step-up-state.d.mts +0 -49
  430. package/dist/internal/transaction-execution-kernel.d.mts +0 -37
  431. package/dist/internal/transaction-execution-kernel.mjs +0 -120
  432. package/dist/internal/transaction-execution-kernel.mjs.map +0 -1
  433. package/dist/internal/transaction-kernel.d.mts +0 -81
  434. package/dist/internal/transaction-kernel.mjs +0 -264
  435. package/dist/internal/transaction-kernel.mjs.map +0 -1
  436. package/src/internal/PasswordPreparedPostconditions.ts +0 -30
  437. package/src/internal/authority-snapshot.ts +0 -91
  438. package/src/internal/email-kernel.ts +0 -1555
  439. package/src/internal/oauth/accounts.ts +0 -838
  440. package/src/internal/oauth/connected-access.ts +0 -388
  441. package/src/internal/oauth/connected-collection.ts +0 -345
  442. package/src/internal/oauth/connected-custody.ts +0 -308
  443. package/src/internal/oauth/connected-flow.ts +0 -562
  444. package/src/internal/oauth/connected-input.ts +0 -147
  445. package/src/internal/oauth/connected-keys.ts +0 -31
  446. package/src/internal/oauth/connected-maintenance.ts +0 -379
  447. package/src/internal/oauth/connected-management.ts +0 -391
  448. package/src/internal/oauth/connected-reference.ts +0 -135
  449. package/src/internal/oauth/connected-settlement.ts +0 -278
  450. package/src/internal/oauth/connected-sign-in.ts +0 -472
  451. package/src/internal/oauth/connected-state.ts +0 -924
  452. package/src/internal/oauth/connected-target.ts +0 -307
  453. package/src/internal/oauth/flow.ts +0 -505
  454. package/src/internal/oauth/input.ts +0 -201
  455. package/src/internal/oauth/owner.ts +0 -22
  456. package/src/internal/oauth/query-compiler.ts +0 -15
  457. package/src/internal/oauth/registration.ts +0 -676
  458. package/src/internal/oauth/target.ts +0 -803
  459. package/src/internal/oauth-kernel.ts +0 -294
  460. package/src/internal/passkey/admission.ts +0 -368
  461. package/src/internal/passkey/credentials.ts +0 -511
  462. package/src/internal/passkey/enrollment.ts +0 -326
  463. package/src/internal/passkey/flow.ts +0 -1062
  464. package/src/internal/passkey/management.ts +0 -426
  465. package/src/internal/passkey/registration-ceremony.ts +0 -283
  466. package/src/internal/passkey/registration-custody.ts +0 -91
  467. package/src/internal/passkey/registration-write.ts +0 -426
  468. package/src/internal/passkey/state.ts +0 -351
  469. package/src/internal/passkey/target.ts +0 -598
  470. package/src/internal/passkey/write-state.ts +0 -678
  471. package/src/internal/passkey/write-target.ts +0 -450
  472. package/src/internal/passkey-kernel.ts +0 -112
  473. package/src/internal/passkeys.ts +0 -652
  474. package/src/internal/password-kernel.ts +0 -1522
  475. package/src/internal/phone-kernel.ts +0 -872
  476. package/src/internal/proof-kernel.ts +0 -1992
  477. package/src/internal/query-operations.ts +0 -91
  478. package/src/internal/session-kernel.ts +0 -2406
  479. package/src/internal/sql-query.ts +0 -304
  480. package/src/internal/transaction-execution-kernel.ts +0 -335
  481. package/src/internal/transaction-kernel.ts +0 -603
@@ -1,1992 +0,0 @@
1
- import {
2
- coordinateCommit,
3
- CurrentCommitJournal,
4
- hasCommitScope,
5
- LifecycleHooks,
6
- HookConfigurationError,
7
- } from "@yielded/auth/Hooks";
8
- import { reportPersistenceFailure } from "@yielded/auth/Persistence";
9
- import {
10
- type ProofCompletionPlan,
11
- ProofBinding,
12
- type ProofAttemptDecision,
13
- type ProofCleanupResult,
14
- type ProofCompletionDecision,
15
- type ProofDeliveryOutcome,
16
- type ProofVersion,
17
- type ProofBudget,
18
- type ProofPolicy,
19
- ProofPersistence,
20
- type ProofDeliveryClaim,
21
- ProofRequestConflict,
22
- ProofUnavailable,
23
- } from "@yielded/auth/Proofs";
24
- import { Cause, Context, DateTime, Effect, Option, Schema } from "effect";
25
- import type * as SqlError from "effect/sql/SqlError";
26
-
27
- import { PersistenceMappingError } from "./mapping-error";
28
- import {
29
- type AnyProofPersistenceMapping,
30
- requiredProofConstraints,
31
- type ProofPersistenceMapping,
32
- type ProofAction,
33
- type ProofCommandDecision,
34
- type ProofContinuationRecord,
35
- type ProofScopeKeys,
36
- type ProofScopeKind,
37
- } from "./models/proof-model";
38
- import {
39
- CurrentPasswordPreparedTransaction,
40
- PasswordPreparedPostconditions,
41
- } from "./PasswordPreparedPostconditions";
42
- /* oxlint-disable no-explicit-any -- existing storage kernels erase foreign table shapes; domain errors remain typed. */
43
- import type { TableModel as Table } from "./query-operations";
44
- import type { QueryFailure } from "./query-operations";
45
- import type { QueryOperations, SqlFragment, SqlColumn } from "./query-operations";
46
- import type { NativeDatabase } from "./transaction-kernel";
47
-
48
- type AdapterFailure = QueryFailure | PersistenceMappingError | SqlError.SqlError;
49
-
50
- export interface ProofSqlQuery<A = ReadonlyArray<any>> extends Effect.Effect<A, AdapterFailure> {
51
- readonly getSQL: () => ReturnType<QueryOperations["sql"]>;
52
- readonly from: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
53
- readonly where: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
54
- readonly limit: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
55
- readonly orderBy: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
56
- readonly for: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
57
- readonly set: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
58
- readonly values: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
59
- readonly onConflictDoNothing: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
60
- readonly onDuplicateKeyUpdate: (...args: ReadonlyArray<any>) => ProofSqlQuery<A>;
61
- }
62
-
63
- export interface ProofSqlDatabase {
64
- readonly select: (...args: ReadonlyArray<any>) => ProofSqlQuery;
65
- readonly insert: (...args: ReadonlyArray<any>) => ProofSqlQuery;
66
- readonly update: (...args: ReadonlyArray<any>) => ProofSqlQuery;
67
- readonly delete: (...args: ReadonlyArray<any>) => ProofSqlQuery;
68
- readonly transaction: <A, E, R>(
69
- body: (transaction: ProofSqlDatabase) => Effect.Effect<A, E, R>,
70
- ) => Effect.Effect<A, E | SqlError.SqlError, R>;
71
- }
72
-
73
- export class CurrentProofSql extends Context.Service<CurrentProofSql, ProofSqlDatabase>()(
74
- "effect-auth/CurrentProofSql",
75
- ) {}
76
-
77
- export interface ProofSqlConfiguration {
78
- readonly mode: "interactive" | "synchronous";
79
- readonly locking: boolean;
80
- readonly standaloneGuard: Effect.Effect<void, ProofUnavailable>;
81
- readonly coordinated?: boolean;
82
- /** Dialect-native insert-if-absent used to create serialization anchors. */
83
- readonly insertIfAbsent: (
84
- query: ProofSqlQuery,
85
- selfKey: string,
86
- selfValue: unknown,
87
- ) => ProofSqlQuery;
88
- }
89
-
90
- type Database = ProofSqlDatabase;
91
-
92
- interface ScopeEntry {
93
- readonly kind: ProofScopeKind;
94
- readonly key: string;
95
- readonly budget: ProofBudget;
96
- }
97
-
98
- export const makeProofKernel = <
99
- Fragment extends SqlFragment = SqlFragment,
100
- Column extends SqlColumn = SqlColumn,
101
- >(
102
- operations: QueryOperations<Fragment, Column>,
103
- ) => {
104
- type Mapping = AnyProofPersistenceMapping<Fragment>;
105
-
106
- const { and, eq, gte, inArray, isNull, lte, notExists, sql, column, updateValues } = operations;
107
- const unavailable = () => ProofUnavailable.make({});
108
-
109
- const translateFailure = <A, E, R>(
110
- effect: Effect.Effect<A, E, R>,
111
- ): Effect.Effect<A, ProofUnavailable, R> =>
112
- reportPersistenceFailure(
113
- effect,
114
- (error) => Schema.is(ProofUnavailable)(error) || Schema.is(HookConfigurationError)(error),
115
- ).pipe(Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, () => unavailable()))));
116
-
117
- const translateIssueFailure = <A, E, R>(
118
- effect: Effect.Effect<A, E, R>,
119
- ): Effect.Effect<A, ProofUnavailable | ProofRequestConflict, R> =>
120
- reportPersistenceFailure(
121
- effect,
122
- (error) =>
123
- Schema.is(ProofUnavailable)(error) ||
124
- Schema.is(ProofRequestConflict)(error) ||
125
- Schema.is(HookConfigurationError)(error),
126
- ).pipe(
127
- Effect.catchCause((cause) =>
128
- Effect.failCause(
129
- Cause.map(cause, (error) =>
130
- Schema.is(ProofRequestConflict)(error) ? error : unavailable(),
131
- ),
132
- ),
133
- ),
134
- );
135
-
136
- const conflict = () => ProofRequestConflict.make({});
137
-
138
- const validConstraints = (mapping: Mapping) =>
139
- Object.entries(requiredProofConstraints).every(
140
- ([key, value]) => mapping.constraints[key as keyof typeof requiredProofConstraints] === value,
141
- );
142
-
143
- const selectRows = (query: ProofSqlQuery, locking: boolean) =>
144
- locking && typeof query.for === "function" ? query.for("update") : query;
145
-
146
- const allocateVersion = (
147
- mapping: Mapping,
148
- mode: ProofSqlConfiguration["mode"],
149
- ): Effect.Effect<ProofVersion, ProofUnavailable | PersistenceMappingError> => {
150
- if (mode === "synchronous")
151
- return mapping.allocateVersionSync === undefined
152
- ? Effect.fail(unavailable())
153
- : Effect.try({
154
- try: mapping.allocateVersionSync,
155
- catch: (cause) => new PersistenceMappingError({ operation: "mapping", cause }),
156
- });
157
- if (mapping.allocateVersion !== undefined) return mapping.allocateVersion;
158
-
159
- return mapping.allocateVersionSync === undefined
160
- ? Effect.fail(unavailable())
161
- : Effect.try({
162
- try: mapping.allocateVersionSync,
163
- catch: (cause) => new PersistenceMappingError({ operation: "mapping", cause }),
164
- });
165
- };
166
-
167
- const canonicalBinding = Schema.encodeSync(Schema.fromJsonString(ProofBinding));
168
-
169
- const sameBinding = (left: ProofBinding, right: ProofBinding): boolean =>
170
- canonicalBinding(left) === canonicalBinding(right);
171
-
172
- const requestColumns = (mapping: Mapping) => ({
173
- moduleId: column(mapping.request.table, mapping.request.moduleId),
174
- requestId: column(mapping.request.table, mapping.request.requestId),
175
- fingerprint: column(mapping.request.table, mapping.request.fingerprint),
176
- proofId: column(mapping.request.table, mapping.request.proofId),
177
- retentionUntil: column(mapping.request.table, mapping.request.retentionUntil),
178
- });
179
-
180
- const seriesColumns = (mapping: Mapping) => ({
181
- moduleId: column(mapping.series.table, mapping.series.moduleId),
182
- purpose: column(mapping.series.table, mapping.series.purpose),
183
- scopeKey: column(mapping.series.table, mapping.series.scopeKey),
184
- activeProofId: column(mapping.series.table, mapping.series.activeProofId),
185
- lastIssueAt: column(mapping.series.table, mapping.series.lastIssueAt),
186
- version: column(mapping.series.table, mapping.series.version),
187
- });
188
-
189
- const generationColumns = (mapping: Mapping) => ({
190
- moduleId: column(mapping.generation.table, mapping.generation.moduleId),
191
- purpose: column(mapping.generation.table, mapping.generation.purpose),
192
- proofId: column(mapping.generation.table, mapping.generation.proofId),
193
- requestId: column(mapping.generation.table, mapping.generation.requestId),
194
- seriesKey: column(mapping.generation.table, mapping.generation.seriesKey),
195
- deliveryId: column(mapping.generation.table, mapping.generation.deliveryId),
196
- verifierKeyId: column(mapping.generation.table, mapping.generation.verifierKeyId),
197
- verifierDigest: column(mapping.generation.table, mapping.generation.verifierDigest),
198
- issuedAt: column(mapping.generation.table, mapping.generation.issuedAt),
199
- expiresAt: column(mapping.generation.table, mapping.generation.expiresAt),
200
- version: column(mapping.generation.table, mapping.generation.version),
201
- state: column(mapping.generation.table, mapping.generation.state),
202
- sendCount: column(mapping.generation.table, mapping.generation.sendCount),
203
- deliveryState: column(mapping.generation.table, mapping.generation.deliveryState),
204
- claimVersion: column(mapping.generation.table, mapping.generation.claimVersion),
205
- claimDeadline: column(mapping.generation.table, mapping.generation.claimDeadline),
206
- retryAt: column(mapping.generation.table, mapping.generation.retryAt),
207
- deliveryRetryMillis: column(mapping.generation.table, mapping.generation.deliveryRetryMillis),
208
- retentionUntil: column(mapping.generation.table, mapping.generation.retentionUntil),
209
- });
210
-
211
- const continuationColumns = (mapping: Mapping) => ({
212
- moduleId: column(mapping.continuation.table, mapping.continuation.moduleId),
213
- purpose: column(mapping.continuation.table, mapping.continuation.purpose),
214
- continuationId: column(mapping.continuation.table, mapping.continuation.continuationId),
215
- digest: column(mapping.continuation.table, mapping.continuation.digest),
216
- proofId: column(mapping.continuation.table, mapping.continuation.proofId),
217
- seriesKey: column(mapping.continuation.table, mapping.continuation.seriesKey),
218
- expiresAt: column(mapping.continuation.table, mapping.continuation.expiresAt),
219
- consumed: column(mapping.continuation.table, mapping.continuation.consumed),
220
- version: column(mapping.continuation.table, mapping.continuation.version),
221
- retentionUntil: column(mapping.continuation.table, mapping.continuation.retentionUntil),
222
- });
223
-
224
- const scopeColumns = (mapping: Mapping) => ({
225
- moduleId: column(mapping.rateScope.table, mapping.rateScope.moduleId),
226
- purpose: column(mapping.rateScope.table, mapping.rateScope.purpose),
227
- action: column(mapping.rateScope.table, mapping.rateScope.action),
228
- scopeKind: column(mapping.rateScope.table, mapping.rateScope.scopeKind),
229
- scopeKey: column(mapping.rateScope.table, mapping.rateScope.scopeKey),
230
- });
231
-
232
- const abuseColumns = (mapping: Mapping) => ({
233
- moduleId: column(mapping.abuseEvent.table, mapping.abuseEvent.moduleId),
234
- purpose: column(mapping.abuseEvent.table, mapping.abuseEvent.purpose),
235
- action: column(mapping.abuseEvent.table, mapping.abuseEvent.action),
236
- scopeKind: column(mapping.abuseEvent.table, mapping.abuseEvent.scopeKind),
237
- scopeKey: column(mapping.abuseEvent.table, mapping.abuseEvent.scopeKey),
238
- commandId: column(mapping.abuseEvent.table, mapping.abuseEvent.commandId),
239
- occurredAt: column(mapping.abuseEvent.table, mapping.abuseEvent.occurredAt),
240
- retentionUntil: column(mapping.abuseEvent.table, mapping.abuseEvent.retentionUntil),
241
- });
242
-
243
- const failureColumns = (mapping: Mapping) => ({
244
- moduleId: column(mapping.failureEvent.table, mapping.failureEvent.moduleId),
245
- purpose: column(mapping.failureEvent.table, mapping.failureEvent.purpose),
246
- seriesKey: column(mapping.failureEvent.table, mapping.failureEvent.seriesKey),
247
- commandId: column(mapping.failureEvent.table, mapping.failureEvent.commandId),
248
- occurredAt: column(mapping.failureEvent.table, mapping.failureEvent.occurredAt),
249
- retentionUntil: column(mapping.failureEvent.table, mapping.failureEvent.retentionUntil),
250
- });
251
-
252
- const commandColumns = (mapping: Mapping) => ({
253
- moduleId: column(mapping.command.table, mapping.command.moduleId),
254
- commandId: column(mapping.command.table, mapping.command.commandId),
255
- kind: column(mapping.command.table, mapping.command.kind),
256
- decision: column(mapping.command.table, mapping.command.decision),
257
- retentionUntil: column(mapping.command.table, mapping.command.retentionUntil),
258
- });
259
-
260
- const nowMillis = DateTime.now.pipe(Effect.map(DateTime.toEpochMillis));
261
-
262
- const lockAuthority = Effect.fn("DrizzleProof.lockAuthority")(function* (
263
- mapping: Mapping,
264
- moduleId: string,
265
- purpose: any,
266
- binding: ProofBinding,
267
- locking: boolean,
268
- ) {
269
- const database = yield* CurrentProofSql;
270
-
271
- const authority = mapping.authority;
272
- let nativeSubjectId: unknown | undefined;
273
-
274
- // Canonical order: subject, identifier rows, credentials sorted by ID.
275
- if (binding._tag !== "Identifier") {
276
- if (
277
- authority.subject === undefined ||
278
- authority.credential === undefined ||
279
- authority.subjectId === undefined
280
- )
281
- return yield* unavailable();
282
- nativeSubjectId = yield* authority.subjectId.toNative(binding.revision.subjectId);
283
- const subject = authority.subject;
284
-
285
- const rows = yield* selectRows(
286
- database
287
- .select()
288
- .from(subject.table)
289
- .where(eq(column(subject.table, subject.id), nativeSubjectId))
290
- .limit(1),
291
- locking,
292
- );
293
-
294
- const row = rows[0];
295
-
296
- if (
297
- row === undefined ||
298
- !subject.isActiveStatus(row[subject.status]) ||
299
- row[subject.securityRevision] !== binding.revision.securityRevision
300
- )
301
- return false;
302
- }
303
- const identifier = authority.identifier;
304
-
305
- const identifierRows = yield* selectRows(
306
- database
307
- .select()
308
- .from(identifier.table)
309
- .where(
310
- and(
311
- eq(column(identifier.table, identifier.namespace), binding.identifier.namespace),
312
- eq(column(identifier.table, identifier.value), binding.identifier.value),
313
- ),
314
- ),
315
- locking,
316
- );
317
-
318
- if (
319
- !identifier.isCurrent(
320
- {
321
- moduleId,
322
- purpose,
323
- binding,
324
- ...(nativeSubjectId === undefined ? {} : { nativeSubjectId }),
325
- },
326
- identifierRows,
327
- )
328
- )
329
- return false;
330
- if (binding._tag === "Identifier") return true;
331
- const credential = authority.credential!;
332
-
333
- const expected = [...binding.revision.credentials].sort((a, b) =>
334
- a.credentialId.localeCompare(b.credentialId),
335
- );
336
-
337
- const rows =
338
- expected.length === 0
339
- ? []
340
- : yield* selectRows(
341
- database
342
- .select()
343
- .from(credential.table)
344
- .where(
345
- and(
346
- eq(column(credential.table, credential.subjectId), nativeSubjectId),
347
- inArray(
348
- column(credential.table, credential.credentialId),
349
- expected.map((item) => item.credentialId),
350
- ),
351
- ),
352
- ),
353
- locking,
354
- );
355
-
356
- if (rows.length !== expected.length) return false;
357
-
358
- const actual = rows
359
- .map((row: any) => ({
360
- credentialId: row[credential.credentialId] as string,
361
- revision: row[credential.revision],
362
- active:
363
- credential.status === undefined ||
364
- credential.isActiveStatus?.(row[credential.status]) === true,
365
- }))
366
- .sort((a: any, b: any) => a.credentialId.localeCompare(b.credentialId));
367
-
368
- return actual.every(
369
- (item: any, index: number) =>
370
- item.active &&
371
- item.credentialId === expected[index]?.credentialId &&
372
- item.revision === expected[index]?.revision,
373
- );
374
- });
375
-
376
- const scopeEntries = (
377
- keys: ProofScopeKeys,
378
- binding: ProofBinding,
379
- action: ProofAction,
380
- policy: ProofPolicy,
381
- ): ReadonlyArray<ScopeEntry> => {
382
- const suffix = action === "issue" ? "Issues" : "Attempts";
383
- const simple = action === "issue" ? "issues" : "attempts";
384
-
385
- const entries: ScopeEntry[] = [
386
- { kind: "action", key: "*", budget: policy.abuse[`action${suffix}`] },
387
- { kind: "identifier", key: keys.identifier, budget: policy.abuse[simple] },
388
- ];
389
-
390
- if (binding._tag !== "Identifier")
391
- entries.push({
392
- kind: "subject",
393
- key: keys.subject,
394
- budget: policy.abuse[`subject${suffix}`],
395
- });
396
-
397
- return entries;
398
- };
399
-
400
- const lockScopes = Effect.fn("DrizzleProof.lockScopes")(function* (
401
- mapping: Mapping,
402
- configuration: ProofSqlConfiguration,
403
- moduleId: string,
404
- purpose: any,
405
- action: ProofAction,
406
- entries: ReadonlyArray<ScopeEntry>,
407
- ) {
408
- const database = yield* CurrentProofSql;
409
-
410
- const c = scopeColumns(mapping);
411
-
412
- for (const entry of entries) {
413
- const values = mapping.rateScope.encodeInsert({
414
- moduleId,
415
- purpose,
416
- action,
417
- scopeKind: entry.kind,
418
- scopeKey: entry.key,
419
- });
420
-
421
- const query = database.insert(mapping.rateScope.table).values(values);
422
-
423
- yield* configuration.insertIfAbsent(query, mapping.rateScope.scopeKey, entry.key);
424
- yield* selectRows(
425
- database
426
- .select()
427
- .from(mapping.rateScope.table)
428
- .where(
429
- and(
430
- eq(c.moduleId, moduleId),
431
- eq(c.purpose, purpose),
432
- eq(c.action, action),
433
- eq(c.scopeKind, entry.kind),
434
- eq(c.scopeKey, entry.key),
435
- ),
436
- )
437
- .limit(1),
438
- configuration.locking,
439
- );
440
- }
441
- });
442
-
443
- const admittedScopes = Effect.fn("DrizzleProof.admittedScopes")(function* (
444
- mapping: Mapping,
445
- moduleId: string,
446
- purpose: any,
447
- action: ProofAction,
448
- entries: ReadonlyArray<ScopeEntry>,
449
- now: number,
450
- ) {
451
- const database = yield* CurrentProofSql;
452
-
453
- const c = abuseColumns(mapping);
454
- const admitted: ScopeEntry[] = [];
455
-
456
- for (const entry of entries) {
457
- const rows = yield* selectRows(
458
- database
459
- .select({ commandId: c.commandId })
460
- .from(mapping.abuseEvent.table)
461
- .where(
462
- and(
463
- eq(c.moduleId, moduleId),
464
- eq(c.purpose, purpose),
465
- eq(c.action, action),
466
- eq(c.scopeKind, entry.kind),
467
- eq(c.scopeKey, entry.key),
468
- gte(c.occurredAt, mapping.encodeInstant(now - entry.budget.windowMillis)),
469
- ),
470
- )
471
- .limit(entry.budget.limit),
472
- true,
473
- );
474
-
475
- if (rows.length < entry.budget.limit) admitted.push(entry);
476
- }
477
-
478
- return admitted;
479
- });
480
-
481
- const insertScopeEvents = Effect.fn("Drizzle.insertScopeEvents")(function* (
482
- mapping: Mapping,
483
- moduleId: string,
484
- purpose: any,
485
- action: ProofAction,
486
- commandId: string,
487
- entries: ReadonlyArray<ScopeEntry>,
488
- now: number,
489
- retentionUntil: number,
490
- ) {
491
- const database = yield* CurrentProofSql;
492
-
493
- return yield* Effect.forEach(
494
- entries,
495
- (entry) =>
496
- database.insert(mapping.abuseEvent.table).values(
497
- mapping.abuseEvent.encodeInsert({
498
- moduleId,
499
- purpose,
500
- action,
501
- scopeKind: entry.kind,
502
- scopeKey: entry.key,
503
- commandId,
504
- occurredAtMillis: now,
505
- retentionUntilMillis: retentionUntil,
506
- }),
507
- ),
508
- { discard: true },
509
- );
510
- });
511
-
512
- const ensureSeries = Effect.fn("DrizzleProof.ensureSeries")(function* (
513
- mapping: Mapping,
514
- configuration: ProofSqlConfiguration,
515
- moduleId: string,
516
- purpose: any,
517
- scopeKey: string,
518
- ) {
519
- const database = yield* CurrentProofSql;
520
-
521
- const c = seriesColumns(mapping);
522
- const initialVersion = yield* allocateVersion(mapping, configuration.mode);
523
-
524
- const query = database
525
- .insert(mapping.series.table)
526
- .values(
527
- mapping.series.encodeInsert({ moduleId, purpose, scopeKey, version: initialVersion }),
528
- );
529
-
530
- yield* configuration.insertIfAbsent(query, mapping.series.scopeKey, scopeKey);
531
-
532
- const rows = yield* selectRows(
533
- database
534
- .select()
535
- .from(mapping.series.table)
536
- .where(and(eq(c.moduleId, moduleId), eq(c.purpose, purpose), eq(c.scopeKey, scopeKey)))
537
- .limit(1),
538
- configuration.locking,
539
- );
540
-
541
- return rows[0] ?? (yield* unavailable());
542
- });
543
-
544
- const readGeneration = Effect.fn("Drizzle.readGeneration")(function* (
545
- mapping: Mapping,
546
- moduleId: string,
547
- proofId: string,
548
- locking: boolean,
549
- ) {
550
- const database = yield* CurrentProofSql;
551
-
552
- const c = generationColumns(mapping);
553
-
554
- return yield* selectRows(
555
- database
556
- .select()
557
- .from(mapping.generation.table)
558
- .where(and(eq(c.moduleId, moduleId), eq(c.proofId, proofId)))
559
- .limit(1),
560
- locking,
561
- );
562
- });
563
-
564
- const failureCount = Effect.fn("DrizzleProof.failureCount")(function* (
565
- mapping: Mapping,
566
- moduleId: string,
567
- purpose: any,
568
- seriesKey: string,
569
- now: number,
570
- policy: ProofPolicy,
571
- ) {
572
- const database = yield* CurrentProofSql;
573
-
574
- const c = failureColumns(mapping);
575
-
576
- const rows = yield* selectRows(
577
- database
578
- .select({ commandId: c.commandId })
579
- .from(mapping.failureEvent.table)
580
- .where(
581
- and(
582
- eq(c.moduleId, moduleId),
583
- eq(c.purpose, purpose),
584
- eq(c.seriesKey, seriesKey),
585
- gte(c.occurredAt, mapping.encodeInstant(now - policy.abuse.attempts.windowMillis)),
586
- ),
587
- )
588
- .limit(policy.maximumFailedAttempts),
589
- true,
590
- );
591
-
592
- return rows.length;
593
- });
594
-
595
- const commandRow = Effect.fn("Drizzle.commandRow")(function* (
596
- mapping: Mapping,
597
- moduleId: string,
598
- commandId: string,
599
- locking: boolean,
600
- ) {
601
- const database = yield* CurrentProofSql;
602
-
603
- const c = commandColumns(mapping);
604
-
605
- return yield* selectRows(
606
- database
607
- .select()
608
- .from(mapping.command.table)
609
- .where(and(eq(c.moduleId, moduleId), eq(c.commandId, commandId)))
610
- .limit(1),
611
- locking,
612
- );
613
- });
614
-
615
- const insertCommand = Effect.fn("Drizzle.insertCommand")(function* (
616
- mapping: Mapping,
617
- moduleId: string,
618
- commandId: string,
619
- kind: "attempt" | "complete",
620
- decision: ProofCommandDecision,
621
- retentionUntil: number,
622
- ) {
623
- const database = yield* CurrentProofSql;
624
-
625
- return yield* database.insert(mapping.command.table).values(
626
- mapping.command.encodeInsert({
627
- moduleId,
628
- commandId,
629
- kind,
630
- decision,
631
- retentionUntilMillis: retentionUntil,
632
- }),
633
- );
634
- });
635
-
636
- const owned = <A, E, R>(
637
- database: Database,
638
- mapping: Mapping,
639
- configuration: ProofSqlConfiguration,
640
- body: Effect.Effect<A, E, R>,
641
- ) => {
642
- if (!validConstraints(mapping)) return Effect.fail(unavailable());
643
-
644
- const run = coordinateCommit(
645
- () =>
646
- database.transaction((transaction) =>
647
- body.pipe(Effect.provideService(CurrentProofSql, transaction)),
648
- ),
649
- { mode: configuration.mode },
650
- ).pipe(Effect.map((result) => result.value));
651
-
652
- return configuration.coordinated !== true
653
- ? Effect.gen(function* () {
654
- if (yield* hasCommitScope) return yield* unavailable();
655
- yield* configuration.standaloneGuard;
656
-
657
- return yield* run;
658
- })
659
- : run;
660
- };
661
-
662
- const makeSqlProofPersistence = Effect.fn("makeSqlProofPersistence")(function* (
663
- mapping: Mapping,
664
- configuration: ProofSqlConfiguration,
665
- ): Effect.fn.Return<
666
- ProofPersistence["Service"],
667
- ProofUnavailable,
668
- LifecycleHooks | CurrentProofSql | NativeDatabase
669
- > {
670
- const database = yield* CurrentProofSql;
671
-
672
- if (!configuration.coordinated)
673
- yield* (operations.validateStorage?.(mapping) ?? Effect.void).pipe(
674
- Effect.mapError(unavailable),
675
- );
676
- const hooks = yield* LifecycleHooks;
677
-
678
- return ProofPersistence.of({
679
- issue: (input, prepare) =>
680
- owned(
681
- database,
682
- mapping,
683
- configuration,
684
- Effect.gen(function* () {
685
- const transaction = yield* CurrentProofSql;
686
- const journal = yield* CurrentCommitJournal;
687
-
688
- const keys = mapping.scopeKeys({
689
- moduleId: input.record.moduleId,
690
- purpose: input.record.purpose,
691
- binding: input.record.binding,
692
- });
693
-
694
- const authorityCurrent = yield* lockAuthority(
695
- mapping,
696
- input.record.moduleId,
697
- input.record.purpose,
698
- input.record.binding,
699
- configuration.locking,
700
- );
701
-
702
- const scopes = scopeEntries(keys, input.record.binding, "issue", input.policy);
703
-
704
- yield* lockScopes(
705
- mapping,
706
- configuration,
707
- input.record.moduleId,
708
- input.record.purpose,
709
- "issue",
710
- scopes.slice(0, 1),
711
- );
712
- const actionNow = yield* nowMillis;
713
-
714
- const actionOpen =
715
- (yield* admittedScopes(
716
- mapping,
717
- input.record.moduleId,
718
- input.record.purpose,
719
- "issue",
720
- scopes.slice(0, 1),
721
- actionNow,
722
- )).length === 1;
723
-
724
- if (actionOpen)
725
- yield* lockScopes(
726
- mapping,
727
- configuration,
728
- input.record.moduleId,
729
- input.record.purpose,
730
- "issue",
731
- scopes.slice(1),
732
- );
733
-
734
- const series = actionOpen
735
- ? yield* ensureSeries(
736
- mapping,
737
- configuration,
738
- input.record.moduleId,
739
- input.record.purpose,
740
- keys.series,
741
- )
742
- : undefined;
743
-
744
- const now = yield* nowMillis;
745
- const retentionUntil = now + input.policy.requestRetentionMillis;
746
- const rc = requestColumns(mapping);
747
-
748
- let requestRows = yield* selectRows(
749
- transaction
750
- .select()
751
- .from(mapping.request.table)
752
- .where(
753
- and(
754
- eq(rc.moduleId, input.record.moduleId),
755
- eq(rc.requestId, input.record.requestId),
756
- ),
757
- )
758
- .limit(1),
759
- configuration.locking,
760
- );
761
-
762
- let request = requestRows[0];
763
-
764
- if (request !== undefined) {
765
- const retainedUntil = yield* mapping.decodeInstant(
766
- request[mapping.request.retentionUntil],
767
- );
768
-
769
- if (retainedUntil > now) {
770
- if (request[mapping.request.fingerprint] !== input.record.fingerprint)
771
- return yield* conflict();
772
- const receipt = yield* mapping.request.decodeReceipt(request);
773
-
774
- return prepare({ _tag: "Existing", receipt }, journal);
775
- }
776
- yield* transaction
777
- .delete(mapping.request.table)
778
- .where(
779
- and(
780
- eq(rc.moduleId, input.record.moduleId),
781
- eq(rc.requestId, input.record.requestId),
782
- lte(rc.retentionUntil, mapping.encodeInstant(now)),
783
- ),
784
- );
785
- }
786
-
787
- const requestInsert = mapping.request.encodeInsert({
788
- record: input.record,
789
- createdAtMillis: now,
790
- retentionUntilMillis: retentionUntil,
791
- });
792
-
793
- const requestQuery = transaction.insert(mapping.request.table).values(requestInsert);
794
-
795
- yield* configuration.insertIfAbsent(
796
- requestQuery,
797
- mapping.request.requestId,
798
- input.record.requestId,
799
- );
800
- requestRows = yield* selectRows(
801
- transaction
802
- .select()
803
- .from(mapping.request.table)
804
- .where(
805
- and(
806
- eq(rc.moduleId, input.record.moduleId),
807
- eq(rc.requestId, input.record.requestId),
808
- ),
809
- )
810
- .limit(1),
811
- configuration.locking,
812
- );
813
- request = requestRows[0];
814
-
815
- if (request === undefined) return yield* unavailable();
816
- if (request[mapping.request.fingerprint] !== input.record.fingerprint)
817
- return yield* conflict();
818
- if (request[mapping.request.proofId] !== input.record.proofId) {
819
- const receipt = yield* mapping.request.decodeReceipt(request);
820
-
821
- return prepare({ _tag: "Existing", receipt }, journal);
822
- }
823
-
824
- const admitted = actionOpen
825
- ? yield* admittedScopes(
826
- mapping,
827
- input.record.moduleId,
828
- input.record.purpose,
829
- "issue",
830
- scopes,
831
- now,
832
- )
833
- : [];
834
-
835
- const sc = seriesColumns(mapping);
836
-
837
- const lastIssueAt =
838
- series?.[mapping.series.lastIssueAt] === null ||
839
- series?.[mapping.series.lastIssueAt] === undefined
840
- ? undefined
841
- : yield* mapping.decodeInstant(series[mapping.series.lastIssueAt]);
842
-
843
- const activeProofId = series?.[mapping.series.activeProofId] as
844
- | string
845
- | null
846
- | undefined;
847
-
848
- const activeGeneration =
849
- activeProofId === null || activeProofId === undefined
850
- ? undefined
851
- : (yield* readGeneration(
852
- mapping,
853
- input.record.moduleId,
854
- activeProofId,
855
- configuration.locking,
856
- ))[0];
857
-
858
- if (
859
- activeProofId !== null &&
860
- activeProofId !== undefined &&
861
- (activeGeneration === undefined ||
862
- activeGeneration[mapping.generation.purpose] !== input.record.purpose)
863
- )
864
- return yield* unavailable();
865
-
866
- const replacementAuthorized =
867
- activeGeneration === undefined ||
868
- activeGeneration[mapping.generation.state] !== "active" ||
869
- (yield* mapping.decodeInstant(activeGeneration[mapping.generation.expiresAt])) <=
870
- now ||
871
- sameBinding(
872
- yield* mapping.generation.decodeBinding(activeGeneration),
873
- input.record.binding,
874
- );
875
-
876
- const supersedesCurrent =
877
- input.supersedes === undefined || input.supersedes === activeProofId;
878
-
879
- const allowed =
880
- authorityCurrent &&
881
- input.eligible &&
882
- admitted.length === scopes.length &&
883
- input.record.issuedAtMillis <= now &&
884
- input.record.expiresAtMillis > now &&
885
- replacementAuthorized &&
886
- supersedesCurrent &&
887
- (lastIssueAt === undefined ||
888
- now - lastIssueAt >= input.policy.abuse.resendCooldownMillis);
889
-
890
- const receipt = {
891
- requestId: input.record.requestId,
892
- reference: {
893
- proofId: input.record.proofId,
894
- purpose: input.record.purpose,
895
- keyId: input.record.verifier.keyId,
896
- },
897
- };
898
-
899
- const prepared = prepare(
900
- allowed
901
- ? ({ _tag: "Issued", record: input.record } as const)
902
- : ({ _tag: "Suppressed", receipt } as const),
903
- journal,
904
- );
905
-
906
- if (!allowed) return prepared;
907
- yield* insertScopeEvents(
908
- mapping,
909
- input.record.moduleId,
910
- input.record.purpose,
911
- "issue",
912
- input.record.requestId,
913
- scopes,
914
- now,
915
- retentionUntil,
916
- );
917
- if (activeProofId !== null && activeProofId !== undefined)
918
- yield* transaction
919
- .update(mapping.generation.table)
920
- .set(updateValues([[mapping.generation.state, "superseded"]]))
921
- .where(
922
- and(
923
- eq(generationColumns(mapping).moduleId, input.record.moduleId),
924
- eq(generationColumns(mapping).proofId, activeProofId),
925
- eq(generationColumns(mapping).state, "active"),
926
- ),
927
- );
928
- yield* transaction.insert(mapping.generation.table).values(
929
- mapping.generation.encodeInsert({
930
- record: input.record,
931
- seriesKey: keys.series,
932
- retentionUntilMillis: retentionUntil,
933
- state: "active",
934
- deliveryState: "new",
935
- policy: input.policy,
936
- }),
937
- );
938
- const nextVersion = yield* allocateVersion(mapping, configuration.mode);
939
-
940
- yield* transaction
941
- .update(mapping.series.table)
942
- .set(
943
- updateValues([
944
- [mapping.series.activeProofId, input.record.proofId],
945
- [mapping.series.lastIssueAt, mapping.encodeInstant(now)],
946
- [mapping.series.version, nextVersion],
947
- ]),
948
- )
949
- .where(
950
- and(
951
- eq(sc.moduleId, input.record.moduleId),
952
- eq(sc.purpose, input.record.purpose),
953
- eq(sc.scopeKey, keys.series),
954
- ),
955
- );
956
-
957
- return prepared;
958
- }),
959
- ).pipe(
960
- Effect.provideService(CurrentProofSql, database),
961
- Effect.provideService(LifecycleHooks, hooks),
962
- translateIssueFailure,
963
- ),
964
- attempt: (input, prepare) =>
965
- owned(
966
- database,
967
- mapping,
968
- configuration,
969
- Effect.gen(function* () {
970
- const transaction = yield* CurrentProofSql;
971
- const journal = yield* CurrentCommitJournal;
972
-
973
- const keys = mapping.scopeKeys({
974
- moduleId: input.moduleId,
975
- purpose: input.purpose,
976
- binding: input.binding,
977
- });
978
-
979
- const authorityCurrent = yield* lockAuthority(
980
- mapping,
981
- input.moduleId,
982
- input.purpose,
983
- input.binding,
984
- configuration.locking,
985
- );
986
-
987
- const scopes = scopeEntries(keys, input.binding, "attempt", input.policy);
988
-
989
- yield* lockScopes(
990
- mapping,
991
- configuration,
992
- input.moduleId,
993
- input.purpose,
994
- "attempt",
995
- scopes.slice(0, 1),
996
- );
997
- const actionNow = yield* nowMillis;
998
-
999
- const actionOpen =
1000
- (yield* admittedScopes(
1001
- mapping,
1002
- input.moduleId,
1003
- input.purpose,
1004
- "attempt",
1005
- scopes.slice(0, 1),
1006
- actionNow,
1007
- )).length === 1;
1008
-
1009
- if (actionOpen)
1010
- yield* lockScopes(
1011
- mapping,
1012
- configuration,
1013
- input.moduleId,
1014
- input.purpose,
1015
- "attempt",
1016
- scopes.slice(1),
1017
- );
1018
-
1019
- const series = actionOpen
1020
- ? yield* ensureSeries(
1021
- mapping,
1022
- configuration,
1023
- input.moduleId,
1024
- input.purpose,
1025
- keys.series,
1026
- )
1027
- : undefined;
1028
-
1029
- const generation = (yield* readGeneration(
1030
- mapping,
1031
- input.moduleId,
1032
- input.proofId,
1033
- configuration.locking,
1034
- ))[0];
1035
-
1036
- const existingCommand = (yield* commandRow(
1037
- mapping,
1038
- input.moduleId,
1039
- input.continuationId,
1040
- configuration.locking,
1041
- ))[0];
1042
-
1043
- if (existingCommand !== undefined) {
1044
- if (existingCommand[mapping.command.decision] === "rejected")
1045
- return prepare({ _tag: "Rejected" }, journal);
1046
-
1047
- return yield* unavailable();
1048
- }
1049
- const now = yield* nowMillis;
1050
-
1051
- const admitted = actionOpen
1052
- ? yield* admittedScopes(
1053
- mapping,
1054
- input.moduleId,
1055
- input.purpose,
1056
- "attempt",
1057
- scopes,
1058
- now,
1059
- )
1060
- : [];
1061
-
1062
- const failures = yield* failureCount(
1063
- mapping,
1064
- input.moduleId,
1065
- input.purpose,
1066
- keys.series,
1067
- now,
1068
- input.policy,
1069
- );
1070
-
1071
- const gc = generationColumns(mapping);
1072
- const activeProofId = series?.[mapping.series.activeProofId];
1073
-
1074
- const storedBinding =
1075
- generation === undefined
1076
- ? undefined
1077
- : yield* mapping.generation.decodeBinding(generation);
1078
-
1079
- const candidateMatches =
1080
- generation !== undefined &&
1081
- input.candidate !== undefined &&
1082
- generation[mapping.generation.verifierKeyId] === input.candidate.keyId &&
1083
- generation[mapping.generation.verifierDigest] === input.candidate.digest;
1084
-
1085
- const currentGeneration =
1086
- generation !== undefined &&
1087
- generation[mapping.generation.purpose] === input.purpose &&
1088
- generation[mapping.generation.state] === "active" &&
1089
- activeProofId === input.proofId &&
1090
- storedBinding !== undefined &&
1091
- sameBinding(storedBinding, input.binding) &&
1092
- Number(yield* mapping.decodeInstant(generation[mapping.generation.expiresAt])) > now;
1093
-
1094
- const accepted =
1095
- authorityCurrent &&
1096
- currentGeneration &&
1097
- candidateMatches &&
1098
- admitted.length === scopes.length &&
1099
- failures < input.policy.maximumFailedAttempts;
1100
-
1101
- const retentionUntil = now + input.policy.requestRetentionMillis;
1102
-
1103
- if (!accepted) {
1104
- const prepared = prepare({ _tag: "Rejected" }, journal);
1105
-
1106
- yield* insertCommand(
1107
- mapping,
1108
- input.moduleId,
1109
- input.continuationId,
1110
- "attempt",
1111
- "rejected",
1112
- retentionUntil,
1113
- );
1114
- yield* insertScopeEvents(
1115
- mapping,
1116
- input.moduleId,
1117
- input.purpose,
1118
- "attempt",
1119
- input.continuationId,
1120
- admitted,
1121
- now,
1122
- retentionUntil,
1123
- );
1124
- if (
1125
- admitted.length === scopes.length &&
1126
- currentGeneration &&
1127
- !candidateMatches &&
1128
- failures < input.policy.maximumFailedAttempts
1129
- )
1130
- yield* transaction.insert(mapping.failureEvent.table).values(
1131
- mapping.failureEvent.encodeInsert({
1132
- moduleId: input.moduleId,
1133
- purpose: input.purpose,
1134
- seriesKey: keys.series,
1135
- commandId: input.continuationId,
1136
- occurredAtMillis: now,
1137
- retentionUntilMillis: retentionUntil,
1138
- }),
1139
- );
1140
-
1141
- return prepared;
1142
- }
1143
- const version = yield* allocateVersion(mapping, configuration.mode);
1144
-
1145
- const expiresAt = Math.min(
1146
- Number(yield* mapping.decodeInstant(generation![mapping.generation.expiresAt])),
1147
- now + input.policy.continuationLifetimeMillis,
1148
- );
1149
-
1150
- const continuation: ProofContinuationRecord = {
1151
- moduleId: input.moduleId,
1152
- purpose: input.purpose,
1153
- continuationId: input.continuationId,
1154
- digest: input.continuationDigest,
1155
- proofId: input.proofId,
1156
- seriesKey: keys.series,
1157
- binding: input.binding,
1158
- expiresAtMillis: expiresAt,
1159
- version,
1160
- };
1161
-
1162
- const decision: ProofAttemptDecision = {
1163
- _tag: "Accepted",
1164
- continuation: {
1165
- continuationId: input.continuationId,
1166
- purpose: input.purpose,
1167
- expiresAtMillis: expiresAt,
1168
- },
1169
- };
1170
-
1171
- const prepared = prepare(decision, journal);
1172
-
1173
- yield* insertCommand(
1174
- mapping,
1175
- input.moduleId,
1176
- input.continuationId,
1177
- "attempt",
1178
- "accepted",
1179
- retentionUntil,
1180
- );
1181
- yield* insertScopeEvents(
1182
- mapping,
1183
- input.moduleId,
1184
- input.purpose,
1185
- "attempt",
1186
- input.continuationId,
1187
- scopes,
1188
- now,
1189
- retentionUntil,
1190
- );
1191
- yield* transaction
1192
- .update(mapping.generation.table)
1193
- .set(updateValues([[mapping.generation.state, "consumed"]]))
1194
- .where(
1195
- and(
1196
- eq(gc.moduleId, input.moduleId),
1197
- eq(gc.proofId, input.proofId),
1198
- eq(gc.state, "active"),
1199
- ),
1200
- );
1201
- yield* transaction.insert(mapping.continuation.table).values(
1202
- mapping.continuation.encodeInsert({
1203
- ...continuation,
1204
- retentionUntilMillis: retentionUntil,
1205
- }),
1206
- );
1207
-
1208
- return prepared;
1209
- }),
1210
- ).pipe(
1211
- Effect.provideService(CurrentProofSql, database),
1212
- Effect.provideService(LifecycleHooks, hooks),
1213
- translateFailure,
1214
- ),
1215
- complete: (input, prepare) =>
1216
- owned(
1217
- database,
1218
- mapping,
1219
- configuration,
1220
- Effect.gen(function* () {
1221
- const journal = yield* CurrentCommitJournal;
1222
-
1223
- return yield* completeIn(mapping, configuration, input, (decision) =>
1224
- prepare(decision, journal),
1225
- );
1226
- }),
1227
- ).pipe(
1228
- Effect.provideService(CurrentProofSql, database),
1229
- Effect.provideService(LifecycleHooks, hooks),
1230
- translateFailure,
1231
- ),
1232
- claimDelivery: (input, prepare) =>
1233
- owned(
1234
- database,
1235
- mapping,
1236
- configuration,
1237
- Effect.gen(function* () {
1238
- const transaction = yield* CurrentProofSql;
1239
- const journal = yield* CurrentCommitJournal;
1240
-
1241
- const rows = yield* readGeneration(
1242
- mapping,
1243
- input.moduleId,
1244
- input.proofId,
1245
- configuration.locking,
1246
- );
1247
-
1248
- const row = rows[0];
1249
- const now = yield* nowMillis;
1250
-
1251
- if (row === undefined) return prepare({ _tag: "Declined" }, journal);
1252
- const c = generationColumns(mapping);
1253
- const expiresAt = yield* mapping.decodeInstant(row[mapping.generation.expiresAt]);
1254
-
1255
- const claimDeadline =
1256
- row[mapping.generation.claimDeadline] === null ||
1257
- row[mapping.generation.claimDeadline] === undefined
1258
- ? undefined
1259
- : yield* mapping.decodeInstant(row[mapping.generation.claimDeadline]);
1260
-
1261
- const retryAt =
1262
- row[mapping.generation.retryAt] === null ||
1263
- row[mapping.generation.retryAt] === undefined
1264
- ? undefined
1265
- : yield* mapping.decodeInstant(row[mapping.generation.retryAt]);
1266
-
1267
- let state = row[mapping.generation.deliveryState] as string;
1268
-
1269
- if (state === "claimed" && claimDeadline !== undefined && claimDeadline <= now) {
1270
- state = "ambiguous";
1271
- yield* transaction
1272
- .update(mapping.generation.table)
1273
- .set(updateValues([[mapping.generation.deliveryState, "ambiguous"]]))
1274
- .where(and(eq(c.moduleId, input.moduleId), eq(c.proofId, input.proofId)));
1275
- }
1276
-
1277
- const canClaim =
1278
- row[mapping.generation.version] === input.version &&
1279
- row[mapping.generation.deliveryId] === input.deliveryId &&
1280
- row[mapping.generation.state] === "active" &&
1281
- expiresAt > now &&
1282
- Number(row[mapping.generation.sendCount]) < input.policy.maximumDeliveryAttempts &&
1283
- (state === "new" ||
1284
- (state === "ambiguous" &&
1285
- input.allowAmbiguousRetry &&
1286
- (retryAt === undefined || retryAt <= now)));
1287
-
1288
- if (!canClaim) return prepare({ _tag: "Declined" }, journal);
1289
- const claimVersion = yield* allocateVersion(mapping, configuration.mode);
1290
- const decision: ProofDeliveryClaim = { _tag: "Claimed", claimVersion };
1291
- const prepared = prepare(decision, journal);
1292
-
1293
- yield* transaction
1294
- .update(mapping.generation.table)
1295
- .set(
1296
- updateValues([
1297
- [mapping.generation.sendCount, Number(row[mapping.generation.sendCount]) + 1],
1298
- [mapping.generation.deliveryState, "claimed"],
1299
- [mapping.generation.claimVersion, claimVersion],
1300
- [
1301
- mapping.generation.claimDeadline,
1302
- mapping.encodeInstant(now + input.policy.deliveryClaimMillis),
1303
- ],
1304
- [
1305
- mapping.generation.retryAt,
1306
- mapping.encodeInstant(now + input.policy.deliveryRetryMillis),
1307
- ],
1308
- ]),
1309
- )
1310
- .where(and(eq(c.moduleId, input.moduleId), eq(c.proofId, input.proofId)));
1311
-
1312
- return prepared;
1313
- }),
1314
- ).pipe(
1315
- Effect.provideService(CurrentProofSql, database),
1316
- Effect.provideService(LifecycleHooks, hooks),
1317
- translateFailure,
1318
- ),
1319
- settleDelivery: (input, prepare) =>
1320
- owned(
1321
- database,
1322
- mapping,
1323
- configuration,
1324
- Effect.gen(function* () {
1325
- const transaction = yield* CurrentProofSql;
1326
- const journal = yield* CurrentCommitJournal;
1327
-
1328
- const initial = (yield* readGeneration(
1329
- mapping,
1330
- input.moduleId,
1331
- input.proofId,
1332
- false,
1333
- ))[0];
1334
-
1335
- if (initial === undefined) return prepare(undefined, journal);
1336
- const keys = initial[mapping.generation.seriesKey] as string;
1337
-
1338
- yield* ensureSeries(
1339
- mapping,
1340
- configuration,
1341
- input.moduleId,
1342
- initial[mapping.generation.purpose],
1343
- keys,
1344
- );
1345
-
1346
- const row = (yield* readGeneration(
1347
- mapping,
1348
- input.moduleId,
1349
- input.proofId,
1350
- configuration.locking,
1351
- ))[0];
1352
-
1353
- const prepared = prepare(undefined, journal);
1354
-
1355
- if (
1356
- row === undefined ||
1357
- row[mapping.generation.version] !== input.version ||
1358
- row[mapping.generation.deliveryId] !== input.deliveryId ||
1359
- row[mapping.generation.claimVersion] !== input.claimVersion ||
1360
- row[mapping.generation.deliveryState] !== "claimed"
1361
- )
1362
- return prepared;
1363
- const c = generationColumns(mapping);
1364
- const outcome: ProofDeliveryOutcome = input.outcome;
1365
-
1366
- const state =
1367
- outcome._tag === "Accepted"
1368
- ? "accepted"
1369
- : outcome._tag === "DefiniteFailure"
1370
- ? "failed"
1371
- : "ambiguous";
1372
-
1373
- const values: Array<readonly [string, unknown]> = [
1374
- [mapping.generation.deliveryState, state],
1375
- [mapping.generation.claimDeadline, null],
1376
- ];
1377
-
1378
- if (outcome._tag === "Ambiguous")
1379
- values.push([
1380
- mapping.generation.retryAt,
1381
- mapping.encodeInstant(
1382
- (yield* nowMillis) + Number(row[mapping.generation.deliveryRetryMillis]),
1383
- ),
1384
- ]);
1385
- if (outcome._tag === "DefiniteFailure")
1386
- values.push([mapping.generation.state, "cancelled"]);
1387
- yield* transaction
1388
- .update(mapping.generation.table)
1389
- .set(updateValues(values))
1390
- .where(and(eq(c.moduleId, input.moduleId), eq(c.proofId, input.proofId)));
1391
- if (outcome._tag === "DefiniteFailure") {
1392
- const sc = seriesColumns(mapping);
1393
-
1394
- yield* transaction
1395
- .update(mapping.series.table)
1396
- .set(updateValues([[mapping.series.activeProofId, null]]))
1397
- .where(
1398
- and(
1399
- eq(sc.moduleId, input.moduleId),
1400
- eq(sc.purpose, row[mapping.generation.purpose]),
1401
- eq(sc.scopeKey, keys),
1402
- eq(sc.activeProofId, input.proofId),
1403
- ),
1404
- );
1405
- }
1406
-
1407
- return prepared;
1408
- }),
1409
- ).pipe(
1410
- Effect.provideService(CurrentProofSql, database),
1411
- Effect.provideService(LifecycleHooks, hooks),
1412
- translateFailure,
1413
- ),
1414
- cancel: (input, prepare) =>
1415
- owned(
1416
- database,
1417
- mapping,
1418
- configuration,
1419
- Effect.gen(function* () {
1420
- const transaction = yield* CurrentProofSql;
1421
- const journal = yield* CurrentCommitJournal;
1422
-
1423
- const authorityCurrent = yield* lockAuthority(
1424
- mapping,
1425
- input.moduleId,
1426
- input.purpose,
1427
- input.binding,
1428
- configuration.locking,
1429
- );
1430
-
1431
- const keys = mapping.scopeKeys({
1432
- moduleId: input.moduleId,
1433
- purpose: input.purpose,
1434
- binding: input.binding,
1435
- });
1436
-
1437
- const series = yield* ensureSeries(
1438
- mapping,
1439
- configuration,
1440
- input.moduleId,
1441
- input.purpose,
1442
- keys.series,
1443
- );
1444
-
1445
- const active = series[mapping.series.activeProofId] as string | undefined | null;
1446
- const prepared = prepare(undefined, journal);
1447
-
1448
- if (authorityCurrent && active !== undefined && active !== null) {
1449
- const gc = generationColumns(mapping);
1450
- const sc = seriesColumns(mapping);
1451
-
1452
- const row = (yield* readGeneration(
1453
- mapping,
1454
- input.moduleId,
1455
- active,
1456
- configuration.locking,
1457
- ))[0];
1458
-
1459
- const storedBinding =
1460
- row === undefined ? undefined : yield* mapping.generation.decodeBinding(row);
1461
-
1462
- if (storedBinding === undefined || !sameBinding(storedBinding, input.binding))
1463
- return prepared;
1464
-
1465
- yield* transaction
1466
- .update(mapping.generation.table)
1467
- .set(updateValues([[mapping.generation.state, "cancelled"]]))
1468
- .where(and(eq(gc.moduleId, input.moduleId), eq(gc.proofId, active)));
1469
- yield* transaction
1470
- .update(mapping.series.table)
1471
- .set(updateValues([[mapping.series.activeProofId, null]]))
1472
- .where(
1473
- and(
1474
- eq(sc.moduleId, input.moduleId),
1475
- eq(sc.purpose, input.purpose),
1476
- eq(sc.scopeKey, keys.series),
1477
- eq(sc.activeProofId, active),
1478
- ),
1479
- );
1480
- }
1481
-
1482
- return prepared;
1483
- }),
1484
- ).pipe(
1485
- Effect.provideService(CurrentProofSql, database),
1486
- Effect.provideService(LifecycleHooks, hooks),
1487
- translateFailure,
1488
- ),
1489
- cleanup: (input, prepare) =>
1490
- owned(
1491
- database,
1492
- mapping,
1493
- configuration,
1494
- Effect.gen(function* () {
1495
- const transaction = yield* CurrentProofSql;
1496
- const journal = yield* CurrentCommitJournal;
1497
-
1498
- const now = yield* nowMillis;
1499
- const nativeNow = mapping.encodeInstant(now);
1500
- const gc = generationColumns(mapping);
1501
- const cc = continuationColumns(mapping);
1502
- const rc = requestColumns(mapping);
1503
- const ac = abuseColumns(mapping);
1504
- const fc = failureColumns(mapping);
1505
- const mc = commandColumns(mapping);
1506
- const sc = seriesColumns(mapping);
1507
- const rsc = scopeColumns(mapping);
1508
- let remaining = input.limit;
1509
- let hasMore = false;
1510
-
1511
- const take = <A>(query: ProofSqlQuery<ReadonlyArray<A>>) =>
1512
- selectRows(query.limit(remaining + 1), configuration.locking).pipe(
1513
- Effect.map((rows) => {
1514
- if (rows.length > remaining) hasMore = true;
1515
- const selected = rows.slice(0, remaining);
1516
-
1517
- remaining -= selected.length;
1518
-
1519
- return selected;
1520
- }),
1521
- );
1522
-
1523
- // Child rows and secret-bearing generations are removed before their
1524
- // retained request/decision records. Every selected row counts toward
1525
- // one caller-wide limit and is locked until this owner commits.
1526
- const continuations = yield* take(
1527
- transaction
1528
- .select({ continuationId: cc.continuationId })
1529
- .from(mapping.continuation.table)
1530
- .where(and(eq(cc.moduleId, input.moduleId), lte(cc.retentionUntil, nativeNow)))
1531
- .orderBy(cc.retentionUntil),
1532
- );
1533
-
1534
- const generations = yield* take(
1535
- transaction
1536
- .select({ proofId: gc.proofId })
1537
- .from(mapping.generation.table)
1538
- .where(and(eq(gc.moduleId, input.moduleId), lte(gc.retentionUntil, nativeNow)))
1539
- .orderBy(gc.retentionUntil),
1540
- );
1541
-
1542
- const requests = yield* take(
1543
- transaction
1544
- .select({ requestId: rc.requestId })
1545
- .from(mapping.request.table)
1546
- .where(and(eq(rc.moduleId, input.moduleId), lte(rc.retentionUntil, nativeNow)))
1547
- .orderBy(rc.retentionUntil),
1548
- );
1549
-
1550
- const abuse = yield* take(
1551
- transaction
1552
- .select({
1553
- action: ac.action,
1554
- scopeKind: ac.scopeKind,
1555
- scopeKey: ac.scopeKey,
1556
- commandId: ac.commandId,
1557
- })
1558
- .from(mapping.abuseEvent.table)
1559
- .where(and(eq(ac.moduleId, input.moduleId), lte(ac.retentionUntil, nativeNow)))
1560
- .orderBy(ac.retentionUntil),
1561
- );
1562
-
1563
- const failures = yield* take(
1564
- transaction
1565
- .select({ seriesKey: fc.seriesKey, commandId: fc.commandId })
1566
- .from(mapping.failureEvent.table)
1567
- .where(and(eq(fc.moduleId, input.moduleId), lte(fc.retentionUntil, nativeNow)))
1568
- .orderBy(fc.retentionUntil),
1569
- );
1570
-
1571
- const commands = yield* take(
1572
- transaction
1573
- .select({ commandId: mc.commandId })
1574
- .from(mapping.command.table)
1575
- .where(and(eq(mc.moduleId, input.moduleId), lte(mc.retentionUntil, nativeNow)))
1576
- .orderBy(mc.retentionUntil),
1577
- );
1578
-
1579
- const series = yield* take(
1580
- transaction
1581
- .select({ purpose: sc.purpose, scopeKey: sc.scopeKey })
1582
- .from(mapping.series.table)
1583
- .where(
1584
- and(
1585
- eq(sc.moduleId, input.moduleId),
1586
- isNull(sc.activeProofId),
1587
- notExists(
1588
- transaction
1589
- .select({ one: sql`1` })
1590
- .from(mapping.generation.table)
1591
- .where(
1592
- and(
1593
- eq(gc.moduleId, sc.moduleId),
1594
- eq(gc.purpose, sc.purpose),
1595
- eq(gc.seriesKey, sc.scopeKey),
1596
- ),
1597
- ),
1598
- ),
1599
- notExists(
1600
- transaction
1601
- .select({ one: sql`1` })
1602
- .from(mapping.failureEvent.table)
1603
- .where(
1604
- and(
1605
- eq(fc.moduleId, sc.moduleId),
1606
- eq(fc.purpose, sc.purpose),
1607
- eq(fc.seriesKey, sc.scopeKey),
1608
- ),
1609
- ),
1610
- ),
1611
- ),
1612
- ),
1613
- );
1614
-
1615
- const rateScopes = yield* take(
1616
- transaction
1617
- .select({
1618
- purpose: rsc.purpose,
1619
- action: rsc.action,
1620
- scopeKind: rsc.scopeKind,
1621
- scopeKey: rsc.scopeKey,
1622
- })
1623
- .from(mapping.rateScope.table)
1624
- .where(
1625
- and(
1626
- eq(rsc.moduleId, input.moduleId),
1627
- notExists(
1628
- transaction
1629
- .select({ one: sql`1` })
1630
- .from(mapping.abuseEvent.table)
1631
- .where(
1632
- and(
1633
- eq(ac.moduleId, rsc.moduleId),
1634
- eq(ac.purpose, rsc.purpose),
1635
- eq(ac.action, rsc.action),
1636
- eq(ac.scopeKind, rsc.scopeKind),
1637
- eq(ac.scopeKey, rsc.scopeKey),
1638
- ),
1639
- ),
1640
- ),
1641
- ),
1642
- ),
1643
- );
1644
-
1645
- // Removing the final history row can make an anchor eligible only after this
1646
- // transaction/batch commits. One extra page lets the caller reclaim it.
1647
- hasMore ||= generations.length > 0 || failures.length > 0 || abuse.length > 0;
1648
- const removed = input.limit - remaining;
1649
- const prepared = prepare({ removed, hasMore } satisfies ProofCleanupResult, journal);
1650
-
1651
- if (continuations.length > 0)
1652
- yield* transaction.delete(mapping.continuation.table).where(
1653
- and(
1654
- eq(cc.moduleId, input.moduleId),
1655
- inArray(
1656
- cc.continuationId,
1657
- continuations.map((row: any) => row.continuationId),
1658
- ),
1659
- lte(cc.retentionUntil, nativeNow),
1660
- ),
1661
- );
1662
- if (generations.length > 0)
1663
- yield* transaction
1664
- .update(mapping.series.table)
1665
- .set(updateValues([[mapping.series.activeProofId, null]]))
1666
- .where(
1667
- and(
1668
- eq(sc.moduleId, input.moduleId),
1669
- inArray(
1670
- sc.activeProofId,
1671
- generations.map((row: any) => row.proofId),
1672
- ),
1673
- ),
1674
- );
1675
- if (generations.length > 0)
1676
- yield* transaction.delete(mapping.generation.table).where(
1677
- and(
1678
- eq(gc.moduleId, input.moduleId),
1679
- inArray(
1680
- gc.proofId,
1681
- generations.map((row: any) => row.proofId),
1682
- ),
1683
- lte(gc.retentionUntil, nativeNow),
1684
- ),
1685
- );
1686
- if (requests.length > 0)
1687
- yield* transaction.delete(mapping.request.table).where(
1688
- and(
1689
- eq(rc.moduleId, input.moduleId),
1690
- inArray(
1691
- rc.requestId,
1692
- requests.map((row: any) => row.requestId),
1693
- ),
1694
- lte(rc.retentionUntil, nativeNow),
1695
- ),
1696
- );
1697
- for (const row of abuse)
1698
- yield* transaction
1699
- .delete(mapping.abuseEvent.table)
1700
- .where(
1701
- and(
1702
- eq(ac.moduleId, input.moduleId),
1703
- eq(ac.action, row.action),
1704
- eq(ac.scopeKind, row.scopeKind),
1705
- eq(ac.scopeKey, row.scopeKey),
1706
- eq(ac.commandId, row.commandId),
1707
- lte(ac.retentionUntil, nativeNow),
1708
- ),
1709
- );
1710
- for (const row of failures)
1711
- yield* transaction
1712
- .delete(mapping.failureEvent.table)
1713
- .where(
1714
- and(
1715
- eq(fc.moduleId, input.moduleId),
1716
- eq(fc.seriesKey, row.seriesKey),
1717
- eq(fc.commandId, row.commandId),
1718
- lte(fc.retentionUntil, nativeNow),
1719
- ),
1720
- );
1721
- if (commands.length > 0)
1722
- yield* transaction.delete(mapping.command.table).where(
1723
- and(
1724
- eq(mc.moduleId, input.moduleId),
1725
- inArray(
1726
- mc.commandId,
1727
- commands.map((row: any) => row.commandId),
1728
- ),
1729
- lte(mc.retentionUntil, nativeNow),
1730
- ),
1731
- );
1732
- for (const row of series)
1733
- yield* transaction.delete(mapping.series.table).where(
1734
- and(
1735
- eq(sc.moduleId, input.moduleId),
1736
- eq(sc.purpose, row.purpose),
1737
- eq(sc.scopeKey, row.scopeKey),
1738
- isNull(sc.activeProofId),
1739
- notExists(
1740
- transaction
1741
- .select({ one: sql`1` })
1742
- .from(mapping.generation.table)
1743
- .where(
1744
- and(
1745
- eq(gc.moduleId, sc.moduleId),
1746
- eq(gc.purpose, sc.purpose),
1747
- eq(gc.seriesKey, sc.scopeKey),
1748
- ),
1749
- ),
1750
- ),
1751
- ),
1752
- );
1753
- for (const row of rateScopes)
1754
- yield* transaction.delete(mapping.rateScope.table).where(
1755
- and(
1756
- eq(rsc.moduleId, input.moduleId),
1757
- eq(rsc.purpose, row.purpose),
1758
- eq(rsc.action, row.action),
1759
- eq(rsc.scopeKind, row.scopeKind),
1760
- eq(rsc.scopeKey, row.scopeKey),
1761
- notExists(
1762
- transaction
1763
- .select({ one: sql`1` })
1764
- .from(mapping.abuseEvent.table)
1765
- .where(
1766
- and(
1767
- eq(ac.moduleId, rsc.moduleId),
1768
- eq(ac.purpose, rsc.purpose),
1769
- eq(ac.action, rsc.action),
1770
- eq(ac.scopeKind, rsc.scopeKind),
1771
- eq(ac.scopeKey, rsc.scopeKey),
1772
- ),
1773
- ),
1774
- ),
1775
- ),
1776
- );
1777
-
1778
- return prepared;
1779
- }),
1780
- ).pipe(
1781
- Effect.provideService(CurrentProofSql, database),
1782
- Effect.provideService(LifecycleHooks, hooks),
1783
- translateFailure,
1784
- ),
1785
- });
1786
- });
1787
-
1788
- const inspectCompletionIn = Effect.fn("DrizzleProof.inspectCompletionIn")(function* (
1789
- mapping: Mapping,
1790
- configuration: ProofSqlConfiguration,
1791
- input: ProofCompletionPlan["input"],
1792
- ensure: boolean,
1793
- ) {
1794
- const database = yield* CurrentProofSql;
1795
-
1796
- const authorityCurrent = yield* lockAuthority(
1797
- mapping,
1798
- input.moduleId,
1799
- input.purpose,
1800
- input.binding,
1801
- configuration.locking,
1802
- );
1803
-
1804
- const keys = mapping.scopeKeys({
1805
- moduleId: input.moduleId,
1806
- purpose: input.purpose,
1807
- binding: input.binding,
1808
- });
1809
-
1810
- if (ensure)
1811
- yield* ensureSeries(mapping, configuration, input.moduleId, input.purpose, keys.series);
1812
- const c = continuationColumns(mapping);
1813
-
1814
- const rows = yield* selectRows(
1815
- database
1816
- .select()
1817
- .from(mapping.continuation.table)
1818
- .where(and(eq(c.moduleId, input.moduleId), eq(c.continuationId, input.continuationId)))
1819
- .limit(1),
1820
- configuration.locking,
1821
- );
1822
-
1823
- const row = rows[0];
1824
- const now = yield* nowMillis;
1825
- const record = row === undefined ? undefined : yield* mapping.continuation.decode(row);
1826
-
1827
- const completed =
1828
- authorityCurrent &&
1829
- row !== undefined &&
1830
- record !== undefined &&
1831
- record.moduleId === input.moduleId &&
1832
- record.continuationId === input.continuationId &&
1833
- record.purpose === input.purpose &&
1834
- record.digest === input.continuationDigest &&
1835
- record.seriesKey === keys.series &&
1836
- sameBinding(record.binding, input.binding) &&
1837
- row[mapping.continuation.consumed] === false &&
1838
- record.expiresAtMillis > now;
1839
-
1840
- return completed ? { record: record!, row, columns: c } : undefined;
1841
- });
1842
-
1843
- /** Nonconsuming same-owner preflight; it never inserts a series or changes expiry. */
1844
- const checkProofCompletionIn = Effect.fn("Drizzle.checkProofCompletionIn")(function* (
1845
- mapping: Mapping,
1846
- configuration: ProofSqlConfiguration,
1847
- input: ProofCompletionPlan["input"],
1848
- ) {
1849
- return yield* inspectCompletionIn(mapping, configuration, input, false).pipe(
1850
- Effect.map((value) => value !== undefined),
1851
- );
1852
- });
1853
-
1854
- const completeIn = Effect.fn("DrizzleProof.completeIn")(function* <A, E = never, R = never>(
1855
- mapping: Mapping,
1856
- configuration: ProofSqlConfiguration,
1857
- input: ProofCompletionPlan["input"],
1858
- prepare: (decision: ProofCompletionDecision) => A,
1859
- protectedMutation?: Effect.Effect<boolean, E, R>,
1860
- ) {
1861
- const database = yield* CurrentProofSql;
1862
-
1863
- const accepted = yield* inspectCompletionIn(mapping, configuration, input, true);
1864
-
1865
- if (accepted === undefined) return prepare("rejected");
1866
- const { record, row: original, columns: c } = accepted;
1867
-
1868
- if (protectedMutation !== undefined && !(yield* protectedMutation)) return yield* unavailable();
1869
- const value = prepare("completed");
1870
-
1871
- yield* database
1872
- .update(mapping.continuation.table)
1873
- .set(updateValues([[mapping.continuation.consumed, true]]))
1874
- .where(
1875
- and(
1876
- eq(c.moduleId, input.moduleId),
1877
- eq(c.continuationId, input.continuationId),
1878
- eq(c.digest, input.continuationDigest),
1879
- eq(c.consumed, false),
1880
- ),
1881
- );
1882
- yield* insertCommand(
1883
- mapping,
1884
- input.moduleId,
1885
- input.continuationDigest,
1886
- "complete",
1887
- "completed",
1888
- record.expiresAtMillis,
1889
- );
1890
-
1891
- const assertApplied = Effect.flatMap(CurrentPasswordPreparedTransaction, (currentTransaction) =>
1892
- Effect.gen(function* () {
1893
- const persisted = (yield* selectRows(
1894
- currentTransaction
1895
- .select()
1896
- .from(mapping.continuation.table)
1897
- .where(and(eq(c.moduleId, input.moduleId), eq(c.continuationId, input.continuationId)))
1898
- .limit(1),
1899
- false,
1900
- ))[0];
1901
-
1902
- const command = (yield* commandRow(
1903
- mapping,
1904
- input.moduleId,
1905
- input.continuationDigest,
1906
- false,
1907
- ))[0];
1908
-
1909
- const decoded =
1910
- persisted === undefined ? undefined : yield* mapping.continuation.decode(persisted);
1911
-
1912
- const immutable = [
1913
- mapping.continuation.moduleId,
1914
- mapping.continuation.purpose,
1915
- mapping.continuation.continuationId,
1916
- mapping.continuation.digest,
1917
- mapping.continuation.proofId,
1918
- mapping.continuation.seriesKey,
1919
- mapping.continuation.version,
1920
- ];
1921
-
1922
- if (
1923
- persisted === undefined ||
1924
- decoded === undefined ||
1925
- !sameBinding(decoded.binding, record.binding) ||
1926
- persisted[mapping.continuation.consumed] !== true ||
1927
- immutable.some((key) => persisted[key] !== original[key]) ||
1928
- (yield* mapping.decodeInstant(persisted[mapping.continuation.expiresAt])) !==
1929
- record.expiresAtMillis ||
1930
- (yield* mapping.decodeInstant(persisted[mapping.continuation.retentionUntil])) !==
1931
- (yield* mapping.decodeInstant(original[mapping.continuation.retentionUntil])) ||
1932
- command === undefined ||
1933
- command[mapping.command.kind] !== "complete" ||
1934
- command[mapping.command.decision] !== "completed" ||
1935
- (yield* mapping.decodeInstant(command[mapping.command.retentionUntil])) !==
1936
- record.expiresAtMillis
1937
- )
1938
- return yield* unavailable();
1939
-
1940
- if (record.expiresAtMillis <= (yield* nowMillis)) return yield* unavailable();
1941
- }).pipe(Effect.provideService(CurrentProofSql, currentTransaction)),
1942
- );
1943
-
1944
- yield* assertApplied.pipe(Effect.provideService(CurrentPasswordPreparedTransaction, database));
1945
- const postconditions = yield* Effect.serviceOption(PasswordPreparedPostconditions);
1946
-
1947
- if (
1948
- Option.isSome(postconditions) &&
1949
- !postconditions.value.register(assertApplied.pipe(translateFailure))
1950
- )
1951
- return yield* unavailable();
1952
-
1953
- return value;
1954
- });
1955
-
1956
- /** Private same-owner seam for password and identifier mutations. */
1957
- const completeProofPlanIn = Effect.fn("Drizzle.completeProofPlanIn")(function* <
1958
- Rq extends Table,
1959
- S extends Table,
1960
- G extends Table,
1961
- Cn extends Table,
1962
- Rs extends Table,
1963
- Aev extends Table,
1964
- F extends Table,
1965
- C extends Table,
1966
- Sub extends Table,
1967
- I extends Table,
1968
- Cr extends Table,
1969
- NativeId,
1970
- A,
1971
- E,
1972
- R,
1973
- >(
1974
- mapping: ProofPersistenceMapping<Rq, S, G, Cn, Rs, Aev, F, C, Sub, I, Cr, NativeId>,
1975
- configuration: ProofSqlConfiguration,
1976
- plan: ProofCompletionPlan,
1977
- protectedMutation: Effect.Effect<boolean, E, R>,
1978
- project: (decision: ProofCompletionDecision) => A,
1979
- ) {
1980
- const journal = yield* CurrentCommitJournal;
1981
-
1982
- return yield* completeIn(
1983
- mapping as unknown as Mapping,
1984
- configuration,
1985
- plan.input,
1986
- (decision) => plan.prepare(decision, journal, project),
1987
- protectedMutation,
1988
- );
1989
- });
1990
-
1991
- return { makeSqlProofPersistence, checkProofCompletionIn, completeProofPlanIn };
1992
- };