@yielded/auth-persistence-drizzle 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/D1.d.mts +963 -0
- package/dist/D1.mjs +29 -0
- package/dist/D1.mjs.map +1 -0
- package/dist/Libsql.d.mts +2134 -0
- package/dist/Libsql.mjs +77 -0
- package/dist/Libsql.mjs.map +1 -0
- package/dist/Mysql2.d.mts +1817 -0
- package/dist/Mysql2.mjs +55 -0
- package/dist/Mysql2.mjs.map +1 -0
- package/dist/Pglite.d.mts +1821 -0
- package/dist/Pglite.mjs +53 -0
- package/dist/Pglite.mjs.map +1 -0
- package/dist/Postgres.d.mts +1821 -0
- package/dist/Postgres.mjs +53 -0
- package/dist/Postgres.mjs.map +1 -0
- package/dist/SqliteBun.d.mts +2129 -0
- package/dist/SqliteBun.mjs +70 -0
- package/dist/SqliteBun.mjs.map +1 -0
- package/dist/SqliteDo.d.mts +2181 -0
- package/dist/SqliteDo.mjs +105 -0
- package/dist/SqliteDo.mjs.map +1 -0
- package/dist/SqliteNode.d.mts +2129 -0
- package/dist/SqliteNode.mjs +70 -0
- package/dist/SqliteNode.mjs.map +1 -0
- package/dist/SqliteWasm.d.mts +2132 -0
- package/dist/SqliteWasm.mjs +70 -0
- package/dist/SqliteWasm.mjs.map +1 -0
- package/dist/_virtual/_rolldown/runtime.mjs +13 -0
- package/dist/drizzle/D1BatchStatements.d.mts +10 -0
- package/dist/drizzle/D1BatchStatements.mjs +8 -0
- package/dist/drizzle/D1BatchStatements.mjs.map +1 -0
- package/dist/drizzle/SuppliedService.d.mts +9 -0
- package/dist/drizzle/d1-emails.d.mts +61 -0
- package/dist/drizzle/d1-emails.mjs +578 -0
- package/dist/drizzle/d1-emails.mjs.map +1 -0
- package/dist/drizzle/d1-generated-statement.mjs +79 -0
- package/dist/drizzle/d1-generated-statement.mjs.map +1 -0
- package/dist/drizzle/d1-identity.d.mts +30 -0
- package/dist/drizzle/d1-identity.mjs +118 -0
- package/dist/drizzle/d1-identity.mjs.map +1 -0
- package/dist/drizzle/d1-oauth.d.mts +300 -0
- package/dist/drizzle/d1-oauth.mjs +76 -0
- package/dist/drizzle/d1-oauth.mjs.map +1 -0
- package/dist/drizzle/d1-passkey.d.mts +47 -0
- package/dist/drizzle/d1-passkey.mjs +95 -0
- package/dist/drizzle/d1-passkey.mjs.map +1 -0
- package/dist/drizzle/d1-password-prepared.d.mts +24 -0
- package/dist/drizzle/d1-password-prepared.mjs +460 -0
- package/dist/drizzle/d1-password-prepared.mjs.map +1 -0
- package/dist/drizzle/d1-passwords.d.mts +86 -0
- package/dist/drizzle/d1-passwords.mjs +1003 -0
- package/dist/drizzle/d1-passwords.mjs.map +1 -0
- package/dist/drizzle/d1-phone.d.mts +23 -0
- package/dist/drizzle/d1-phone.mjs +30 -0
- package/dist/drizzle/d1-phone.mjs.map +1 -0
- package/dist/drizzle/d1-planning.d.mts +11 -0
- package/dist/drizzle/d1-planning.mjs +43 -0
- package/dist/drizzle/d1-planning.mjs.map +1 -0
- package/dist/drizzle/d1-proofs.d.mts +79 -0
- package/dist/drizzle/d1-proofs.mjs +829 -0
- package/dist/drizzle/d1-proofs.mjs.map +1 -0
- package/dist/drizzle/d1-sessions.d.mts +66 -0
- package/dist/drizzle/d1-sessions.mjs +965 -0
- package/dist/drizzle/d1-sessions.mjs.map +1 -0
- package/dist/drizzle/d1-totp.d.mts +23 -0
- package/dist/drizzle/d1-totp.mjs +27 -0
- package/dist/drizzle/d1-totp.mjs.map +1 -0
- package/dist/drizzle/email-model.d.mts +30 -0
- package/dist/drizzle/email-model.mjs +2 -0
- package/dist/drizzle/email-registration.d.mts +29 -0
- package/dist/drizzle/email-registration.mjs +236 -0
- package/dist/drizzle/email-registration.mjs.map +1 -0
- package/dist/drizzle/email-sql.d.mts +1 -0
- package/dist/drizzle/email-sql.mjs +9 -0
- package/dist/drizzle/email-sql.mjs.map +1 -0
- package/dist/drizzle/email-target.d.mts +19 -0
- package/dist/drizzle/email-target.mjs +72 -0
- package/dist/drizzle/email-target.mjs.map +1 -0
- package/dist/drizzle/model.d.mts +245 -0
- package/dist/drizzle/model.mjs +55 -0
- package/dist/drizzle/model.mjs.map +1 -0
- package/dist/drizzle/mysql-emails.d.mts +70 -0
- package/dist/drizzle/mysql-emails.mjs +38 -0
- package/dist/drizzle/mysql-emails.mjs.map +1 -0
- package/dist/drizzle/mysql-identity.d.mts +21 -0
- package/dist/drizzle/mysql-identity.mjs +93 -0
- package/dist/drizzle/mysql-identity.mjs.map +1 -0
- package/dist/drizzle/mysql-password-prepared.d.mts +29 -0
- package/dist/drizzle/mysql-password-prepared.mjs +16 -0
- package/dist/drizzle/mysql-password-prepared.mjs.map +1 -0
- package/dist/drizzle/mysql-passwords.d.mts +85 -0
- package/dist/drizzle/mysql-passwords.mjs +38 -0
- package/dist/drizzle/mysql-passwords.mjs.map +1 -0
- package/dist/drizzle/mysql-proofs.d.mts +74 -0
- package/dist/drizzle/mysql-proofs.mjs +23 -0
- package/dist/drizzle/mysql-proofs.mjs.map +1 -0
- package/dist/drizzle/mysql-sessions.d.mts +91 -0
- package/dist/drizzle/mysql-sessions.mjs +53 -0
- package/dist/drizzle/mysql-sessions.mjs.map +1 -0
- package/dist/drizzle/mysql.d.mts +69 -0
- package/dist/drizzle/mysql.mjs +218 -0
- package/dist/drizzle/mysql.mjs.map +1 -0
- package/dist/drizzle/oauth-accounts.mjs +358 -0
- package/dist/drizzle/oauth-accounts.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-access.mjs +210 -0
- package/dist/drizzle/oauth-connected-access.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-collection.mjs +202 -0
- package/dist/drizzle/oauth-connected-collection.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-custody.mjs +146 -0
- package/dist/drizzle/oauth-connected-custody.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-drivers.mjs +76 -0
- package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-flow.mjs +247 -0
- package/dist/drizzle/oauth-connected-flow.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-input.mjs +103 -0
- package/dist/drizzle/oauth-connected-input.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-maintenance.mjs +214 -0
- package/dist/drizzle/oauth-connected-maintenance.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-management.mjs +228 -0
- package/dist/drizzle/oauth-connected-management.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-model.d.mts +277 -0
- package/dist/drizzle/oauth-connected-model.mjs +22 -0
- package/dist/drizzle/oauth-connected-model.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-reference.d.mts +16 -0
- package/dist/drizzle/oauth-connected-reference.mjs +53 -0
- package/dist/drizzle/oauth-connected-reference.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-settlement.mjs +117 -0
- package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-state.d.mts +1954 -0
- package/dist/drizzle/oauth-connected-state.mjs +422 -0
- package/dist/drizzle/oauth-connected-state.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-target.d.mts +752 -0
- package/dist/drizzle/oauth-connected-target.mjs +91 -0
- package/dist/drizzle/oauth-connected-target.mjs.map +1 -0
- package/dist/drizzle/oauth-drivers.mjs +51 -0
- package/dist/drizzle/oauth-drivers.mjs.map +1 -0
- package/dist/drizzle/oauth-flow.d.mts +22 -0
- package/dist/drizzle/oauth-flow.mjs +253 -0
- package/dist/drizzle/oauth-flow.mjs.map +1 -0
- package/dist/drizzle/oauth-input.mjs +127 -0
- package/dist/drizzle/oauth-input.mjs.map +1 -0
- package/dist/drizzle/oauth-model.d.mts +461 -0
- package/dist/drizzle/oauth-model.mjs +49 -0
- package/dist/drizzle/oauth-model.mjs.map +1 -0
- package/dist/drizzle/oauth-mysql.mjs +8 -0
- package/dist/drizzle/oauth-mysql.mjs.map +1 -0
- package/dist/drizzle/oauth-owner.d.mts +10 -0
- package/dist/drizzle/oauth-owner.mjs +10 -0
- package/dist/drizzle/oauth-owner.mjs.map +1 -0
- package/dist/drizzle/oauth-registration.d.mts +5 -0
- package/dist/drizzle/oauth-registration.mjs +374 -0
- package/dist/drizzle/oauth-registration.mjs.map +1 -0
- package/dist/drizzle/oauth-state.mjs +107 -0
- package/dist/drizzle/oauth-state.mjs.map +1 -0
- package/dist/drizzle/oauth-target.d.mts +109 -0
- package/dist/drizzle/oauth-target.mjs +246 -0
- package/dist/drizzle/oauth-target.mjs.map +1 -0
- package/dist/drizzle/passkey-drivers.mjs +34 -0
- package/dist/drizzle/passkey-drivers.mjs.map +1 -0
- package/dist/drizzle/passkey-kernel.mjs +8 -0
- package/dist/drizzle/passkey-kernel.mjs.map +1 -0
- package/dist/drizzle/passkey-model.d.mts +43 -0
- package/dist/drizzle/passkey-model.mjs +8 -0
- package/dist/drizzle/passkey-model.mjs.map +1 -0
- package/dist/drizzle/passkey-registration-ceremony-model.d.mts +12 -0
- package/dist/drizzle/passkey-registration-ceremony-model.mjs +2 -0
- package/dist/drizzle/passkey-state.mjs +7 -0
- package/dist/drizzle/passkey-state.mjs.map +1 -0
- package/dist/drizzle/passkey-target.d.mts +2 -0
- package/dist/drizzle/passkey-target.mjs +7 -0
- package/dist/drizzle/passkey-target.mjs.map +1 -0
- package/dist/drizzle/passkey-write-drivers.mjs +32 -0
- package/dist/drizzle/passkey-write-drivers.mjs.map +1 -0
- package/dist/drizzle/passkey-write-model.d.mts +20 -0
- package/dist/drizzle/passkey-write-model.mjs +9 -0
- package/dist/drizzle/passkey-write-model.mjs.map +1 -0
- package/dist/drizzle/passkey-write-target.d.mts +5 -0
- package/dist/drizzle/passkey-write-target.mjs +7 -0
- package/dist/drizzle/passkey-write-target.mjs.map +1 -0
- package/dist/drizzle/password-model.d.mts +24 -0
- package/dist/drizzle/password-model.mjs +2 -0
- package/dist/drizzle/password-prepared-model.d.mts +92 -0
- package/dist/drizzle/password-prepared-model.mjs +11 -0
- package/dist/drizzle/password-prepared-model.mjs.map +1 -0
- package/dist/drizzle/password-prepared-sql.mjs +389 -0
- package/dist/drizzle/password-prepared-sql.mjs.map +1 -0
- package/dist/drizzle/password-prepared-state.mjs +104 -0
- package/dist/drizzle/password-prepared-state.mjs.map +1 -0
- package/dist/drizzle/password-prepared-target.d.mts +11 -0
- package/dist/drizzle/password-prepared-target.mjs +56 -0
- package/dist/drizzle/password-prepared-target.mjs.map +1 -0
- package/dist/drizzle/password-registration.d.mts +7 -0
- package/dist/drizzle/password-registration.mjs +134 -0
- package/dist/drizzle/password-registration.mjs.map +1 -0
- package/dist/drizzle/password-sql.d.mts +1 -0
- package/dist/drizzle/password-sql.mjs +9 -0
- package/dist/drizzle/password-sql.mjs.map +1 -0
- package/dist/drizzle/password-target.d.mts +16 -0
- package/dist/drizzle/password-target.mjs +61 -0
- package/dist/drizzle/password-target.mjs.map +1 -0
- package/dist/drizzle/pg-emails.d.mts +71 -0
- package/dist/drizzle/pg-emails.mjs +38 -0
- package/dist/drizzle/pg-emails.mjs.map +1 -0
- package/dist/drizzle/pg-password-prepared.d.mts +30 -0
- package/dist/drizzle/pg-password-prepared.mjs +16 -0
- package/dist/drizzle/pg-password-prepared.mjs.map +1 -0
- package/dist/drizzle/pg-passwords.d.mts +86 -0
- package/dist/drizzle/pg-passwords.mjs +38 -0
- package/dist/drizzle/pg-passwords.mjs.map +1 -0
- package/dist/drizzle/pg-proofs.d.mts +75 -0
- package/dist/drizzle/pg-proofs.mjs +22 -0
- package/dist/drizzle/pg-proofs.mjs.map +1 -0
- package/dist/drizzle/pg-sessions.d.mts +92 -0
- package/dist/drizzle/pg-sessions.mjs +53 -0
- package/dist/drizzle/pg-sessions.mjs.map +1 -0
- package/dist/drizzle/pg.d.mts +80 -0
- package/dist/drizzle/pg.mjs +289 -0
- package/dist/drizzle/pg.mjs.map +1 -0
- package/dist/drizzle/phone-model.d.mts +113 -0
- package/dist/drizzle/phone-model.mjs +39 -0
- package/dist/drizzle/phone-model.mjs.map +1 -0
- package/dist/drizzle/phone-state.mjs +14 -0
- package/dist/drizzle/phone-state.mjs.map +1 -0
- package/dist/drizzle/phone-target.d.mts +14 -0
- package/dist/drizzle/phone-target.mjs +168 -0
- package/dist/drizzle/phone-target.mjs.map +1 -0
- package/dist/drizzle/proof-model.d.mts +21 -0
- package/dist/drizzle/proof-model.mjs +2 -0
- package/dist/drizzle/proof-sql.d.mts +1 -0
- package/dist/drizzle/proof-sql.mjs +8 -0
- package/dist/drizzle/proof-sql.mjs.map +1 -0
- package/dist/drizzle/proof-target.d.mts +11 -0
- package/dist/drizzle/proof-target.mjs +36 -0
- package/dist/drizzle/proof-target.mjs.map +1 -0
- package/dist/drizzle/query-operations.mjs +27 -0
- package/dist/drizzle/query-operations.mjs.map +1 -0
- package/dist/drizzle/session-model.d.mts +31 -0
- package/dist/drizzle/session-model.mjs +2 -0
- package/dist/drizzle/session-sql.mjs +8 -0
- package/dist/drizzle/session-sql.mjs.map +1 -0
- package/dist/drizzle/session-target.d.mts +27 -0
- package/dist/drizzle/session-target.mjs +46 -0
- package/dist/drizzle/session-target.mjs.map +1 -0
- package/dist/drizzle/sqlite-emails.mjs +45 -0
- package/dist/drizzle/sqlite-emails.mjs.map +1 -0
- package/dist/drizzle/sqlite-identity.mjs +90 -0
- package/dist/drizzle/sqlite-identity.mjs.map +1 -0
- package/dist/drizzle/sqlite-password-prepared.mjs +21 -0
- package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -0
- package/dist/drizzle/sqlite-passwords.mjs +49 -0
- package/dist/drizzle/sqlite-passwords.mjs.map +1 -0
- package/dist/drizzle/sqlite-proofs.mjs +29 -0
- package/dist/drizzle/sqlite-proofs.mjs.map +1 -0
- package/dist/drizzle/sqlite-sessions.mjs +74 -0
- package/dist/drizzle/sqlite-sessions.mjs.map +1 -0
- package/dist/drizzle/sqlite.d.mts +77 -0
- package/dist/drizzle/sqlite.mjs +217 -0
- package/dist/drizzle/sqlite.mjs.map +1 -0
- package/dist/drizzle/standalone-guard.mjs +17 -0
- package/dist/drizzle/standalone-guard.mjs.map +1 -0
- package/dist/drizzle/step-up-model.d.mts +16 -0
- package/dist/drizzle/step-up-model.mjs +2 -0
- package/dist/drizzle/table-model.d.mts +11 -0
- package/dist/drizzle/totp-model.d.mts +82 -0
- package/dist/drizzle/totp-model.mjs +13 -0
- package/dist/drizzle/totp-model.mjs.map +1 -0
- package/dist/drizzle/totp-state.d.mts +37 -0
- package/dist/drizzle/totp-state.mjs +287 -0
- package/dist/drizzle/totp-state.mjs.map +1 -0
- package/dist/drizzle/totp-target.d.mts +14 -0
- package/dist/drizzle/totp-target.mjs +81 -0
- package/dist/drizzle/totp-target.mjs.map +1 -0
- package/dist/drizzle/transaction-execution.d.mts +2 -0
- package/dist/drizzle/transaction-execution.mjs +11 -0
- package/dist/drizzle/transaction-execution.mjs.map +1 -0
- package/dist/drizzle/transaction-mysql.mjs +47 -0
- package/dist/drizzle/transaction-mysql.mjs.map +1 -0
- package/dist/drizzle/transaction-owner.d.mts +2 -0
- package/dist/drizzle/transaction-owner.mjs +8 -0
- package/dist/drizzle/transaction-owner.mjs.map +1 -0
- package/dist/index.d.mts +27 -0
- package/dist/index.mjs +27 -0
- package/dist/internal/drizzle-migrations.mjs +19 -0
- package/dist/internal/drizzle-migrations.mjs.map +1 -0
- package/dist/internal/drizzle-postgres.mjs +37 -0
- package/dist/internal/drizzle-postgres.mjs.map +1 -0
- package/dist/internal/drizzle-sqlite.mjs +35 -0
- package/dist/internal/drizzle-sqlite.mjs.map +1 -0
- package/package.json +1 -0
- package/src/D1.ts +136 -0
- package/src/Libsql.ts +257 -0
- package/src/Mysql2.ts +184 -0
- package/src/Pglite.ts +174 -0
- package/src/Postgres.ts +174 -0
- package/src/SqliteBun.ts +258 -0
- package/src/SqliteDo.ts +473 -0
- package/src/SqliteNode.ts +259 -0
- package/src/SqliteWasm.ts +263 -0
- package/src/drizzle/D1BatchStatements.ts +10 -0
- package/src/drizzle/SuppliedService.ts +10 -0
- package/src/drizzle/d1-emails.ts +1829 -0
- package/src/drizzle/d1-generated-statement.ts +129 -0
- package/src/drizzle/d1-identity.ts +375 -0
- package/src/drizzle/d1-oauth.ts +340 -0
- package/src/drizzle/d1-passkey.ts +373 -0
- package/src/drizzle/d1-password-prepared.ts +1270 -0
- package/src/drizzle/d1-passwords.ts +2656 -0
- package/src/drizzle/d1-phone.ts +96 -0
- package/src/drizzle/d1-planning.ts +104 -0
- package/src/drizzle/d1-proofs.ts +2305 -0
- package/src/drizzle/d1-sessions.ts +2857 -0
- package/src/drizzle/d1-totp.ts +78 -0
- package/src/drizzle/email-model.ts +202 -0
- package/src/drizzle/email-registration.ts +698 -0
- package/src/drizzle/email-sql.ts +25 -0
- package/src/drizzle/email-target.ts +243 -0
- package/src/drizzle/model.ts +459 -0
- package/src/drizzle/mysql-emails.ts +321 -0
- package/src/drizzle/mysql-identity.ts +324 -0
- package/src/drizzle/mysql-password-prepared.ts +204 -0
- package/src/drizzle/mysql-passwords.ts +339 -0
- package/src/drizzle/mysql-proofs.ts +181 -0
- package/src/drizzle/mysql-sessions.ts +741 -0
- package/src/drizzle/mysql.ts +687 -0
- package/src/drizzle/oauth-accounts.ts +804 -0
- package/src/drizzle/oauth-connected-access.ts +354 -0
- package/src/drizzle/oauth-connected-collection.ts +324 -0
- package/src/drizzle/oauth-connected-custody.ts +277 -0
- package/src/drizzle/oauth-connected-drivers.ts +465 -0
- package/src/drizzle/oauth-connected-flow.ts +441 -0
- package/src/drizzle/oauth-connected-input.ts +127 -0
- package/src/drizzle/oauth-connected-maintenance.ts +345 -0
- package/src/drizzle/oauth-connected-management.ts +365 -0
- package/src/drizzle/oauth-connected-model.ts +347 -0
- package/src/drizzle/oauth-connected-reference.ts +112 -0
- package/src/drizzle/oauth-connected-settlement.ts +226 -0
- package/src/drizzle/oauth-connected-state.ts +845 -0
- package/src/drizzle/oauth-connected-target.ts +264 -0
- package/src/drizzle/oauth-drivers.ts +569 -0
- package/src/drizzle/oauth-flow.ts +462 -0
- package/src/drizzle/oauth-input.ts +201 -0
- package/src/drizzle/oauth-model.ts +617 -0
- package/src/drizzle/oauth-mysql.ts +10 -0
- package/src/drizzle/oauth-owner.ts +29 -0
- package/src/drizzle/oauth-registration.ts +640 -0
- package/src/drizzle/oauth-state.ts +215 -0
- package/src/drizzle/oauth-target.ts +750 -0
- package/src/drizzle/passkey-drivers.ts +385 -0
- package/src/drizzle/passkey-kernel.ts +4 -0
- package/src/drizzle/passkey-model.ts +153 -0
- package/src/drizzle/passkey-registration-ceremony-model.ts +32 -0
- package/src/drizzle/passkey-state.ts +3 -0
- package/src/drizzle/passkey-target.ts +23 -0
- package/src/drizzle/passkey-write-drivers.ts +395 -0
- package/src/drizzle/passkey-write-model.ts +103 -0
- package/src/drizzle/passkey-write-target.ts +9 -0
- package/src/drizzle/password-model.ts +169 -0
- package/src/drizzle/password-prepared-model.ts +259 -0
- package/src/drizzle/password-prepared-sql.ts +1191 -0
- package/src/drizzle/password-prepared-state.ts +231 -0
- package/src/drizzle/password-prepared-target.ts +160 -0
- package/src/drizzle/password-registration.ts +363 -0
- package/src/drizzle/password-sql.ts +13 -0
- package/src/drizzle/password-target.ts +224 -0
- package/src/drizzle/pg-emails.ts +321 -0
- package/src/drizzle/pg-password-prepared.ts +205 -0
- package/src/drizzle/pg-passwords.ts +338 -0
- package/src/drizzle/pg-proofs.ts +191 -0
- package/src/drizzle/pg-sessions.ts +750 -0
- package/src/drizzle/pg.ts +984 -0
- package/src/drizzle/phone-model.ts +190 -0
- package/src/drizzle/phone-state.ts +21 -0
- package/src/drizzle/phone-target.ts +472 -0
- package/src/drizzle/proof-model.ts +139 -0
- package/src/drizzle/proof-sql.ts +10 -0
- package/src/drizzle/proof-target.ts +122 -0
- package/src/drizzle/query-operations.ts +43 -0
- package/src/drizzle/session-model.ts +215 -0
- package/src/drizzle/session-sql.ts +14 -0
- package/src/drizzle/session-target.ts +338 -0
- package/src/drizzle/sqlite-emails.ts +366 -0
- package/src/drizzle/sqlite-identity.ts +344 -0
- package/src/drizzle/sqlite-password-prepared.ts +260 -0
- package/src/drizzle/sqlite-passwords.ts +497 -0
- package/src/drizzle/sqlite-proofs.ts +202 -0
- package/src/drizzle/sqlite-sessions.ts +971 -0
- package/src/drizzle/sqlite.ts +705 -0
- package/src/drizzle/standalone-guard.ts +32 -0
- package/src/drizzle/step-up-model.ts +73 -0
- package/src/drizzle/table-model.ts +9 -0
- package/src/drizzle/totp-model.ts +92 -0
- package/src/drizzle/totp-state.ts +525 -0
- package/src/drizzle/totp-target.ts +308 -0
- package/src/drizzle/transaction-execution.ts +13 -0
- package/src/drizzle/transaction-mysql.ts +106 -0
- package/src/drizzle/transaction-owner.ts +11 -0
- package/src/index.ts +378 -0
- package/src/internal/drizzle-migrations.ts +29 -0
- package/src/internal/drizzle-postgres.ts +83 -0
- package/src/internal/drizzle-sqlite.ts +81 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { cryptoLayer, hooksLayer } from "@yielded/auth/Persistence";
|
|
2
|
+
import {
|
|
3
|
+
type PhoneAdmissionPolicy,
|
|
4
|
+
type PhoneLifecyclePolicy,
|
|
5
|
+
type PhoneNumber,
|
|
6
|
+
PhoneAdmission,
|
|
7
|
+
PhonePersistence,
|
|
8
|
+
PhoneSignInTargets,
|
|
9
|
+
} from "@yielded/auth/PhoneOtp";
|
|
10
|
+
import type { SubjectId } from "@yielded/auth/Schema";
|
|
11
|
+
import type { AuthenticationRequirement } from "@yielded/auth/Sessions";
|
|
12
|
+
import type { InferInsertModel, InferSelectModel, SQL, Table } from "drizzle-orm";
|
|
13
|
+
import { Effect, Layer } from "effect";
|
|
14
|
+
|
|
15
|
+
import type { PersistenceMappingError } from "./model";
|
|
16
|
+
import type { AnyProofPersistenceMapping, ProofPersistenceMapping } from "./proof-model";
|
|
17
|
+
const proofMapping = Symbol("effect-auth/phone/proofs");
|
|
18
|
+
|
|
19
|
+
/** Opaque same-owner proof mapping. The builder preserves the consumer's table codecs. */
|
|
20
|
+
export interface PhoneProofCompletionMapping {
|
|
21
|
+
readonly [proofMapping]: AnyProofPersistenceMapping;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const phoneProofCompletionMapping = <
|
|
25
|
+
Rq extends Table,
|
|
26
|
+
S extends Table,
|
|
27
|
+
G extends Table,
|
|
28
|
+
Cn extends Table,
|
|
29
|
+
Rs extends Table,
|
|
30
|
+
A extends Table,
|
|
31
|
+
F extends Table,
|
|
32
|
+
C extends Table,
|
|
33
|
+
Sub extends Table,
|
|
34
|
+
I extends Table,
|
|
35
|
+
Cr extends Table,
|
|
36
|
+
N,
|
|
37
|
+
>(
|
|
38
|
+
mapping: ProofPersistenceMapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, N>,
|
|
39
|
+
): PhoneProofCompletionMapping =>
|
|
40
|
+
Object.freeze({
|
|
41
|
+
[proofMapping]: Object.freeze({
|
|
42
|
+
...mapping,
|
|
43
|
+
request: Object.freeze({ ...mapping.request }),
|
|
44
|
+
series: Object.freeze({ ...mapping.series }),
|
|
45
|
+
generation: Object.freeze({ ...mapping.generation }),
|
|
46
|
+
continuation: Object.freeze({ ...mapping.continuation }),
|
|
47
|
+
rateScope: Object.freeze({ ...mapping.rateScope }),
|
|
48
|
+
abuseEvent: Object.freeze({ ...mapping.abuseEvent }),
|
|
49
|
+
failureEvent: Object.freeze({ ...mapping.failureEvent }),
|
|
50
|
+
command: Object.freeze({ ...mapping.command }),
|
|
51
|
+
constraints: Object.freeze({ ...mapping.constraints }),
|
|
52
|
+
authority: Object.freeze({
|
|
53
|
+
...mapping.authority,
|
|
54
|
+
identifier: Object.freeze({ ...mapping.authority.identifier }),
|
|
55
|
+
...(mapping.authority.subject === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: { subject: Object.freeze({ ...mapping.authority.subject }) }),
|
|
58
|
+
...(mapping.authority.credential === undefined
|
|
59
|
+
? {}
|
|
60
|
+
: { credential: Object.freeze({ ...mapping.authority.credential }) }),
|
|
61
|
+
...(mapping.authority.subjectId === undefined
|
|
62
|
+
? {}
|
|
63
|
+
: { subjectId: Object.freeze({ ...mapping.authority.subjectId }) }),
|
|
64
|
+
}),
|
|
65
|
+
...(mapping.d1 === undefined ? {} : { d1: Object.freeze({ ...mapping.d1 }) }),
|
|
66
|
+
}) as unknown as AnyProofPersistenceMapping,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
/** @internal */
|
|
70
|
+
export const phoneProofs = (mapping: PhoneProofCompletionMapping) => mapping[proofMapping];
|
|
71
|
+
export type PhoneColumn<T extends Table> = Extract<keyof T["_"]["columns"], string>;
|
|
72
|
+
export type PhoneMappingSource<M, R = never> = M | Effect.Effect<M, PersistenceMappingError, R>;
|
|
73
|
+
|
|
74
|
+
export const requiredPhoneConstraints = {
|
|
75
|
+
subject: "unique(id)",
|
|
76
|
+
identifier: "unique(namespace,value)",
|
|
77
|
+
credential: "unique(credentialId)",
|
|
78
|
+
state: "unique(scope)",
|
|
79
|
+
} as const;
|
|
80
|
+
|
|
81
|
+
/** Consumer-owned schema; encoders and allocators are synchronous and side-effect free.
|
|
82
|
+
* State stores permanent number custody and command tombstones, plus bounded admission
|
|
83
|
+
* counters. Never delete custody rows to make a recycled number eligible. A consumer's
|
|
84
|
+
* explicit recovery workflow may resolve custody only after independent authentication.
|
|
85
|
+
* Subject defaults own account provisioning; no email/profile schema is prescribed. */
|
|
86
|
+
export interface PhoneMapping<
|
|
87
|
+
S extends Table,
|
|
88
|
+
I extends Table,
|
|
89
|
+
C extends Table,
|
|
90
|
+
T extends Table,
|
|
91
|
+
N,
|
|
92
|
+
> {
|
|
93
|
+
readonly moduleId: string;
|
|
94
|
+
readonly policy: PhoneLifecyclePolicy;
|
|
95
|
+
readonly admission: PhoneAdmissionPolicy;
|
|
96
|
+
readonly constraints: typeof requiredPhoneConstraints;
|
|
97
|
+
readonly proofs: PhoneProofCompletionMapping;
|
|
98
|
+
readonly subjectIds: {
|
|
99
|
+
readonly toNative: (id: SubjectId) => N;
|
|
100
|
+
readonly toSubject: (id: N) => SubjectId;
|
|
101
|
+
readonly allocate: () => N;
|
|
102
|
+
};
|
|
103
|
+
readonly subject: {
|
|
104
|
+
readonly table: S;
|
|
105
|
+
readonly id: PhoneColumn<S>;
|
|
106
|
+
readonly securityRevision: PhoneColumn<S>;
|
|
107
|
+
readonly activeCondition: SQL;
|
|
108
|
+
readonly decodeRequirement: (row: InferSelectModel<S>) => AuthenticationRequirement;
|
|
109
|
+
/** Current action policy, independently from primary sign-in assurance. */
|
|
110
|
+
readonly decodeActionRequirement?: (
|
|
111
|
+
row: InferSelectModel<S>,
|
|
112
|
+
action: "verify" | "change",
|
|
113
|
+
) => AuthenticationRequirement;
|
|
114
|
+
readonly encodeInsert: (input: {
|
|
115
|
+
readonly id: N;
|
|
116
|
+
readonly securityRevision: string;
|
|
117
|
+
readonly phoneNumber: PhoneNumber;
|
|
118
|
+
}) => InferInsertModel<S>;
|
|
119
|
+
};
|
|
120
|
+
readonly identifier: {
|
|
121
|
+
readonly table: I;
|
|
122
|
+
readonly namespace: PhoneColumn<I>;
|
|
123
|
+
readonly value: PhoneColumn<I>;
|
|
124
|
+
readonly subjectId: PhoneColumn<I>;
|
|
125
|
+
readonly revision: PhoneColumn<I>;
|
|
126
|
+
readonly verifiedAt: PhoneColumn<I>;
|
|
127
|
+
readonly status: PhoneColumn<I>;
|
|
128
|
+
readonly activeCondition: SQL;
|
|
129
|
+
readonly encodeStatus: (active: boolean) => unknown;
|
|
130
|
+
readonly encodeInsert: (input: {
|
|
131
|
+
readonly phoneNumber: PhoneNumber;
|
|
132
|
+
readonly subjectId: N;
|
|
133
|
+
readonly revision: string;
|
|
134
|
+
readonly verifiedAtMillis: number;
|
|
135
|
+
readonly active: boolean;
|
|
136
|
+
}) => InferInsertModel<I>;
|
|
137
|
+
};
|
|
138
|
+
readonly credential: {
|
|
139
|
+
readonly table: C;
|
|
140
|
+
readonly id: PhoneColumn<C>;
|
|
141
|
+
readonly subjectId: PhoneColumn<C>;
|
|
142
|
+
readonly revision: PhoneColumn<C>;
|
|
143
|
+
readonly status: PhoneColumn<C>;
|
|
144
|
+
readonly activeCondition: SQL;
|
|
145
|
+
readonly encodeStatus: (active: boolean) => unknown;
|
|
146
|
+
readonly encodeInsert: (input: {
|
|
147
|
+
readonly credentialId: string;
|
|
148
|
+
readonly subjectId: N;
|
|
149
|
+
readonly revision: string;
|
|
150
|
+
readonly active: boolean;
|
|
151
|
+
}) => InferInsertModel<C>;
|
|
152
|
+
};
|
|
153
|
+
readonly state: {
|
|
154
|
+
readonly table: T;
|
|
155
|
+
readonly scope: PhoneColumn<T>;
|
|
156
|
+
readonly state: PhoneColumn<T>;
|
|
157
|
+
readonly version: PhoneColumn<T>;
|
|
158
|
+
readonly encodeInsert: (input: {
|
|
159
|
+
readonly scope: string;
|
|
160
|
+
readonly state: string;
|
|
161
|
+
readonly version: string;
|
|
162
|
+
}) => InferInsertModel<T>;
|
|
163
|
+
};
|
|
164
|
+
readonly encodeInstant: (millis: number) => unknown;
|
|
165
|
+
readonly engineNowMillis: SQL;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface D1PhoneMapping {
|
|
169
|
+
readonly d1: { readonly primary: true };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface PhonePersistenceServices {
|
|
173
|
+
readonly phonePersistence: PhonePersistence["Service"];
|
|
174
|
+
readonly phoneAdmission: PhoneAdmission["Service"];
|
|
175
|
+
readonly phoneSignInTargets: PhoneSignInTargets["Service"];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Bundle phone storage, admission, and lookup with overridable crypto and hook defaults. */
|
|
179
|
+
export const phonePersistenceLayer = <E, R>(
|
|
180
|
+
services: Effect.Effect<PhonePersistenceServices, E, R>,
|
|
181
|
+
) =>
|
|
182
|
+
Layer.unwrap(
|
|
183
|
+
Effect.map(services, (value) =>
|
|
184
|
+
Layer.mergeAll(
|
|
185
|
+
Layer.succeed(PhonePersistence, value.phonePersistence),
|
|
186
|
+
Layer.succeed(PhoneAdmission, value.phoneAdmission),
|
|
187
|
+
Layer.succeed(PhoneSignInTargets, value.phoneSignInTargets),
|
|
188
|
+
),
|
|
189
|
+
),
|
|
190
|
+
).pipe(Layer.provide([cryptoLayer, hooksLayer]));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { makePhoneKernel } from "@yielded/auth-persistence/Adapter";
|
|
2
|
+
|
|
3
|
+
import { drizzleQueryOperations } from "./query-operations";
|
|
4
|
+
import { both, makeTransactionRows } from "./transaction-owner";
|
|
5
|
+
export { CurrentPhoneTransaction } from "@yielded/auth-persistence/Adapter";
|
|
6
|
+
|
|
7
|
+
const kernel = makePhoneKernel(drizzleQueryOperations, { both, makeTransactionRows });
|
|
8
|
+
|
|
9
|
+
export const {
|
|
10
|
+
unavailable,
|
|
11
|
+
equal,
|
|
12
|
+
copiedRow,
|
|
13
|
+
col,
|
|
14
|
+
capturePhone,
|
|
15
|
+
lookupPhone,
|
|
16
|
+
admitPhone,
|
|
17
|
+
preparePhoneMutation,
|
|
18
|
+
cleanupPhoneAdmission,
|
|
19
|
+
} = kernel;
|
|
20
|
+
|
|
21
|
+
export const invariant: (value: unknown) => asserts value = kernel.invariant;
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { randomId } from "@yielded/auth-crypto";
|
|
2
|
+
import { LifecycleHooks } from "@yielded/auth/Hooks";
|
|
3
|
+
import {
|
|
4
|
+
PhoneConfigurationError,
|
|
5
|
+
PhoneLifecyclePolicy,
|
|
6
|
+
PhoneAdmissionPolicy,
|
|
7
|
+
PhoneLifecycleTarget,
|
|
8
|
+
PhoneActionAuthorization,
|
|
9
|
+
PhoneAdmission,
|
|
10
|
+
type PhoneMutation,
|
|
11
|
+
PhonePersistence,
|
|
12
|
+
PhoneSignInTargets,
|
|
13
|
+
type PhoneOtpUnavailable as PhoneUnavailable,
|
|
14
|
+
} from "@yielded/auth/PhoneOtp";
|
|
15
|
+
import { ProofBinding } from "@yielded/auth/Proofs";
|
|
16
|
+
import { sql, type Table } from "drizzle-orm";
|
|
17
|
+
/* oxlint-disable no-explicit-any -- shared native implementation; driver entrypoints retain exact database and table types. */
|
|
18
|
+
import { Context, Effect, Schema } from "effect";
|
|
19
|
+
import type { Statement } from "effect/unstable/sql/Statement";
|
|
20
|
+
|
|
21
|
+
import { CurrentD1PlanningDatabase } from "./d1-planning";
|
|
22
|
+
import { compileD1ProofCompletionPlan } from "./d1-proofs";
|
|
23
|
+
import type { PersistenceMappingError } from "./model";
|
|
24
|
+
import {
|
|
25
|
+
phoneProofs,
|
|
26
|
+
type PhoneMapping,
|
|
27
|
+
type PhoneMappingSource,
|
|
28
|
+
type PhonePersistenceServices,
|
|
29
|
+
requiredPhoneConstraints,
|
|
30
|
+
} from "./phone-model";
|
|
31
|
+
import {
|
|
32
|
+
capturePhone,
|
|
33
|
+
lookupPhone,
|
|
34
|
+
admitPhone,
|
|
35
|
+
cleanupPhoneAdmission,
|
|
36
|
+
CurrentPhoneTransaction,
|
|
37
|
+
invariant,
|
|
38
|
+
equal,
|
|
39
|
+
preparePhoneMutation,
|
|
40
|
+
unavailable,
|
|
41
|
+
} from "./phone-state";
|
|
42
|
+
import { requiredProofConstraints } from "./proof-model";
|
|
43
|
+
import { completeProofPlanIn, CurrentProofSql } from "./proof-sql";
|
|
44
|
+
import type { SuppliedService } from "./SuppliedService";
|
|
45
|
+
import {
|
|
46
|
+
coordinateTransactionOwner,
|
|
47
|
+
makeTransactionExecution,
|
|
48
|
+
sqlClientTransactionStandaloneGuard,
|
|
49
|
+
type TransactionExecution,
|
|
50
|
+
type TransactionTargetConfiguration,
|
|
51
|
+
type TransactionCoordinatorError,
|
|
52
|
+
} from "./transaction-execution";
|
|
53
|
+
import type { TransactionNativeDatabase } from "./transaction-owner";
|
|
54
|
+
export type PhoneTargetConfiguration = TransactionTargetConfiguration<PhoneUnavailable>;
|
|
55
|
+
|
|
56
|
+
export type PhoneCoordinatorError<E> =
|
|
57
|
+
| TransactionCoordinatorError<E, PhoneUnavailable>
|
|
58
|
+
| PhoneConfigurationError
|
|
59
|
+
| PersistenceMappingError;
|
|
60
|
+
|
|
61
|
+
export const sqlClientPhoneStandaloneGuard = (
|
|
62
|
+
database: Parameters<typeof sqlClientTransactionStandaloneGuard>[1],
|
|
63
|
+
) => sqlClientTransactionStandaloneGuard(unavailable, database);
|
|
64
|
+
|
|
65
|
+
const validateMapping = <M>(original: M, configuration: PhoneTargetConfiguration): M => {
|
|
66
|
+
const mapping = original as any;
|
|
67
|
+
|
|
68
|
+
invariant(mapping.moduleId.length > 0);
|
|
69
|
+
Schema.decodeSync(PhoneLifecyclePolicy)(mapping.policy);
|
|
70
|
+
Schema.decodeSync(PhoneAdmissionPolicy)(mapping.admission);
|
|
71
|
+
invariant(mapping.admission.requestRetentionMillis >= mapping.admission.windowMillis);
|
|
72
|
+
const proofs = phoneProofs(mapping.proofs);
|
|
73
|
+
|
|
74
|
+
invariant(proofs !== undefined);
|
|
75
|
+
for (const [key, value] of Object.entries(requiredProofConstraints))
|
|
76
|
+
invariant((proofs.constraints as any)?.[key] === value);
|
|
77
|
+
if (configuration.mode === "synchronous") invariant(proofs.allocateVersionSync !== undefined);
|
|
78
|
+
if (configuration.mode === "batch")
|
|
79
|
+
invariant(
|
|
80
|
+
proofs.d1 !== undefined && proofs.authority.identifier.d1CurrentCondition !== undefined,
|
|
81
|
+
);
|
|
82
|
+
for (const [key, value] of Object.entries(requiredPhoneConstraints))
|
|
83
|
+
invariant(mapping.constraints?.[key] === value);
|
|
84
|
+
if (configuration.mode === "batch") invariant(mapping.d1?.primary === true);
|
|
85
|
+
|
|
86
|
+
return Object.freeze({
|
|
87
|
+
...mapping,
|
|
88
|
+
policy: Object.freeze({ ...mapping.policy }),
|
|
89
|
+
subject: Object.freeze({ ...mapping.subject }),
|
|
90
|
+
state: Object.freeze({ ...mapping.state }),
|
|
91
|
+
identifier: Object.freeze({ ...mapping.identifier }),
|
|
92
|
+
admission: Object.freeze({ ...mapping.admission }),
|
|
93
|
+
credential: Object.freeze({ ...mapping.credential }),
|
|
94
|
+
subjectIds: Object.freeze({ ...mapping.subjectIds }),
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const services = (
|
|
99
|
+
mapping: any,
|
|
100
|
+
execution: TransactionExecution<PhoneUnavailable, CurrentPhoneTransaction>,
|
|
101
|
+
hooks: LifecycleHooks["Service"],
|
|
102
|
+
configuration: PhoneTargetConfiguration,
|
|
103
|
+
): PhonePersistenceServices => {
|
|
104
|
+
const run = <A, E, R>(effect: Effect.Effect<A, E, R>, mutation = true) =>
|
|
105
|
+
execution.admit.pipe(
|
|
106
|
+
Effect.andThen(execution.run(effect, mutation)),
|
|
107
|
+
Effect.provideService(LifecycleHooks, hooks),
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
phoneAdmission: PhoneAdmission.of({
|
|
112
|
+
admit: (input) => run(admitPhone(mapping, { ...input })),
|
|
113
|
+
cleanup: (input) => run(cleanupPhoneAdmission(mapping, { ...input })),
|
|
114
|
+
}),
|
|
115
|
+
phoneSignInTargets: PhoneSignInTargets.of({
|
|
116
|
+
lookup: (input) => run(lookupPhone(mapping, { ...input }), false),
|
|
117
|
+
}),
|
|
118
|
+
phonePersistence: PhonePersistence.of({
|
|
119
|
+
target: (input) =>
|
|
120
|
+
run(
|
|
121
|
+
Effect.gen(function* () {
|
|
122
|
+
invariant(input.moduleId === mapping.moduleId);
|
|
123
|
+
|
|
124
|
+
return (yield* capturePhone(mapping, { ...input })).target;
|
|
125
|
+
}),
|
|
126
|
+
false,
|
|
127
|
+
),
|
|
128
|
+
mutate: (original, prepare) =>
|
|
129
|
+
Effect.suspend(() => {
|
|
130
|
+
const input: PhoneMutation = {
|
|
131
|
+
...original,
|
|
132
|
+
target: Schema.decodeSync(Schema.toCodecIso(PhoneLifecycleTarget))(
|
|
133
|
+
Schema.encodeSync(Schema.toCodecIso(PhoneLifecycleTarget))(original.target),
|
|
134
|
+
),
|
|
135
|
+
policy: { ...original.policy },
|
|
136
|
+
...(original.authorization === undefined
|
|
137
|
+
? {}
|
|
138
|
+
: {
|
|
139
|
+
authorization: Schema.decodeSync(Schema.toCodecIso(PhoneActionAuthorization))(
|
|
140
|
+
Schema.encodeSync(Schema.toCodecIso(PhoneActionAuthorization))(
|
|
141
|
+
original.authorization,
|
|
142
|
+
),
|
|
143
|
+
),
|
|
144
|
+
}),
|
|
145
|
+
completion: {
|
|
146
|
+
input: {
|
|
147
|
+
...original.completion.input,
|
|
148
|
+
binding: Schema.decodeSync(Schema.toCodecIso(ProofBinding))(
|
|
149
|
+
Schema.encodeSync(Schema.toCodecIso(ProofBinding))(
|
|
150
|
+
original.completion.input.binding,
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
},
|
|
154
|
+
prepare: original.completion.prepare,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
return run(
|
|
159
|
+
Effect.gen(function* () {
|
|
160
|
+
const owner = yield* CurrentPhoneTransaction,
|
|
161
|
+
candidate = yield* preparePhoneMutation(mapping, input);
|
|
162
|
+
|
|
163
|
+
if (candidate.mutate === undefined) {
|
|
164
|
+
const receipt = prepare(candidate.decision, owner.journal);
|
|
165
|
+
|
|
166
|
+
owner.guards.push(receipt as any);
|
|
167
|
+
|
|
168
|
+
return receipt;
|
|
169
|
+
}
|
|
170
|
+
const cn = phoneProofs(mapping.proofs).continuation;
|
|
171
|
+
|
|
172
|
+
const observed = yield* owner.read(
|
|
173
|
+
cn.table,
|
|
174
|
+
equal(cn.table, {
|
|
175
|
+
[cn.moduleId]: input.completion.input.moduleId,
|
|
176
|
+
[cn.continuationId]: input.completion.input.continuationId,
|
|
177
|
+
}),
|
|
178
|
+
{ limit: 1 },
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
let completed = false;
|
|
182
|
+
|
|
183
|
+
const plan = {
|
|
184
|
+
...input.completion,
|
|
185
|
+
prepare: (decision: any, journal: any) => {
|
|
186
|
+
completed = decision === "completed";
|
|
187
|
+
const proofReceipt = input.completion.prepare(decision, journal, () => undefined);
|
|
188
|
+
|
|
189
|
+
owner.guards.push(proofReceipt);
|
|
190
|
+
|
|
191
|
+
return prepare(
|
|
192
|
+
decision === "completed" ? candidate.decision : { _tag: "Rejected" },
|
|
193
|
+
journal,
|
|
194
|
+
);
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
let receipt;
|
|
199
|
+
|
|
200
|
+
if (owner.batch) {
|
|
201
|
+
const offset = owner.statements.length;
|
|
202
|
+
|
|
203
|
+
yield* candidate.mutate;
|
|
204
|
+
const statements = owner.statements.splice(offset);
|
|
205
|
+
|
|
206
|
+
const compiled = yield* compileD1ProofCompletionPlan(
|
|
207
|
+
phoneProofs(mapping.proofs) as any,
|
|
208
|
+
plan as any,
|
|
209
|
+
{ statements, appliedCondition: candidate.appliedCondition! },
|
|
210
|
+
(x) => x,
|
|
211
|
+
).pipe(Effect.provideService(CurrentD1PlanningDatabase, owner.database));
|
|
212
|
+
|
|
213
|
+
// Mutation observations describe an accepted plan. A stale proof aborts this owner.
|
|
214
|
+
invariant(compiled.statements.length !== 0);
|
|
215
|
+
owner.statements.push(...compiled.statements, ...(compiled.postconditions ?? []));
|
|
216
|
+
receipt = compiled.receipt;
|
|
217
|
+
} else {
|
|
218
|
+
receipt = yield* completeProofPlanIn(
|
|
219
|
+
phoneProofs(mapping.proofs),
|
|
220
|
+
{
|
|
221
|
+
mode: configuration.mode === "synchronous" ? "synchronous" : "interactive",
|
|
222
|
+
locking: configuration.locking,
|
|
223
|
+
standaloneGuard: Effect.void,
|
|
224
|
+
coordinated: true,
|
|
225
|
+
insertIfAbsent: (query: any, key, value) =>
|
|
226
|
+
configuration.dialect === "mysql"
|
|
227
|
+
? query.onDuplicateKeyUpdate({ set: { [key]: value } })
|
|
228
|
+
: query.onConflictDoNothing(),
|
|
229
|
+
},
|
|
230
|
+
plan as any,
|
|
231
|
+
candidate.mutate,
|
|
232
|
+
(x) => x,
|
|
233
|
+
).pipe(Effect.provideService(CurrentProofSql, owner.database));
|
|
234
|
+
}
|
|
235
|
+
if (completed) {
|
|
236
|
+
invariant(observed.rows.length === 1);
|
|
237
|
+
const record = yield* cn.decode(observed.rows[0]!);
|
|
238
|
+
|
|
239
|
+
observed.rows = observed.rows.map((row) => ({ ...row, [cn.consumed]: true }));
|
|
240
|
+
const command = phoneProofs(mapping.proofs).command;
|
|
241
|
+
|
|
242
|
+
owner.postconditions.push(
|
|
243
|
+
sql`${mapping.engineNowMillis} < ${record.expiresAtMillis}`,
|
|
244
|
+
sql`exists(select 1 from ${command.table} where ${equal(command.table, { [command.moduleId]: input.completion.input.moduleId, [command.commandId]: input.completion.input.continuationDigest, [command.kind]: "complete", [command.decision]: "completed", [command.retentionUntil]: phoneProofs(mapping.proofs).encodeInstant(record.expiresAtMillis) })})`,
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
invariant(receipt?._tag === "PreparedCommit");
|
|
248
|
+
owner.guards.push(receipt as any);
|
|
249
|
+
|
|
250
|
+
return receipt as ReturnType<typeof prepare>;
|
|
251
|
+
}),
|
|
252
|
+
);
|
|
253
|
+
}).pipe(Effect.catchDefect(() => Effect.fail(unavailable()))),
|
|
254
|
+
}),
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export const makeTargetPhonePersistence = <
|
|
259
|
+
S extends Table,
|
|
260
|
+
I extends Table,
|
|
261
|
+
F extends Table,
|
|
262
|
+
C extends Table,
|
|
263
|
+
N,
|
|
264
|
+
RSetup = never,
|
|
265
|
+
>(
|
|
266
|
+
database: TransactionNativeDatabase,
|
|
267
|
+
source: PhoneMappingSource<PhoneMapping<S, I, C, F, N>, RSetup>,
|
|
268
|
+
configuration: PhoneTargetConfiguration,
|
|
269
|
+
) =>
|
|
270
|
+
Effect.gen(function* () {
|
|
271
|
+
const hooks = yield* LifecycleHooks;
|
|
272
|
+
const original = yield* Effect.isEffect(source) ? source : Effect.succeed(source);
|
|
273
|
+
|
|
274
|
+
const mapping = yield* Effect.try({
|
|
275
|
+
try: () => validateMapping(original, configuration),
|
|
276
|
+
catch: () => PhoneConfigurationError.make({}),
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const execution = makeTransactionExecution(
|
|
280
|
+
CurrentPhoneTransaction,
|
|
281
|
+
database,
|
|
282
|
+
configuration,
|
|
283
|
+
unavailable,
|
|
284
|
+
randomId,
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
return services(mapping, execution, hooks, configuration);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
export const coordinateTargetPhone = <M, A, E, R, RSetup = never>(
|
|
291
|
+
database: TransactionNativeDatabase,
|
|
292
|
+
source: PhoneMappingSource<M, RSetup>,
|
|
293
|
+
configuration: PhoneTargetConfiguration,
|
|
294
|
+
body: (
|
|
295
|
+
transaction: any,
|
|
296
|
+
services: PhonePersistenceServices,
|
|
297
|
+
append: (statement: Statement<any>) => void,
|
|
298
|
+
) => Effect.Effect<A, E, R>,
|
|
299
|
+
): Effect.Effect<A, PhoneCoordinatorError<E>, R | RSetup | LifecycleHooks> =>
|
|
300
|
+
Effect.gen(function* () {
|
|
301
|
+
const hooks = yield* LifecycleHooks;
|
|
302
|
+
const original = yield* Effect.isEffect(source) ? source : Effect.succeed(source);
|
|
303
|
+
|
|
304
|
+
const mapping = yield* Effect.try({
|
|
305
|
+
try: () => validateMapping(original, configuration),
|
|
306
|
+
catch: () => PhoneConfigurationError.make({}),
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
return yield* coordinateTransactionOwner(
|
|
310
|
+
database,
|
|
311
|
+
CurrentPhoneTransaction,
|
|
312
|
+
configuration,
|
|
313
|
+
Effect.void,
|
|
314
|
+
unavailable,
|
|
315
|
+
randomId,
|
|
316
|
+
(execution) => services(mapping, execution, hooks, configuration),
|
|
317
|
+
body,
|
|
318
|
+
);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
type TransactionOf<D> = D extends { readonly transaction: (...args: any[]) => any }
|
|
322
|
+
? Parameters<Parameters<D["transaction"]>[0]>[0]
|
|
323
|
+
: never;
|
|
324
|
+
|
|
325
|
+
/** Concrete driver wrappers select transaction mode; cryptography always precedes these owners. */
|
|
326
|
+
export const makePhoneTarget = <
|
|
327
|
+
D extends { readonly transaction: any },
|
|
328
|
+
T extends Table,
|
|
329
|
+
Extra = unknown,
|
|
330
|
+
Synchronous extends boolean = false,
|
|
331
|
+
>(
|
|
332
|
+
configuration: PhoneTargetConfiguration,
|
|
333
|
+
) => {
|
|
334
|
+
function coordinatePhonePersistence<
|
|
335
|
+
Database extends D,
|
|
336
|
+
S extends T,
|
|
337
|
+
I extends T,
|
|
338
|
+
F extends T,
|
|
339
|
+
C extends T,
|
|
340
|
+
N,
|
|
341
|
+
A,
|
|
342
|
+
E,
|
|
343
|
+
R,
|
|
344
|
+
RSetup = never,
|
|
345
|
+
DatabaseError = never,
|
|
346
|
+
DatabaseRequirements = never,
|
|
347
|
+
>(
|
|
348
|
+
acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
|
|
349
|
+
options: {
|
|
350
|
+
readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & Extra, RSetup>;
|
|
351
|
+
readonly transaction?: never;
|
|
352
|
+
},
|
|
353
|
+
body: Effect.Effect<
|
|
354
|
+
A,
|
|
355
|
+
E,
|
|
356
|
+
Synchronous extends true ? NoInfer<PhonePersistence | PhoneAdmission | PhoneSignInTargets> : R
|
|
357
|
+
>,
|
|
358
|
+
): Effect.Effect<
|
|
359
|
+
A,
|
|
360
|
+
PhoneCoordinatorError<E> | DatabaseError,
|
|
361
|
+
| (Synchronous extends true
|
|
362
|
+
? never
|
|
363
|
+
: Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets>)
|
|
364
|
+
| LifecycleHooks
|
|
365
|
+
| RSetup
|
|
366
|
+
| DatabaseRequirements
|
|
367
|
+
>;
|
|
368
|
+
function coordinatePhonePersistence<
|
|
369
|
+
Database extends D,
|
|
370
|
+
S extends T,
|
|
371
|
+
I extends T,
|
|
372
|
+
F extends T,
|
|
373
|
+
C extends T,
|
|
374
|
+
N,
|
|
375
|
+
A,
|
|
376
|
+
E,
|
|
377
|
+
R,
|
|
378
|
+
TxId,
|
|
379
|
+
TxShape,
|
|
380
|
+
RSetup = never,
|
|
381
|
+
DatabaseError = never,
|
|
382
|
+
DatabaseRequirements = never,
|
|
383
|
+
>(
|
|
384
|
+
acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
|
|
385
|
+
options: {
|
|
386
|
+
readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & Extra, RSetup>;
|
|
387
|
+
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<Database>>, TxShape>;
|
|
388
|
+
},
|
|
389
|
+
body: Effect.Effect<
|
|
390
|
+
A,
|
|
391
|
+
E,
|
|
392
|
+
Synchronous extends true
|
|
393
|
+
? NoInfer<PhonePersistence | PhoneAdmission | PhoneSignInTargets | TxId>
|
|
394
|
+
: R
|
|
395
|
+
>,
|
|
396
|
+
): Effect.Effect<
|
|
397
|
+
A,
|
|
398
|
+
PhoneCoordinatorError<E> | DatabaseError,
|
|
399
|
+
| (Synchronous extends true
|
|
400
|
+
? never
|
|
401
|
+
: Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets | TxId>)
|
|
402
|
+
| LifecycleHooks
|
|
403
|
+
| RSetup
|
|
404
|
+
| DatabaseRequirements
|
|
405
|
+
>;
|
|
406
|
+
function coordinatePhonePersistence<
|
|
407
|
+
Database extends D,
|
|
408
|
+
S extends T,
|
|
409
|
+
I extends T,
|
|
410
|
+
F extends T,
|
|
411
|
+
C extends T,
|
|
412
|
+
N,
|
|
413
|
+
A,
|
|
414
|
+
E,
|
|
415
|
+
R,
|
|
416
|
+
TxId,
|
|
417
|
+
TxShape,
|
|
418
|
+
RSetup = never,
|
|
419
|
+
DatabaseError = never,
|
|
420
|
+
DatabaseRequirements = never,
|
|
421
|
+
>(
|
|
422
|
+
acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
|
|
423
|
+
options: {
|
|
424
|
+
readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & Extra, RSetup>;
|
|
425
|
+
readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<Database>>, TxShape>;
|
|
426
|
+
},
|
|
427
|
+
body: Effect.Effect<A, E, R>,
|
|
428
|
+
): Effect.Effect<
|
|
429
|
+
A,
|
|
430
|
+
PhoneCoordinatorError<E> | DatabaseError,
|
|
431
|
+
| Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets>
|
|
432
|
+
| LifecycleHooks
|
|
433
|
+
| RSetup
|
|
434
|
+
| DatabaseRequirements
|
|
435
|
+
> {
|
|
436
|
+
return Effect.flatMap(acquire, (database) =>
|
|
437
|
+
coordinateTargetPhone(
|
|
438
|
+
database as any,
|
|
439
|
+
options.mapping,
|
|
440
|
+
configuration,
|
|
441
|
+
(transaction: TransactionOf<Database>, services) => {
|
|
442
|
+
const provided = Context.make(PhonePersistence, services.phonePersistence).pipe(
|
|
443
|
+
Context.add(PhoneAdmission, services.phoneAdmission),
|
|
444
|
+
Context.add(PhoneSignInTargets, services.phoneSignInTargets),
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
const work = Effect.provideContext(body, provided);
|
|
448
|
+
|
|
449
|
+
return options.transaction === undefined
|
|
450
|
+
? work
|
|
451
|
+
: Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
452
|
+
},
|
|
453
|
+
),
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return {
|
|
458
|
+
makePhonePersistenceServices: <
|
|
459
|
+
Database extends D,
|
|
460
|
+
S extends T,
|
|
461
|
+
I extends T,
|
|
462
|
+
F extends T,
|
|
463
|
+
C extends T,
|
|
464
|
+
N,
|
|
465
|
+
RSetup = never,
|
|
466
|
+
>(
|
|
467
|
+
database: Database,
|
|
468
|
+
mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & Extra, RSetup>,
|
|
469
|
+
) => makeTargetPhonePersistence(database as any, mapping, configuration),
|
|
470
|
+
coordinatePhonePersistence,
|
|
471
|
+
};
|
|
472
|
+
};
|