@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 @@
|
|
|
1
|
+
{"version":3,"file":"pg-sessions.mjs","names":[],"sources":["../../src/drizzle/pg-sessions.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport {\n AuthenticationAuthority,\n type SessionUnavailable,\n type PendingAuthentication,\n type SessionRepository,\n type SignedSessionValidity,\n type StatefulSessionPersistence,\n type SessionStepUpPersistence,\n} from \"@yielded/auth/Sessions\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectPgDatabase as PgliteDatabase } from \"drizzle-orm/effect-pglite\";\nimport type { EffectPgDatabase as PostgresDatabase } from \"drizzle-orm/effect-postgres\";\nimport type { AnyPgTable } from \"drizzle-orm/pg-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport type {\n AuthenticationAuthorityMapping,\n PendingAuthenticationMapping,\n SignedSessionValidityMapping,\n StatefulSessionMapping,\n} from \"./session-model\";\nimport {\n coordinateTargetAuthenticationAuthority,\n coordinateTargetPendingAuthentication,\n coordinateTargetSignedSessionValidity,\n coordinateTargetStatefulSessions,\n makeTargetAuthenticationAuthorityServices,\n makeTargetPendingAuthenticationServices,\n makeTargetSignedSessionValidityServices,\n makeTargetStatefulSessionServices,\n sqlClientSessionStandaloneGuard,\n makeTargetSessionStepUpServices,\n coordinateTargetSessionStepUp,\n} from \"./session-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = PostgresDatabase<AnyRelations> | PgliteDatabase<AnyRelations>;\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nconst configuration = (database: Database) => ({\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientSessionStandaloneGuard(database),\n});\n\nexport const makePgAuthenticationAuthorityServices = <\n Claims,\n Subject extends AnyPgTable,\n Credential extends AnyPgTable,\n Flow extends AnyPgTable,\n Pending extends AnyPgTable,\n NativeSubjectId,\n>(\n database: Database,\n mapping: AuthenticationAuthorityMapping<\n Claims,\n Subject,\n Credential,\n Flow,\n Pending,\n NativeSubjectId\n >,\n) => makeTargetAuthenticationAuthorityServices<Claims>(database, mapping, configuration(database));\n\nexport const makePgPendingAuthenticationServices = <\n Claims,\n Subject extends AnyPgTable,\n Credential extends AnyPgTable,\n Pending extends AnyPgTable,\n Flow extends AnyPgTable,\n NativeSubjectId,\n>(\n database: Database,\n mapping: PendingAuthenticationMapping<\n Claims,\n Subject,\n Credential,\n Pending,\n Flow,\n NativeSubjectId\n >,\n) => makeTargetPendingAuthenticationServices<Claims>(database, mapping, configuration(database));\n\nexport const makePgStatefulSessionServices = <\n Claims,\n Subject extends AnyPgTable,\n Credential extends AnyPgTable,\n Session extends AnyPgTable,\n Flow extends AnyPgTable,\n Pending extends AnyPgTable,\n NativeSubjectId,\n NativeSessionId,\n>(\n database: Database,\n mapping: StatefulSessionMapping<\n Claims,\n Subject,\n Credential,\n Session,\n Flow,\n Pending,\n NativeSubjectId,\n NativeSessionId\n >,\n) => makeTargetStatefulSessionServices<Claims>(database, mapping, configuration(database));\n\nexport const makePgSignedSessionValidityServices = <\n Subject extends AnyPgTable,\n Tombstone extends AnyPgTable,\n NativeSubjectId,\n NativeSessionId,\n>(\n database: Database,\n mapping: SignedSessionValidityMapping<Subject, Tombstone, NativeSubjectId, NativeSessionId>,\n) => makeTargetSignedSessionValidityServices(database, mapping, configuration(database));\n\nexport function coordinatePgAuthenticationAuthority<\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n F extends AnyPgTable,\n P extends AnyPgTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthenticationAuthorityMapping<Claims, S, C, F, P, NativeId>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, AuthenticationAuthority> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgAuthenticationAuthority<\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n F extends AnyPgTable,\n P extends AnyPgTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthenticationAuthorityMapping<Claims, S, C, F, P, NativeId>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, AuthenticationAuthority | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgAuthenticationAuthority<\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n F extends AnyPgTable,\n P extends AnyPgTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthenticationAuthorityMapping<Claims, S, C, F, P, NativeId>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, AuthenticationAuthority> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetAuthenticationAuthority<\n Claims,\n TransactionOf<D>,\n A,\n E,\n Exclude<R, AuthenticationAuthority>\n >(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly authenticationAuthority: AuthenticationAuthority[\"Service\"] },\n ) => {\n const provided = Context.make(AuthenticationAuthority, services.authenticationAuthority);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport function coordinatePgPendingAuthentication<\n TargetId,\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n P extends AnyPgTable,\n F extends AnyPgTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PendingAuthenticationMapping<NoInfer<Claims>, S, C, P, F, NativeId>;\n readonly target: SuppliedService<TargetId, PendingAuthentication<Claims>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgPendingAuthentication<\n TargetId,\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n P extends AnyPgTable,\n F extends AnyPgTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PendingAuthenticationMapping<NoInfer<Claims>, S, C, P, F, NativeId>;\n readonly target: SuppliedService<TargetId, PendingAuthentication<Claims>>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgPendingAuthentication<\n TargetId,\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n P extends AnyPgTable,\n F extends AnyPgTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PendingAuthenticationMapping<NoInfer<Claims>, S, C, P, F, NativeId>;\n readonly target: SuppliedService<TargetId, PendingAuthentication<Claims>>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetPendingAuthentication<Claims, TransactionOf<D>, A, E, Exclude<R, TargetId>>(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly pendingAuthentication: PendingAuthentication<Claims> },\n ) => {\n const provided = Context.make(options.target, services.pendingAuthentication);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport function coordinatePgStatefulSessions<\n PersistenceId,\n RepositoryId,\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n Session extends AnyPgTable,\n F extends AnyPgTable,\n P extends AnyPgTable,\n NativeId,\n NativeSessionId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: StatefulSessionMapping<\n NoInfer<Claims>,\n S,\n C,\n Session,\n F,\n P,\n NativeId,\n NativeSessionId\n >;\n readonly persistence: SuppliedService<PersistenceId, StatefulSessionPersistence<Claims>>;\n readonly repository: SuppliedService<RepositoryId, SessionRepository>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PersistenceId | RepositoryId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgStatefulSessions<\n PersistenceId,\n RepositoryId,\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n Session extends AnyPgTable,\n F extends AnyPgTable,\n P extends AnyPgTable,\n NativeId,\n NativeSessionId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: StatefulSessionMapping<\n NoInfer<Claims>,\n S,\n C,\n Session,\n F,\n P,\n NativeId,\n NativeSessionId\n >;\n readonly persistence: SuppliedService<PersistenceId, StatefulSessionPersistence<Claims>>;\n readonly repository: SuppliedService<RepositoryId, SessionRepository>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PersistenceId | RepositoryId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgStatefulSessions<\n PersistenceId,\n RepositoryId,\n Claims,\n D extends Database,\n S extends AnyPgTable,\n C extends AnyPgTable,\n Session extends AnyPgTable,\n F extends AnyPgTable,\n P extends AnyPgTable,\n NativeId,\n NativeSessionId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: StatefulSessionMapping<\n NoInfer<Claims>,\n S,\n C,\n Session,\n F,\n P,\n NativeId,\n NativeSessionId\n >;\n readonly persistence: SuppliedService<PersistenceId, StatefulSessionPersistence<Claims>>;\n readonly repository: SuppliedService<RepositoryId, SessionRepository>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PersistenceId | RepositoryId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetStatefulSessions<\n Claims,\n TransactionOf<D>,\n A,\n E,\n Exclude<R, PersistenceId | RepositoryId>\n >(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: {\n readonly statefulSessionPersistence: StatefulSessionPersistence<Claims>;\n readonly sessionRepository: SessionRepository;\n },\n ) => {\n const provided = Context.make(\n options.persistence,\n services.statefulSessionPersistence,\n ).pipe(Context.add(options.repository, services.sessionRepository));\n\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport function coordinatePgSignedSessionValidity<\n TargetId,\n D extends Database,\n S extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: SignedSessionValidityMapping<S, T, NativeId, NativeSessionId>;\n readonly target: SuppliedService<TargetId, SignedSessionValidity>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgSignedSessionValidity<\n TargetId,\n D extends Database,\n S extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: SignedSessionValidityMapping<S, T, NativeId, NativeSessionId>;\n readonly target: SuppliedService<TargetId, SignedSessionValidity>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgSignedSessionValidity<\n TargetId,\n D extends Database,\n S extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: SignedSessionValidityMapping<S, T, NativeId, NativeSessionId>;\n readonly target: SuppliedService<TargetId, SignedSessionValidity>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetSignedSessionValidity<TransactionOf<D>, A, E, Exclude<R, TargetId>>(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly signedSessionValidity: SignedSessionValidity },\n ) => {\n const provided = Context.make(options.target, services.signedSessionValidity);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nimport type { SessionStepUpMapping } from \"./step-up-model\";\n\nexport const makePgSessionStepUpServices = <\n Claims,\n Id,\n S extends AnyPgTable,\n C extends AnyPgTable,\n I extends AnyPgTable,\n Session extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n>(\n database: Database,\n mapping: SessionStepUpMapping<NoInfer<Claims>, S, C, I, Session, T, NativeId, NativeSessionId>,\n target: Context.Service<Id, SessionStepUpPersistence<Claims>>,\n) => makeTargetSessionStepUpServices(database, mapping, target, configuration(database));\n\nexport function coordinatePgSessionStepUp<\n Claims,\n Id,\n S extends AnyPgTable,\n C extends AnyPgTable,\n I extends AnyPgTable,\n Session extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n D extends Database,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: SessionStepUpMapping<\n NoInfer<Claims>,\n S,\n C,\n I,\n Session,\n T,\n NativeId,\n NativeSessionId\n >;\n readonly target: SuppliedService<Id, SessionStepUpPersistence<Claims>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, Id> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgSessionStepUp<\n Claims,\n Id,\n S extends AnyPgTable,\n C extends AnyPgTable,\n I extends AnyPgTable,\n Session extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n D extends Database,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: SessionStepUpMapping<\n NoInfer<Claims>,\n S,\n C,\n I,\n Session,\n T,\n NativeId,\n NativeSessionId\n >;\n readonly target: SuppliedService<Id, SessionStepUpPersistence<Claims>>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, Id | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinatePgSessionStepUp<\n Claims,\n Id,\n S extends AnyPgTable,\n C extends AnyPgTable,\n I extends AnyPgTable,\n Session extends AnyPgTable,\n T extends AnyPgTable,\n NativeId,\n NativeSessionId,\n D extends Database,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: SessionStepUpMapping<\n NoInfer<Claims>,\n S,\n C,\n I,\n Session,\n T,\n NativeId,\n NativeSessionId\n >;\n readonly target: SuppliedService<Id, SessionStepUpPersistence<Claims>>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | SessionUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, Id> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetSessionStepUp<Claims, Id, TransactionOf<D>, A, E, Exclude<R, Id>>(\n database,\n options.mapping,\n options.target,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly sessionStepUpPersistence: SessionStepUpPersistence<Claims> },\n ) => {\n const provided = Context.make(options.target, services.sessionStepUpPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n"],"mappings":";;;;AAyCA,MAAM,iBAAiB,cAAwB;CAC7C,MAAM;CACN,SAAS;CACT,iBAAiB,gCAAgC,QAAQ;AAC3D;AAEA,MAAa,yCAQX,UACA,YAQG,0CAAkD,UAAU,SAAS,cAAc,QAAQ,CAAC;AAEjG,MAAa,uCAQX,UACA,YAQG,wCAAgD,UAAU,SAAS,cAAc,QAAQ,CAAC;AAE/F,MAAa,iCAUX,UACA,YAUG,kCAA0C,UAAU,SAAS,cAAc,QAAQ,CAAC;AAEzF,MAAa,uCAMX,UACA,YACG,wCAAwC,UAAU,SAAS,cAAc,QAAQ,CAAC;AAwDvF,SAAgB,oCAgBd,SACA,SAIA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,wCAOE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,yBAAyB,SAAS,uBAAuB;EACvF,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AA4DA,SAAgB,kCAiBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,sCACE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,qBAAqB;EAC5E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAsFA,SAAgB,6BAoBd,SACA,SAeA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,iCAOE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aAIG;EACH,MAAM,WAAW,QAAQ,KACvB,QAAQ,aACR,SAAS,0BACX,CAAC,CAAC,KAAK,QAAQ,IAAI,QAAQ,YAAY,SAAS,iBAAiB,CAAC;EAElE,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAwDA,SAAgB,kCAed,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,sCACE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,qBAAqB;EAC5E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAIA,MAAa,+BAWX,UACA,SACA,WACG,gCAAgC,UAAU,SAAS,QAAQ,cAAc,QAAQ,CAAC;AAkFvF,SAAgB,0BAmBd,SACA,SAcA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,8BACE,UACA,QAAQ,SACR,QAAQ,QACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,wBAAwB;EAC/E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { AuthStoreTables, AuthTables, ChallengeConsumeDecision, ConsumeDecision, ExternalIdentityTables, OAuthStateTables, SubjectProvisioningTables } from "./model.mjs";
|
|
2
|
+
import { SuppliedService } from "./SuppliedService.mjs";
|
|
3
|
+
import { AuthStore, EmailOtpRejected } from "@yielded/auth/AuthStore";
|
|
4
|
+
import { AuthStoreError, InvalidRegistration } from "@yielded/auth/Errors";
|
|
5
|
+
import { ExternalIdentity, ExternalIdentityMutation, IdentityConflict, IdentityUnavailable, SubjectProvisioner, SubjectProvisioningInput } from "@yielded/auth/Identity";
|
|
6
|
+
import { InvalidOAuthState, OAuthState, OAuthStateDecisions, OAuthStateStore } from "@yielded/auth/OAuth";
|
|
7
|
+
import { ConsumeChallenge, ConsumeRegistration, NewChallenge, NewRegistration, SubjectId, TokenDigest, VerifiedEmail } from "@yielded/auth/Schema";
|
|
8
|
+
import { AnyRelations } from "drizzle-orm";
|
|
9
|
+
import { Context, Effect, Layer } from "effect";
|
|
10
|
+
import { AuthStoreDecisions } from "@yielded/auth/Persistence";
|
|
11
|
+
import { EffectPgDatabase } from "drizzle-orm/effect-pglite";
|
|
12
|
+
import { AnyPgTable } from "drizzle-orm/pg-core";
|
|
13
|
+
import { EffectPgDatabase as EffectPgDatabase$1 } from "drizzle-orm/effect-postgres";
|
|
14
|
+
import { SqlError } from "effect/unstable/sql/SqlError";
|
|
15
|
+
//#region src/drizzle/pg.d.ts
|
|
16
|
+
type Database = EffectPgDatabase$1<AnyRelations> | EffectPgDatabase<AnyRelations>;
|
|
17
|
+
type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
|
|
18
|
+
export declare const makePgAuthStoreServices: <C extends AnyPgTable, R extends AnyPgTable>(database: Database, mapping: AuthStoreTables<C, R>) => {
|
|
19
|
+
readonly authStore: {
|
|
20
|
+
readonly issueChallenge: (input: NewChallenge) => Effect.Effect<void, import("@yielded/auth/AuthStore").IssueChallengeError>;
|
|
21
|
+
readonly consumeChallenge: (input: ConsumeChallenge) => Effect.Effect<VerifiedEmail, EmailOtpRejected | AuthStoreError>;
|
|
22
|
+
readonly issueRegistration: (input: NewRegistration) => Effect.Effect<void, AuthStoreError>;
|
|
23
|
+
readonly inspectRegistration: (tokenDigest: TokenDigest) => Effect.Effect<import("@yielded/auth/Schema").PendingRegistration, InvalidRegistration | AuthStoreError>;
|
|
24
|
+
readonly consumeRegistration: (input: ConsumeRegistration) => Effect.Effect<void, InvalidRegistration | AuthStoreError>;
|
|
25
|
+
};
|
|
26
|
+
readonly decisions: {
|
|
27
|
+
readonly consumeChallenge: (input: ConsumeChallenge) => Effect.Effect<ChallengeConsumeDecision, AuthStoreError, never>;
|
|
28
|
+
readonly consumeRegistration: (input: ConsumeRegistration) => Effect.Effect<ConsumeDecision<void>, AuthStoreError, never>;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export declare const makePgOAuthStateServices: <S extends AnyPgTable>(database: Database, mapping: OAuthStateTables<S>) => {
|
|
32
|
+
readonly oauthStateStore: {
|
|
33
|
+
readonly issue: (state: OAuthState) => Effect.Effect<void, AuthStoreError>;
|
|
34
|
+
readonly consume: (stateDigest: TokenDigest) => Effect.Effect<OAuthState, InvalidOAuthState | AuthStoreError>;
|
|
35
|
+
};
|
|
36
|
+
readonly decisions: {
|
|
37
|
+
readonly consumeOAuthState: (digest: string & import("effect/Brand").Brand<"effect-auth/TokenDigest">) => Effect.Effect<ConsumeDecision<OAuthState>, AuthStoreError, never>;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Owns the native outer commit. Keep rejection as a decision value inside the
|
|
42
|
+
* owner; interruption before commit rolls back. Retry an unknown commit outcome
|
|
43
|
+
* only with the same stable request identity.
|
|
44
|
+
*/
|
|
45
|
+
export declare function coordinatePgAuthStoreTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
46
|
+
readonly mapping: AuthStoreTables<C, R>;
|
|
47
|
+
readonly transaction?: never;
|
|
48
|
+
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions> | DatabaseRequirements>;
|
|
49
|
+
export declare function coordinatePgAuthStoreTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements, TxId, TxShape>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
50
|
+
readonly mapping: AuthStoreTables<C, R>;
|
|
51
|
+
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
52
|
+
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions | TxId> | DatabaseRequirements>;
|
|
53
|
+
export declare function coordinatePgOAuthStateTransaction<D extends Database, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
54
|
+
readonly mapping: OAuthStateTables<S>;
|
|
55
|
+
readonly transaction?: never;
|
|
56
|
+
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, OAuthStateDecisions> | DatabaseRequirements>;
|
|
57
|
+
export declare function coordinatePgOAuthStateTransaction<D extends Database, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements, TxId, TxShape>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
58
|
+
readonly mapping: OAuthStateTables<S>;
|
|
59
|
+
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
60
|
+
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, OAuthStateDecisions | TxId> | DatabaseRequirements>;
|
|
61
|
+
export declare function coordinatePgAuthTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
62
|
+
readonly mapping: AuthTables<C, R, S>;
|
|
63
|
+
readonly transaction?: never;
|
|
64
|
+
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions> | DatabaseRequirements>;
|
|
65
|
+
export declare function coordinatePgAuthTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements, TxId, TxShape>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
66
|
+
readonly mapping: AuthTables<C, R, S>;
|
|
67
|
+
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
68
|
+
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions | TxId> | DatabaseRequirements>;
|
|
69
|
+
export declare const makePgSubjectProvisioningServices: <Subject extends AnyPgTable, Identifier extends AnyPgTable, Request extends AnyPgTable, NativeId>(database: Database, mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) => {
|
|
70
|
+
readonly subjectProvisioner: {
|
|
71
|
+
readonly provision: (input: SubjectProvisioningInput) => Effect.Effect<import("@yielded/auth/Identity").ProvisioningResult, IdentityConflict | IdentityUnavailable>;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
export declare const makePgExternalIdentityServices: <Subject extends AnyPgTable, External extends AnyPgTable, NativeId>(database: Database, mapping: ExternalIdentityTables<Subject, External, NativeId>) => {
|
|
75
|
+
readonly externalIdentityMutation: {
|
|
76
|
+
readonly bind: (subjectId: SubjectId, identity: ExternalIdentity) => Effect.Effect<void, IdentityConflict | IdentityUnavailable>;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
//# sourceMappingURL=pg.d.mts.map
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { PersistenceMappingError, column, isMappedConstraintConflict, provisioningFingerprint, requireStandaloneConsume, updateValues } from "./model.mjs";
|
|
2
|
+
import { AuthStore, EmailOtpRejected } from "@yielded/auth/AuthStore";
|
|
3
|
+
import { AuthRateLimited, AuthStoreError, InvalidRegistration } from "@yielded/auth/Errors";
|
|
4
|
+
import { ExternalIdentityMutation, IdentityConflict, IdentityUnavailable, SubjectProvisioned, SubjectProvisioner } from "@yielded/auth/Identity";
|
|
5
|
+
import { InvalidOAuthState, OAuthStateDecisions, OAuthStateStore } from "@yielded/auth/OAuth";
|
|
6
|
+
import { VerifiedEmail } from "@yielded/auth/Schema";
|
|
7
|
+
import { and, eq, gt, lt, lte, ne, or, sql } from "drizzle-orm";
|
|
8
|
+
import { Cause, Context, DateTime, Duration, Effect, Schema } from "effect";
|
|
9
|
+
import { AuthStoreDecisions, reportPersistenceFailure } from "@yielded/auth/Persistence";
|
|
10
|
+
import "drizzle-orm/pg-core";
|
|
11
|
+
//#region src/drizzle/pg.ts
|
|
12
|
+
const storeReadError = () => AuthStoreError.make({ message: "Auth store read failed" });
|
|
13
|
+
const storeWriteError = () => AuthStoreError.make({ message: "Auth store write failed" });
|
|
14
|
+
const isStoreFailure = Schema.is(AuthStoreError);
|
|
15
|
+
const mapStoreFailure = (failure) => (effect) => reportPersistenceFailure(effect, isStoreFailure).pipe(Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, failure))));
|
|
16
|
+
const mapStoreReadFailure = mapStoreFailure(storeReadError);
|
|
17
|
+
const mapStoreWriteFailure = mapStoreFailure(storeWriteError);
|
|
18
|
+
const identityUnavailable = () => IdentityUnavailable.make();
|
|
19
|
+
const isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));
|
|
20
|
+
const mapIdentityFailure = (effect) => reportPersistenceFailure(effect, isIdentityFailure).pipe(Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, (error) => isIdentityFailure(error) ? error : identityUnavailable()))));
|
|
21
|
+
const selected = (row) => row;
|
|
22
|
+
const makePgAuthStoreServices = (database, mapping) => {
|
|
23
|
+
const db = database;
|
|
24
|
+
const challengeTable = mapping.challenge.table;
|
|
25
|
+
const challengeColumns = mapping.challenge.columns;
|
|
26
|
+
const pgChallenge = {
|
|
27
|
+
challengeId: column(challengeTable, challengeColumns.challengeId),
|
|
28
|
+
tokenDigest: column(challengeTable, challengeColumns.tokenDigest),
|
|
29
|
+
namespace: column(challengeTable, challengeColumns.namespace),
|
|
30
|
+
value: column(challengeTable, challengeColumns.value),
|
|
31
|
+
purpose: column(challengeTable, challengeColumns.purpose),
|
|
32
|
+
otpKeyId: column(challengeTable, challengeColumns.otpKeyId),
|
|
33
|
+
otpDigest: column(challengeTable, challengeColumns.otpDigest),
|
|
34
|
+
issuedAt: column(challengeTable, challengeColumns.issuedAt),
|
|
35
|
+
expiresAt: column(challengeTable, challengeColumns.expiresAt),
|
|
36
|
+
attemptLimit: column(challengeTable, challengeColumns.attemptLimit),
|
|
37
|
+
failedAttempts: column(challengeTable, challengeColumns.failedAttempts),
|
|
38
|
+
consumed: column(challengeTable, challengeColumns.consumed)
|
|
39
|
+
};
|
|
40
|
+
const registrationTable = mapping.registration.table;
|
|
41
|
+
const registrationColumns = mapping.registration.columns;
|
|
42
|
+
const registration = {
|
|
43
|
+
tokenDigest: column(registrationTable, registrationColumns.tokenDigest),
|
|
44
|
+
expiresAt: column(registrationTable, registrationColumns.expiresAt),
|
|
45
|
+
consumed: column(registrationTable, registrationColumns.consumed)
|
|
46
|
+
};
|
|
47
|
+
const issueChallenge = Effect.fn("DrizzlePgAuthStore.issueChallenge")(function* (input) {
|
|
48
|
+
const now = yield* DateTime.now;
|
|
49
|
+
const cooldownCutoff = DateTime.mapEpochMillis(now, (millis) => millis - Duration.toMillis(input.resendCooldown));
|
|
50
|
+
if ((yield* Effect.suspend(() => {
|
|
51
|
+
const values = mapping.challenge.encodeInsert(input, {
|
|
52
|
+
namespace: mapping.challenge.identifierNamespace,
|
|
53
|
+
failedAttempts: 0,
|
|
54
|
+
consumed: false
|
|
55
|
+
});
|
|
56
|
+
const nativeNow = mapping.challenge.encodeInstant(now);
|
|
57
|
+
const nativeCutoff = mapping.challenge.encodeInstant(cooldownCutoff);
|
|
58
|
+
const nativeIssuedAt = mapping.challenge.encodeInstant(input.issuedAt);
|
|
59
|
+
const preservedAttempts = sql`case when ${gt(pgChallenge.expiresAt, nativeNow)} then ${pgChallenge.failedAttempts} else 0 end`;
|
|
60
|
+
const update = mapping.challenge.encodeUpdate(input, {
|
|
61
|
+
namespace: mapping.challenge.identifierNamespace,
|
|
62
|
+
failedAttempts: preservedAttempts,
|
|
63
|
+
consumed: false
|
|
64
|
+
});
|
|
65
|
+
return db.insert(challengeTable).values(values).onConflictDoUpdate({
|
|
66
|
+
target: [
|
|
67
|
+
pgChallenge.namespace,
|
|
68
|
+
pgChallenge.value,
|
|
69
|
+
pgChallenge.purpose
|
|
70
|
+
],
|
|
71
|
+
set: update,
|
|
72
|
+
setWhere: and(ne(pgChallenge.challengeId, input.challengeId), lt(pgChallenge.issuedAt, nativeIssuedAt), or(eq(pgChallenge.consumed, true), lte(pgChallenge.issuedAt, nativeCutoff)))
|
|
73
|
+
}).returning();
|
|
74
|
+
}).pipe(mapStoreWriteFailure)).length > 0) return;
|
|
75
|
+
const existing = yield* Effect.suspend(() => db.select().from(challengeTable).where(and(eq(pgChallenge.namespace, mapping.challenge.identifierNamespace), eq(pgChallenge.value, input.email), eq(pgChallenge.purpose, input.purpose))).limit(1)).pipe(mapStoreReadFailure);
|
|
76
|
+
const decoded = existing[0] === void 0 ? void 0 : yield* Effect.suspend(() => mapping.challenge.decode(selected(existing[0]))).pipe(mapStoreReadFailure);
|
|
77
|
+
const retryAfterSeconds = decoded === void 0 ? Math.max(1, Math.ceil(Duration.toMillis(input.resendCooldown) / 1e3)) : Math.max(1, Math.ceil((DateTime.toEpochMillis(decoded.challenge.issuedAt) + Duration.toMillis(input.resendCooldown) - DateTime.toEpochMillis(now)) / 1e3));
|
|
78
|
+
return yield* AuthRateLimited.make({ retryAfterSeconds });
|
|
79
|
+
});
|
|
80
|
+
const consumeChallengeDecision = Effect.fn("DrizzlePgAuthStore.consumeChallengeDecision")(function* (input) {
|
|
81
|
+
const now = yield* DateTime.now;
|
|
82
|
+
const alternatives = Object.entries(input.otpDigests).map(([keyId, digest]) => and(eq(pgChallenge.otpKeyId, keyId), eq(pgChallenge.otpDigest, digest)));
|
|
83
|
+
const matches = alternatives.length === 0 ? sql`false` : or(...alternatives);
|
|
84
|
+
const rows = yield* Effect.suspend(() => db.update(challengeTable).set(updateValues([[challengeColumns.consumed, sql`case when ${matches} then true else ${pgChallenge.consumed} end`], [challengeColumns.failedAttempts, sql`${pgChallenge.failedAttempts} + case when ${matches} then 0 else 1 end`]])).where(and(eq(pgChallenge.tokenDigest, input.tokenDigest), eq(pgChallenge.consumed, false), gt(pgChallenge.expiresAt, mapping.challenge.encodeInstant(now)), sql`${pgChallenge.failedAttempts} < ${pgChallenge.attemptLimit}`)).returning()).pipe(mapStoreWriteFailure);
|
|
85
|
+
if (rows[0] === void 0) return {
|
|
86
|
+
_tag: "rejected",
|
|
87
|
+
reason: "missing_challenge"
|
|
88
|
+
};
|
|
89
|
+
const decoded = yield* Effect.suspend(() => mapping.challenge.decode(selected(rows[0]))).pipe(mapStoreReadFailure);
|
|
90
|
+
if (!decoded.consumed) return {
|
|
91
|
+
_tag: "rejected",
|
|
92
|
+
reason: "bad_code"
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
_tag: "accepted",
|
|
96
|
+
value: VerifiedEmail.make({
|
|
97
|
+
email: decoded.challenge.email,
|
|
98
|
+
purpose: decoded.challenge.purpose
|
|
99
|
+
})
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
const consumeChallenge = Effect.fn("DrizzlePgAuthStore.consumeChallenge")(function* (input) {
|
|
103
|
+
yield* requireStandaloneConsume(db);
|
|
104
|
+
const decision = yield* consumeChallengeDecision(input);
|
|
105
|
+
return decision._tag === "accepted" ? decision.value : yield* EmailOtpRejected.make({ reason: decision.reason });
|
|
106
|
+
});
|
|
107
|
+
const issueRegistration = Effect.fn("DrizzlePgAuthStore.issueRegistration")(function* (input) {
|
|
108
|
+
yield* Effect.suspend(() => db.insert(registrationTable).values(mapping.registration.encodeInsert(input, false))).pipe(mapStoreWriteFailure);
|
|
109
|
+
});
|
|
110
|
+
const inspectRegistration = Effect.fn("DrizzlePgAuthStore.inspectRegistration")(function* (tokenDigest) {
|
|
111
|
+
const now = yield* DateTime.now;
|
|
112
|
+
const rows = yield* Effect.suspend(() => db.select().from(registrationTable).where(and(eq(registration.tokenDigest, tokenDigest), eq(registration.consumed, false), gt(registration.expiresAt, mapping.registration.encodeInstant(now)))).limit(1)).pipe(mapStoreReadFailure);
|
|
113
|
+
if (rows[0] === void 0) return yield* InvalidRegistration.make();
|
|
114
|
+
return (yield* Effect.suspend(() => mapping.registration.decode(selected(rows[0]))).pipe(mapStoreReadFailure)).registration;
|
|
115
|
+
});
|
|
116
|
+
const consumeRegistrationDecision = Effect.fn("DrizzlePgAuthStore.consumeRegistrationDecision")(function* (input) {
|
|
117
|
+
const now = yield* DateTime.now;
|
|
118
|
+
return (yield* Effect.suspend(() => db.update(registrationTable).set(updateValues([[registrationColumns.consumed, true]])).where(and(eq(registration.tokenDigest, input.tokenDigest), eq(registration.consumed, false), gt(registration.expiresAt, mapping.registration.encodeInstant(now)))).returning({ consumed: registration.consumed })).pipe(mapStoreWriteFailure)).length === 0 ? { _tag: "rejected" } : {
|
|
119
|
+
_tag: "accepted",
|
|
120
|
+
value: void 0
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
const consumeRegistration = Effect.fn("DrizzlePgAuthStore.consumeRegistration")(function* (input) {
|
|
124
|
+
yield* requireStandaloneConsume(db);
|
|
125
|
+
if ((yield* consumeRegistrationDecision(input))._tag === "rejected") return yield* InvalidRegistration.make();
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
authStore: AuthStore.of({
|
|
129
|
+
issueChallenge,
|
|
130
|
+
consumeChallenge,
|
|
131
|
+
issueRegistration,
|
|
132
|
+
inspectRegistration,
|
|
133
|
+
consumeRegistration
|
|
134
|
+
}),
|
|
135
|
+
decisions: {
|
|
136
|
+
consumeChallenge: consumeChallengeDecision,
|
|
137
|
+
consumeRegistration: consumeRegistrationDecision
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
const makePgOAuthStateServices = (database, mapping) => {
|
|
142
|
+
const db = database;
|
|
143
|
+
const stateTable = mapping.oauthState.table;
|
|
144
|
+
const stateColumns = mapping.oauthState.columns;
|
|
145
|
+
const state = {
|
|
146
|
+
stateDigest: column(stateTable, stateColumns.stateDigest),
|
|
147
|
+
expiresAt: column(stateTable, stateColumns.expiresAt),
|
|
148
|
+
consumed: column(stateTable, stateColumns.consumed)
|
|
149
|
+
};
|
|
150
|
+
const issue = Effect.fn("DrizzlePgOAuthStateStore.issue")(function* (input) {
|
|
151
|
+
yield* Effect.suspend(() => db.insert(stateTable).values(mapping.oauthState.encodeInsert(input, false))).pipe(mapStoreWriteFailure);
|
|
152
|
+
});
|
|
153
|
+
const consumeDecision = Effect.fn("DrizzlePgOAuthStateStore.consumeDecision")(function* (digest) {
|
|
154
|
+
const now = yield* DateTime.now;
|
|
155
|
+
const rows = yield* Effect.suspend(() => db.update(stateTable).set(updateValues([[stateColumns.consumed, true]])).where(and(eq(state.stateDigest, digest), eq(state.consumed, false), gt(state.expiresAt, mapping.oauthState.encodeInstant(now)))).returning()).pipe(mapStoreWriteFailure);
|
|
156
|
+
if (rows[0] === void 0) return { _tag: "rejected" };
|
|
157
|
+
return {
|
|
158
|
+
_tag: "accepted",
|
|
159
|
+
value: (yield* Effect.suspend(() => mapping.oauthState.decode(selected(rows[0]))).pipe(mapStoreReadFailure)).state
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
const consume = Effect.fn("DrizzlePgOAuthStateStore.consume")(function* (digest) {
|
|
163
|
+
yield* requireStandaloneConsume(db);
|
|
164
|
+
const decision = yield* consumeDecision(digest);
|
|
165
|
+
return decision._tag === "accepted" ? decision.value : yield* InvalidOAuthState.make();
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
oauthStateStore: OAuthStateStore.of({
|
|
169
|
+
issue,
|
|
170
|
+
consume
|
|
171
|
+
}),
|
|
172
|
+
decisions: { consumeOAuthState: consumeDecision }
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
const makePgAuthServices = (database, mapping) => {
|
|
176
|
+
const auth = makePgAuthStoreServices(database, mapping);
|
|
177
|
+
const oauth = makePgOAuthStateServices(database, mapping);
|
|
178
|
+
return {
|
|
179
|
+
...auth,
|
|
180
|
+
...oauth,
|
|
181
|
+
decisions: {
|
|
182
|
+
...auth.decisions,
|
|
183
|
+
...oauth.decisions
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
function coordinatePgAuthStoreTransaction(acquire, options, body) {
|
|
188
|
+
return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
|
|
189
|
+
const decisions = makePgAuthStoreServices(transaction, options.mapping).decisions;
|
|
190
|
+
const provided = Context.make(AuthStoreDecisions, decisions);
|
|
191
|
+
const work = Effect.provideContext(body, provided);
|
|
192
|
+
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
function coordinatePgOAuthStateTransaction(acquire, options, body) {
|
|
196
|
+
return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
|
|
197
|
+
const decisions = makePgOAuthStateServices(transaction, options.mapping).decisions;
|
|
198
|
+
const provided = Context.make(OAuthStateDecisions, decisions);
|
|
199
|
+
const work = Effect.provideContext(body, provided);
|
|
200
|
+
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
function coordinatePgAuthTransaction(acquire, options, body) {
|
|
204
|
+
return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
|
|
205
|
+
const decisions = makePgAuthServices(transaction, options.mapping).decisions;
|
|
206
|
+
const provided = Context.make(AuthStoreDecisions, decisions).pipe(Context.add(OAuthStateDecisions, decisions));
|
|
207
|
+
const work = Effect.provideContext(body, provided);
|
|
208
|
+
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
const makePgSubjectProvisioningServices = (database, mapping) => {
|
|
212
|
+
const db = database;
|
|
213
|
+
const requestTable = mapping.provisioningRequest.table;
|
|
214
|
+
const requestIdColumn = column(requestTable, mapping.provisioningRequest.requestId);
|
|
215
|
+
const requestFingerprintColumn = column(requestTable, mapping.provisioningRequest.fingerprint);
|
|
216
|
+
const requestSubjectColumn = column(requestTable, mapping.provisioningRequest.subjectId);
|
|
217
|
+
const identifierTable = mapping.identifier.table;
|
|
218
|
+
const identifierNamespaceColumn = column(identifierTable, mapping.identifier.namespace);
|
|
219
|
+
const identifierValueColumn = column(identifierTable, mapping.identifier.value);
|
|
220
|
+
const findReceipt = Effect.fn("DrizzlePgIdentity.findReceipt")(function* (requestId) {
|
|
221
|
+
return (yield* db.select({
|
|
222
|
+
fingerprint: requestFingerprintColumn,
|
|
223
|
+
subjectId: requestSubjectColumn
|
|
224
|
+
}).from(requestTable).where(eq(requestIdColumn, requestId)).limit(1))[0];
|
|
225
|
+
});
|
|
226
|
+
const provision = Effect.fn("DrizzlePgIdentity.provision")(function* (input) {
|
|
227
|
+
const fingerprint = provisioningFingerprint(input);
|
|
228
|
+
const existing = yield* findReceipt(input.requestId);
|
|
229
|
+
if (existing !== void 0) {
|
|
230
|
+
if (existing.fingerprint !== fingerprint) return yield* IdentityConflict.make();
|
|
231
|
+
const id = yield* mapping.subjectId.toSubject(existing.subjectId);
|
|
232
|
+
return SubjectProvisioned.make({ subjectId: id });
|
|
233
|
+
}
|
|
234
|
+
const nativeId = yield* db.transaction((tx) => Effect.gen(function* () {
|
|
235
|
+
const allocated = mapping.subject.allocateId === void 0 ? void 0 : yield* mapping.subject.allocateId;
|
|
236
|
+
const nativeId = (yield* tx.insert(mapping.subject.table).values(mapping.subject.encodeInsert(input, allocated)).returning({ id: column(mapping.subject.table, mapping.subject.id) }))[0]?.id ?? allocated;
|
|
237
|
+
if (nativeId === void 0) return yield* PersistenceMappingError.make({
|
|
238
|
+
operation: "provisionSubject.generatedId",
|
|
239
|
+
cause: /* @__PURE__ */ new Error("subject insert did not return its native id")
|
|
240
|
+
});
|
|
241
|
+
if (input.identifier !== void 0) yield* tx.insert(identifierTable).values(mapping.identifier.encodeInsert(input.identifier, nativeId, input.verifiedAt));
|
|
242
|
+
yield* tx.insert(requestTable).values(mapping.provisioningRequest.encodeInsert(input.requestId, fingerprint, nativeId));
|
|
243
|
+
return nativeId;
|
|
244
|
+
})).pipe(Effect.catchCause((cause) => {
|
|
245
|
+
if (cause.reasons.length === 0 || !cause.reasons.every((reason) => Cause.isFailReason(reason) && isMappedConstraintConflict(mapping.isConstraintConflict, reason.error))) return Effect.failCause(cause);
|
|
246
|
+
return findReceipt(input.requestId).pipe(Effect.flatMap((receipt) => {
|
|
247
|
+
if (receipt !== void 0 && receipt.fingerprint === fingerprint) return Effect.succeed(receipt.subjectId);
|
|
248
|
+
if (input.identifier === void 0) return IdentityConflict.make();
|
|
249
|
+
return db.select({ subjectId: column(identifierTable, mapping.identifier.subjectId) }).from(identifierTable).where(and(eq(identifierNamespaceColumn, input.identifier.namespace), eq(identifierValueColumn, input.identifier.value))).limit(1).pipe(Effect.flatMap(() => IdentityConflict.make()));
|
|
250
|
+
}));
|
|
251
|
+
}));
|
|
252
|
+
const subjectId = yield* mapping.subjectId.toSubject(nativeId);
|
|
253
|
+
return SubjectProvisioned.make({ subjectId });
|
|
254
|
+
}, mapIdentityFailure);
|
|
255
|
+
return { subjectProvisioner: SubjectProvisioner.of({ provision }) };
|
|
256
|
+
};
|
|
257
|
+
const makePgExternalIdentityServices = (database, mapping) => {
|
|
258
|
+
const db = database;
|
|
259
|
+
const externalTable = mapping.externalIdentity.table;
|
|
260
|
+
const externalProviderColumn = column(externalTable, mapping.externalIdentity.provider);
|
|
261
|
+
const externalIssuerColumn = column(externalTable, mapping.externalIdentity.issuer);
|
|
262
|
+
const externalSubjectColumn = column(externalTable, mapping.externalIdentity.subject);
|
|
263
|
+
const externalSubjectIdColumn = column(externalTable, mapping.externalIdentity.subjectId);
|
|
264
|
+
const subjectIdColumn = column(mapping.subject.table, mapping.subject.id);
|
|
265
|
+
const subjectStatusColumn = column(mapping.subject.table, mapping.subject.status);
|
|
266
|
+
const bind = Effect.fn("DrizzlePgIdentity.bindExternalIdentity")(function* (subjectId, identity) {
|
|
267
|
+
const nativeId = yield* mapping.subjectId.toNative(subjectId);
|
|
268
|
+
if ((yield* db.transaction((tx) => Effect.gen(function* () {
|
|
269
|
+
const subjects = yield* tx.select({ status: subjectStatusColumn }).from(mapping.subject.table).where(eq(subjectIdColumn, nativeId)).for("update").limit(1);
|
|
270
|
+
if (subjects[0] === void 0 || !mapping.subject.isActiveStatus(subjects[0].status)) return { _tag: "conflict" };
|
|
271
|
+
const links = yield* tx.select({ subjectId: externalSubjectIdColumn }).from(externalTable).where(and(eq(externalProviderColumn, identity.provider), eq(externalIssuerColumn, identity.issuer), eq(externalSubjectColumn, identity.subject))).for("update").limit(1);
|
|
272
|
+
if (links[0] !== void 0) return mapping.subjectId.equals(links[0].subjectId, nativeId) ? { _tag: "bound" } : { _tag: "conflict" };
|
|
273
|
+
yield* tx.insert(externalTable).values(mapping.externalIdentity.encodeInsert(identity, nativeId));
|
|
274
|
+
return { _tag: "bound" };
|
|
275
|
+
})).pipe(Effect.catchCause((cause) => {
|
|
276
|
+
if (cause.reasons.length === 0 || !cause.reasons.every((reason) => Cause.isFailReason(reason) && isMappedConstraintConflict(mapping.isConstraintConflict, reason.error))) return Effect.failCause(cause);
|
|
277
|
+
return db.select({ subjectId: externalSubjectIdColumn }).from(externalTable).where(and(eq(externalProviderColumn, identity.provider), eq(externalIssuerColumn, identity.issuer), eq(externalSubjectColumn, identity.subject))).limit(1).pipe(Effect.map((rows) => rows[0] !== void 0 && mapping.subjectId.equals(rows[0].subjectId, nativeId) ? { _tag: "bound" } : { _tag: "conflict" }));
|
|
278
|
+
})))._tag === "conflict") return yield* IdentityConflict.make();
|
|
279
|
+
}, mapIdentityFailure);
|
|
280
|
+
return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) };
|
|
281
|
+
};
|
|
282
|
+
const makePgIdentityServices = (database, mapping) => ({
|
|
283
|
+
...makePgSubjectProvisioningServices(database, mapping),
|
|
284
|
+
...makePgExternalIdentityServices(database, mapping)
|
|
285
|
+
});
|
|
286
|
+
//#endregion
|
|
287
|
+
export { coordinatePgAuthStoreTransaction, coordinatePgAuthTransaction, coordinatePgOAuthStateTransaction, makePgAuthServices, makePgAuthStoreServices, makePgExternalIdentityServices, makePgIdentityServices, makePgOAuthStateServices, makePgSubjectProvisioningServices };
|
|
288
|
+
|
|
289
|
+
//# sourceMappingURL=pg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.mjs","names":[],"sources":["../../src/drizzle/pg.ts"],"sourcesContent":["import { AuthStore, EmailOtpRejected } from \"@yielded/auth/AuthStore\";\nimport { AuthRateLimited, AuthStoreError, InvalidRegistration } from \"@yielded/auth/Errors\";\nimport {\n ExternalIdentityMutation,\n IdentityConflict,\n IdentityUnavailable,\n SubjectProvisioned,\n type ExternalIdentity,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n} from \"@yielded/auth/Identity\";\nimport {\n InvalidOAuthState,\n OAuthStateDecisions,\n OAuthStateStore,\n type OAuthState,\n} from \"@yielded/auth/OAuth\";\nimport { AuthStoreDecisions, reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport {\n VerifiedEmail,\n type ConsumeChallenge,\n type ConsumeRegistration,\n type NewChallenge,\n type NewRegistration,\n type SubjectId,\n type TokenDigest,\n} from \"@yielded/auth/Schema\";\n/* oxlint-disable no-explicit-any -- Drizzle's generic query builders lose the concrete consumer table through a runtime column map. Assertions stay in this adapter. */\nimport {\n and,\n eq,\n gt,\n lt,\n lte,\n ne,\n or,\n sql,\n type AnyRelations,\n type InferSelectModel,\n} from \"drizzle-orm\";\nimport type { EffectPgDatabase as PgliteDatabase } from \"drizzle-orm/effect-pglite\";\nimport type { EffectPgDatabase as PgDatabase } from \"drizzle-orm/effect-postgres\";\nimport { type AnyPgTable, type PgColumn } from \"drizzle-orm/pg-core\";\nimport { Cause, Context, DateTime, Duration, Effect, Layer, Schema } from \"effect\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport {\n column,\n PersistenceMappingError,\n isMappedConstraintConflict,\n provisioningFingerprint,\n requireStandaloneConsume,\n updateValues,\n type AuthTables,\n type AuthStoreTables,\n type ChallengeConsumeDecision,\n type ConsumeDecision,\n type ExternalIdentityTables,\n type IdentityTables,\n type OAuthStateTables,\n type SubjectProvisioningTables,\n} from \"./model\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = PgDatabase<AnyRelations> | PgliteDatabase<AnyRelations>;\ntype RuntimeDatabase = PgDatabase<any> & Parameters<typeof requireStandaloneConsume>[0];\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nconst storeReadError = () => AuthStoreError.make({ message: \"Auth store read failed\" });\nconst storeWriteError = () => AuthStoreError.make({ message: \"Auth store write failed\" });\nconst isStoreFailure = Schema.is(AuthStoreError);\n\nconst mapStoreFailure =\n (failure: () => AuthStoreError) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, AuthStoreError, R> =>\n reportPersistenceFailure(effect, isStoreFailure).pipe(\n Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, failure))),\n );\n\nconst mapStoreReadFailure = mapStoreFailure(storeReadError);\nconst mapStoreWriteFailure = mapStoreFailure(storeWriteError);\nconst identityUnavailable = () => IdentityUnavailable.make();\nconst isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));\n\nconst mapIdentityFailure = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n reportPersistenceFailure(effect, isIdentityFailure).pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) => (isIdentityFailure(error) ? error : identityUnavailable())),\n ),\n ),\n );\n\nconst selected = <T extends AnyPgTable>(row: unknown): InferSelectModel<T> =>\n row as InferSelectModel<T>;\n\nexport const makePgAuthStoreServices = <C extends AnyPgTable, R extends AnyPgTable>(\n database: Database,\n mapping: AuthStoreTables<C, R>,\n) => {\n const db = database as RuntimeDatabase;\n const challengeTable = mapping.challenge.table;\n const challengeColumns = mapping.challenge.columns;\n\n const challenge = {\n challengeId: column(challengeTable, challengeColumns.challengeId),\n tokenDigest: column(challengeTable, challengeColumns.tokenDigest),\n namespace: column(challengeTable, challengeColumns.namespace),\n value: column(challengeTable, challengeColumns.value),\n purpose: column(challengeTable, challengeColumns.purpose),\n otpKeyId: column(challengeTable, challengeColumns.otpKeyId),\n otpDigest: column(challengeTable, challengeColumns.otpDigest),\n issuedAt: column(challengeTable, challengeColumns.issuedAt),\n expiresAt: column(challengeTable, challengeColumns.expiresAt),\n attemptLimit: column(challengeTable, challengeColumns.attemptLimit),\n failedAttempts: column(challengeTable, challengeColumns.failedAttempts),\n consumed: column(challengeTable, challengeColumns.consumed),\n } as const;\n\n const pgChallenge = challenge as Record<keyof typeof challenge, PgColumn>;\n const registrationTable = mapping.registration.table;\n const registrationColumns = mapping.registration.columns;\n\n const registration = {\n tokenDigest: column(registrationTable, registrationColumns.tokenDigest),\n expiresAt: column(registrationTable, registrationColumns.expiresAt),\n consumed: column(registrationTable, registrationColumns.consumed),\n } as const;\n\n const issueChallenge = Effect.fn(\"DrizzlePgAuthStore.issueChallenge\")(function* (\n input: NewChallenge,\n ) {\n const now = yield* DateTime.now;\n\n const cooldownCutoff = DateTime.mapEpochMillis(\n now,\n (millis) => millis - Duration.toMillis(input.resendCooldown),\n );\n\n const rows = yield* Effect.suspend(() => {\n const values = mapping.challenge.encodeInsert(input, {\n namespace: mapping.challenge.identifierNamespace,\n failedAttempts: 0,\n consumed: false,\n });\n\n const nativeNow = mapping.challenge.encodeInstant(now);\n const nativeCutoff = mapping.challenge.encodeInstant(cooldownCutoff);\n const nativeIssuedAt = mapping.challenge.encodeInstant(input.issuedAt);\n const preservedAttempts = sql`case when ${gt(pgChallenge.expiresAt, nativeNow)} then ${pgChallenge.failedAttempts} else 0 end`;\n\n const update = mapping.challenge.encodeUpdate(input, {\n namespace: mapping.challenge.identifierNamespace,\n failedAttempts: preservedAttempts as any,\n consumed: false,\n });\n\n return db\n .insert(challengeTable as any)\n .values(values as any)\n .onConflictDoUpdate({\n target: [pgChallenge.namespace, pgChallenge.value, pgChallenge.purpose],\n set: update as any,\n setWhere: and(\n ne(pgChallenge.challengeId, input.challengeId),\n lt(pgChallenge.issuedAt, nativeIssuedAt),\n or(eq(pgChallenge.consumed, true), lte(pgChallenge.issuedAt, nativeCutoff)),\n ),\n })\n .returning();\n }).pipe(mapStoreWriteFailure);\n\n if (rows.length > 0) return;\n\n const existing = yield* Effect.suspend(() =>\n db\n .select()\n .from(challengeTable as any)\n .where(\n and(\n eq(pgChallenge.namespace, mapping.challenge.identifierNamespace),\n eq(pgChallenge.value, input.email),\n eq(pgChallenge.purpose, input.purpose),\n ),\n )\n .limit(1),\n ).pipe(mapStoreReadFailure);\n\n const decoded =\n existing[0] === undefined\n ? undefined\n : yield* Effect.suspend(() => mapping.challenge.decode(selected<C>(existing[0]))).pipe(\n mapStoreReadFailure,\n );\n\n const retryAfterSeconds =\n decoded === undefined\n ? Math.max(1, Math.ceil(Duration.toMillis(input.resendCooldown) / 1000))\n : Math.max(\n 1,\n Math.ceil(\n (DateTime.toEpochMillis(decoded.challenge.issuedAt) +\n Duration.toMillis(input.resendCooldown) -\n DateTime.toEpochMillis(now)) /\n 1000,\n ),\n );\n\n return yield* AuthRateLimited.make({ retryAfterSeconds });\n });\n\n const consumeChallengeDecision = Effect.fn(\"DrizzlePgAuthStore.consumeChallengeDecision\")(\n function* (\n input: ConsumeChallenge,\n ): Effect.fn.Return<ChallengeConsumeDecision, AuthStoreError> {\n const now = yield* DateTime.now;\n\n const alternatives = Object.entries(input.otpDigests).map(([keyId, digest]) =>\n and(eq(pgChallenge.otpKeyId, keyId), eq(pgChallenge.otpDigest, digest)),\n );\n\n const matches = alternatives.length === 0 ? sql<boolean>`false` : or(...alternatives)!;\n\n const rows = yield* Effect.suspend(() =>\n db\n .update(challengeTable as any)\n .set(\n updateValues<C>([\n [\n challengeColumns.consumed,\n sql`case when ${matches} then true else ${pgChallenge.consumed} end`,\n ],\n [\n challengeColumns.failedAttempts,\n sql`${pgChallenge.failedAttempts} + case when ${matches} then 0 else 1 end`,\n ],\n ]) as any,\n )\n .where(\n and(\n eq(pgChallenge.tokenDigest, input.tokenDigest),\n eq(pgChallenge.consumed, false),\n gt(pgChallenge.expiresAt, mapping.challenge.encodeInstant(now)),\n sql`${pgChallenge.failedAttempts} < ${pgChallenge.attemptLimit}`,\n ),\n )\n .returning(),\n ).pipe(mapStoreWriteFailure);\n\n if (rows[0] === undefined) {\n return { _tag: \"rejected\", reason: \"missing_challenge\" };\n }\n\n const decoded = yield* Effect.suspend(() =>\n mapping.challenge.decode(selected<C>(rows[0])),\n ).pipe(mapStoreReadFailure);\n\n if (!decoded.consumed) return { _tag: \"rejected\", reason: \"bad_code\" };\n\n return {\n _tag: \"accepted\",\n value: VerifiedEmail.make({\n email: decoded.challenge.email,\n purpose: decoded.challenge.purpose,\n }),\n };\n },\n );\n\n const consumeChallenge = Effect.fn(\"DrizzlePgAuthStore.consumeChallenge\")(function* (\n input: ConsumeChallenge,\n ) {\n yield* requireStandaloneConsume(db);\n const decision = yield* consumeChallengeDecision(input);\n\n return decision._tag === \"accepted\"\n ? decision.value\n : yield* EmailOtpRejected.make({ reason: decision.reason });\n });\n\n const issueRegistration = Effect.fn(\"DrizzlePgAuthStore.issueRegistration\")(function* (\n input: NewRegistration,\n ) {\n yield* Effect.suspend(() =>\n db\n .insert(registrationTable as any)\n .values(mapping.registration.encodeInsert(input, false) as any),\n ).pipe(mapStoreWriteFailure);\n });\n\n const inspectRegistration = Effect.fn(\"DrizzlePgAuthStore.inspectRegistration\")(function* (\n tokenDigest: TokenDigest,\n ) {\n const now = yield* DateTime.now;\n\n const rows = yield* Effect.suspend(() =>\n db\n .select()\n .from(registrationTable as any)\n .where(\n and(\n eq(registration.tokenDigest, tokenDigest),\n eq(registration.consumed, false),\n gt(registration.expiresAt, mapping.registration.encodeInstant(now)),\n ),\n )\n .limit(1),\n ).pipe(mapStoreReadFailure);\n\n if (rows[0] === undefined) return yield* InvalidRegistration.make();\n\n const decoded = yield* Effect.suspend(() =>\n mapping.registration.decode(selected<R>(rows[0])),\n ).pipe(mapStoreReadFailure);\n\n return decoded.registration;\n });\n\n const consumeRegistrationDecision = Effect.fn(\"DrizzlePgAuthStore.consumeRegistrationDecision\")(\n function* (\n input: ConsumeRegistration,\n ): Effect.fn.Return<ConsumeDecision<void>, AuthStoreError> {\n const now = yield* DateTime.now;\n\n const rows = yield* Effect.suspend(() =>\n db\n .update(registrationTable as any)\n .set(updateValues<R>([[registrationColumns.consumed, true]]) as any)\n .where(\n and(\n eq(registration.tokenDigest, input.tokenDigest),\n eq(registration.consumed, false),\n gt(registration.expiresAt, mapping.registration.encodeInstant(now)),\n ),\n )\n .returning({ consumed: registration.consumed as PgColumn }),\n ).pipe(mapStoreWriteFailure);\n\n return rows.length === 0 ? { _tag: \"rejected\" } : { _tag: \"accepted\", value: undefined };\n },\n );\n\n const consumeRegistration = Effect.fn(\"DrizzlePgAuthStore.consumeRegistration\")(function* (\n input: ConsumeRegistration,\n ) {\n yield* requireStandaloneConsume(db);\n const decision = yield* consumeRegistrationDecision(input);\n\n if (decision._tag === \"rejected\") return yield* InvalidRegistration.make();\n });\n\n return {\n authStore: AuthStore.of({\n issueChallenge,\n consumeChallenge,\n issueRegistration,\n inspectRegistration,\n consumeRegistration,\n }),\n decisions: {\n consumeChallenge: consumeChallengeDecision,\n consumeRegistration: consumeRegistrationDecision,\n },\n } as const;\n};\n\nexport const makePgOAuthStateServices = <S extends AnyPgTable>(\n database: Database,\n mapping: OAuthStateTables<S>,\n) => {\n const db = database as RuntimeDatabase;\n const stateTable = mapping.oauthState.table;\n const stateColumns = mapping.oauthState.columns;\n\n const state = {\n stateDigest: column(stateTable, stateColumns.stateDigest),\n expiresAt: column(stateTable, stateColumns.expiresAt),\n consumed: column(stateTable, stateColumns.consumed),\n } as const;\n\n const issue = Effect.fn(\"DrizzlePgOAuthStateStore.issue\")(function* (input: OAuthState) {\n yield* Effect.suspend(() =>\n db.insert(stateTable as any).values(mapping.oauthState.encodeInsert(input, false) as any),\n ).pipe(mapStoreWriteFailure);\n });\n\n const consumeDecision = Effect.fn(\"DrizzlePgOAuthStateStore.consumeDecision\")(function* (\n digest: TokenDigest,\n ): Effect.fn.Return<ConsumeDecision<OAuthState>, AuthStoreError> {\n const now = yield* DateTime.now;\n\n const rows = yield* Effect.suspend(() =>\n db\n .update(stateTable as any)\n .set(updateValues<S>([[stateColumns.consumed, true]]) as any)\n .where(\n and(\n eq(state.stateDigest, digest),\n eq(state.consumed, false),\n gt(state.expiresAt, mapping.oauthState.encodeInstant(now)),\n ),\n )\n .returning(),\n ).pipe(mapStoreWriteFailure);\n\n if (rows[0] === undefined) return { _tag: \"rejected\" };\n\n const decoded = yield* Effect.suspend(() =>\n mapping.oauthState.decode(selected<S>(rows[0])),\n ).pipe(mapStoreReadFailure);\n\n return { _tag: \"accepted\", value: decoded.state };\n });\n\n const consume = Effect.fn(\"DrizzlePgOAuthStateStore.consume\")(function* (digest: TokenDigest) {\n yield* requireStandaloneConsume(db);\n const decision = yield* consumeDecision(digest);\n\n return decision._tag === \"accepted\" ? decision.value : yield* InvalidOAuthState.make();\n });\n\n return {\n oauthStateStore: OAuthStateStore.of({ issue, consume }),\n decisions: { consumeOAuthState: consumeDecision },\n } as const;\n};\n\nexport const makePgAuthServices = <\n C extends AnyPgTable,\n R extends AnyPgTable,\n S extends AnyPgTable,\n>(\n database: Database,\n mapping: AuthTables<C, R, S>,\n) => {\n const auth = makePgAuthStoreServices(database, mapping);\n const oauth = makePgOAuthStateServices(database, mapping);\n\n return { ...auth, ...oauth, decisions: { ...auth.decisions, ...oauth.decisions } } as const;\n};\n\n/**\n * Owns the native outer commit. Keep rejection as a decision value inside the\n * owner; interruption before commit rolls back. Retry an unknown commit outcome\n * only with the same stable request identity.\n */\nexport function coordinatePgAuthStoreTransaction<\n D extends Database,\n C extends AnyPgTable,\n R extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: AuthStoreTables<C, R>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions> | DatabaseRequirements\n>;\n\nexport function coordinatePgAuthStoreTransaction<\n D extends Database,\n C extends AnyPgTable,\n R extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthStoreTables<C, R>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinatePgAuthStoreTransaction<\n D extends Database,\n C extends AnyPgTable,\n R extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthStoreTables<C, R>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, AuthStoreDecisions>>((transaction) => {\n const decisions = makePgAuthStoreServices(transaction as never, options.mapping).decisions;\n const provided = Context.make(AuthStoreDecisions, decisions);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n }),\n );\n}\n\nexport function coordinatePgOAuthStateTransaction<\n D extends Database,\n S extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthStateTables<S>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, OAuthStateDecisions> | DatabaseRequirements\n>;\n\nexport function coordinatePgOAuthStateTransaction<\n D extends Database,\n S extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthStateTables<S>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, OAuthStateDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinatePgOAuthStateTransaction<\n D extends Database,\n S extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthStateTables<S>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, OAuthStateDecisions>>((transaction) => {\n const decisions = makePgOAuthStateServices(transaction as never, options.mapping).decisions;\n const provided = Context.make(OAuthStateDecisions, decisions);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n }),\n );\n}\n\nexport function coordinatePgAuthTransaction<\n D extends Database,\n C extends AnyPgTable,\n R extends AnyPgTable,\n S extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: AuthTables<C, R, S>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions> | DatabaseRequirements\n>;\n\nexport function coordinatePgAuthTransaction<\n D extends Database,\n C extends AnyPgTable,\n R extends AnyPgTable,\n S extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthTables<C, R, S>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinatePgAuthTransaction<\n D extends Database,\n C extends AnyPgTable,\n R extends AnyPgTable,\n S extends AnyPgTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthTables<C, R, S>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions>>(\n (transaction) => {\n const decisions = makePgAuthServices(transaction as never, options.mapping).decisions;\n\n const provided = Context.make(AuthStoreDecisions, decisions).pipe(\n Context.add(OAuthStateDecisions, decisions),\n );\n\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n },\n ),\n );\n}\n\nexport const makePgSubjectProvisioningServices = <\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(\n database: Database,\n mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>,\n) => {\n const db = database as RuntimeDatabase;\n const requestTable = mapping.provisioningRequest.table;\n const requestIdColumn = column(requestTable, mapping.provisioningRequest.requestId);\n const requestFingerprintColumn = column(requestTable, mapping.provisioningRequest.fingerprint);\n const requestSubjectColumn = column(requestTable, mapping.provisioningRequest.subjectId);\n const identifierTable = mapping.identifier.table;\n const identifierNamespaceColumn = column(identifierTable, mapping.identifier.namespace);\n const identifierValueColumn = column(identifierTable, mapping.identifier.value);\n\n const findReceipt = Effect.fn(\"DrizzlePgIdentity.findReceipt\")(function* (requestId: string) {\n const rows = yield* db\n .select({\n fingerprint: requestFingerprintColumn as PgColumn,\n subjectId: requestSubjectColumn as PgColumn,\n })\n .from(requestTable as any)\n .where(eq(requestIdColumn, requestId))\n .limit(1);\n\n return rows[0];\n });\n\n const provision = Effect.fn(\"DrizzlePgIdentity.provision\")(function* (\n input: SubjectProvisioningInput,\n ) {\n const fingerprint = provisioningFingerprint(input);\n const existing = yield* findReceipt(input.requestId);\n\n if (existing !== undefined) {\n if (existing.fingerprint !== fingerprint) return yield* IdentityConflict.make();\n const id = yield* mapping.subjectId.toSubject(existing.subjectId as NativeId);\n\n return SubjectProvisioned.make({ subjectId: id });\n }\n\n const attempt = db.transaction((tx) =>\n Effect.gen(function* () {\n const allocated =\n mapping.subject.allocateId === undefined ? undefined : yield* mapping.subject.allocateId;\n\n const inserted = yield* tx\n .insert(mapping.subject.table as any)\n .values(mapping.subject.encodeInsert(input, allocated) as any)\n .returning({ id: column(mapping.subject.table, mapping.subject.id) as PgColumn });\n\n const nativeId = (inserted[0]?.id ?? allocated) as NativeId | undefined;\n\n if (nativeId === undefined) {\n return yield* PersistenceMappingError.make({\n operation: \"provisionSubject.generatedId\",\n cause: new Error(\"subject insert did not return its native id\"),\n });\n }\n if (input.identifier !== undefined) {\n yield* tx\n .insert(identifierTable as any)\n .values(\n mapping.identifier.encodeInsert(input.identifier, nativeId, input.verifiedAt) as any,\n );\n }\n yield* tx\n .insert(requestTable as any)\n .values(\n mapping.provisioningRequest.encodeInsert(input.requestId, fingerprint, nativeId) as any,\n );\n\n return nativeId;\n }),\n );\n\n const nativeId = yield* attempt.pipe(\n Effect.catchCause(\n (\n cause,\n ): Effect.Effect<\n NativeId,\n | Effect.Error<typeof attempt>\n | Effect.Error<ReturnType<typeof findReceipt>>\n | IdentityConflict\n > => {\n if (\n cause.reasons.length === 0 ||\n !cause.reasons.every(\n (reason) =>\n Cause.isFailReason(reason) &&\n isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),\n )\n )\n return Effect.failCause(cause);\n\n return findReceipt(input.requestId).pipe(\n Effect.flatMap((receipt) => {\n if (receipt !== undefined && receipt.fingerprint === fingerprint) {\n return Effect.succeed(receipt.subjectId as NativeId);\n }\n if (input.identifier === undefined) return IdentityConflict.make();\n\n return db\n .select({\n subjectId: column(identifierTable, mapping.identifier.subjectId) as PgColumn,\n })\n .from(identifierTable as any)\n .where(\n and(\n eq(identifierNamespaceColumn, input.identifier.namespace),\n eq(identifierValueColumn, input.identifier.value),\n ),\n )\n .limit(1)\n .pipe(Effect.flatMap(() => IdentityConflict.make()));\n }),\n );\n },\n ),\n );\n\n const subjectId = yield* mapping.subjectId.toSubject(nativeId);\n\n return SubjectProvisioned.make({ subjectId });\n }, mapIdentityFailure);\n\n return {\n subjectProvisioner: SubjectProvisioner.of({ provision }),\n } as const;\n};\n\nexport const makePgExternalIdentityServices = <\n Subject extends AnyPgTable,\n External extends AnyPgTable,\n NativeId,\n>(\n database: Database,\n mapping: ExternalIdentityTables<Subject, External, NativeId>,\n) => {\n const db = database as RuntimeDatabase;\n const externalTable = mapping.externalIdentity.table;\n\n const externalProviderColumn = column(\n externalTable,\n mapping.externalIdentity.provider,\n ) as PgColumn;\n\n const externalIssuerColumn = column(externalTable, mapping.externalIdentity.issuer) as PgColumn;\n const externalSubjectColumn = column(externalTable, mapping.externalIdentity.subject) as PgColumn;\n\n const externalSubjectIdColumn = column(\n externalTable,\n mapping.externalIdentity.subjectId,\n ) as PgColumn;\n\n const subjectIdColumn = column(mapping.subject.table, mapping.subject.id) as PgColumn;\n const subjectStatusColumn = column(mapping.subject.table, mapping.subject.status) as PgColumn;\n\n const bind = Effect.fn(\"DrizzlePgIdentity.bindExternalIdentity\")(function* (\n subjectId: SubjectId,\n identity: ExternalIdentity,\n ) {\n const nativeId = yield* mapping.subjectId.toNative(subjectId);\n\n const decision = yield* db\n .transaction((tx) =>\n Effect.gen(function* () {\n const subjects = yield* tx\n .select({ status: subjectStatusColumn })\n .from(mapping.subject.table as any)\n .where(eq(subjectIdColumn, nativeId))\n .for(\"update\")\n .limit(1);\n\n if (subjects[0] === undefined || !mapping.subject.isActiveStatus(subjects[0].status))\n return { _tag: \"conflict\" } as const;\n\n const links = yield* tx\n .select({ subjectId: externalSubjectIdColumn })\n .from(externalTable as any)\n .where(\n and(\n eq(externalProviderColumn, identity.provider),\n eq(externalIssuerColumn, identity.issuer),\n eq(externalSubjectColumn, identity.subject),\n ),\n )\n .for(\"update\")\n .limit(1);\n\n if (links[0] !== undefined)\n return mapping.subjectId.equals(links[0].subjectId as NativeId, nativeId)\n ? ({ _tag: \"bound\" } as const)\n : ({ _tag: \"conflict\" } as const);\n yield* tx\n .insert(externalTable as any)\n .values(mapping.externalIdentity.encodeInsert(identity, nativeId) as any);\n\n return { _tag: \"bound\" } as const;\n }),\n )\n .pipe(\n Effect.catchCause((cause) => {\n if (\n cause.reasons.length === 0 ||\n !cause.reasons.every(\n (reason) =>\n Cause.isFailReason(reason) &&\n isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),\n )\n )\n return Effect.failCause(cause);\n\n return db\n .select({ subjectId: externalSubjectIdColumn })\n .from(externalTable as any)\n .where(\n and(\n eq(externalProviderColumn, identity.provider),\n eq(externalIssuerColumn, identity.issuer),\n eq(externalSubjectColumn, identity.subject),\n ),\n )\n .limit(1)\n .pipe(\n Effect.map((rows) =>\n rows[0] !== undefined &&\n mapping.subjectId.equals(rows[0].subjectId as NativeId, nativeId)\n ? ({ _tag: \"bound\" } as const)\n : ({ _tag: \"conflict\" } as const),\n ),\n );\n }),\n );\n\n if (decision._tag === \"conflict\") return yield* IdentityConflict.make();\n }, mapIdentityFailure);\n\n return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) } as const;\n};\n\nexport const makePgIdentityServices = <\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n External extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(\n database: Database,\n mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>,\n) => ({\n ...makePgSubjectProvisioningServices(database, mapping),\n ...makePgExternalIdentityServices(database, mapping),\n});\n\nexport const pgLayers = <\n Id,\n C extends AnyPgTable,\n R extends AnyPgTable,\n S extends AnyPgTable,\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n External extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(\n database: Context.Service<Id, Database>,\n auth: AuthTables<C, R, S>,\n identity: IdentityTables<Subject, Identifier, External, Request, NativeId>,\n) => ({\n identity: Layer.merge(\n Layer.effect(\n SubjectProvisioner,\n database.use((db) => Effect.succeed(makePgIdentityServices(db, identity).subjectProvisioner)),\n ),\n Layer.effect(\n ExternalIdentityMutation,\n database.use((db) =>\n Effect.succeed(makePgIdentityServices(db, identity).externalIdentityMutation),\n ),\n ),\n ),\n authStore: Layer.effect(\n AuthStore,\n database.use((db) => Effect.succeed(makePgAuthServices(db, auth).authStore)),\n ),\n oauthStateStore: Layer.effect(\n OAuthStateStore,\n database.use((db) => Effect.succeed(makePgAuthServices(db, auth).oauthStateStore)),\n ),\n});\n"],"mappings":"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"}
|