@yielded/auth-persistence-drizzle 0.1.0-beta.24 → 0.1.0-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/D1.d.mts +495 -1151
- package/dist/D1.mjs +41 -19
- package/dist/D1.mjs.map +1 -1
- package/dist/Libsql.d.mts +385 -1996
- package/dist/Libsql.mjs +43 -47
- package/dist/Libsql.mjs.map +1 -1
- package/dist/Mysql2.d.mts +397 -1743
- package/dist/Mysql2.mjs +35 -41
- package/dist/Mysql2.mjs.map +1 -1
- package/dist/Pglite.d.mts +397 -1743
- package/dist/Pglite.mjs +42 -31
- package/dist/Pglite.mjs.map +1 -1
- package/dist/Postgres.d.mts +397 -1743
- package/dist/Postgres.mjs +42 -31
- package/dist/Postgres.mjs.map +1 -1
- package/dist/SqliteBun.d.mts +385 -1992
- package/dist/SqliteBun.mjs +43 -43
- package/dist/SqliteBun.mjs.map +1 -1
- package/dist/SqliteDo.d.mts +385 -1991
- package/dist/SqliteDo.mjs +42 -41
- package/dist/SqliteDo.mjs.map +1 -1
- package/dist/SqliteNode.d.mts +385 -1992
- package/dist/SqliteNode.mjs +43 -43
- package/dist/SqliteNode.mjs.map +1 -1
- package/dist/SqliteWasm.d.mts +385 -1992
- package/dist/SqliteWasm.mjs +43 -43
- package/dist/SqliteWasm.mjs.map +1 -1
- package/dist/drizzle/d1-identity.mjs +2 -2
- package/dist/drizzle/d1-identity.mjs.map +1 -1
- package/dist/drizzle/driver-types.d.mts +15 -0
- package/dist/drizzle/email-drivers.mjs +32 -0
- package/dist/drizzle/email-drivers.mjs.map +1 -0
- package/dist/drizzle/email-model.d.mts +9 -13
- package/dist/drizzle/email-target.d.mts +10 -11
- package/dist/drizzle/email-target.mjs +33 -70
- package/dist/drizzle/email-target.mjs.map +1 -1
- package/dist/drizzle/model.d.mts +1 -10
- package/dist/drizzle/model.mjs +1 -2
- package/dist/drizzle/model.mjs.map +1 -1
- package/dist/drizzle/mysql-identity.mjs +3 -6
- package/dist/drizzle/mysql-identity.mjs.map +1 -1
- package/dist/drizzle/native-clock.d.mts +9 -0
- package/dist/drizzle/native-clock.mjs +18 -0
- package/dist/drizzle/native-clock.mjs.map +1 -0
- package/dist/drizzle/native-database.d.mts +46 -0
- package/dist/drizzle/native-database.mjs +6 -5
- package/dist/drizzle/native-database.mjs.map +1 -1
- package/dist/drizzle/native-sql-table.mjs +13 -5
- package/dist/drizzle/native-sql-table.mjs.map +1 -1
- package/dist/drizzle/native-target.d.mts +6 -0
- package/dist/drizzle/native-target.mjs +44 -0
- package/dist/drizzle/native-target.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-drivers.mjs +4 -56
- package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-model.d.mts +5 -22
- package/dist/drizzle/oauth-connected-model.mjs +1 -7
- package/dist/drizzle/oauth-connected-reference.d.mts +5 -7
- package/dist/drizzle/oauth-connected-reference.mjs +11 -3
- package/dist/drizzle/oauth-connected-reference.mjs.map +1 -1
- package/dist/drizzle/oauth-drivers.mjs +1 -2
- package/dist/drizzle/oauth-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-model.d.mts +11 -37
- package/dist/drizzle/oauth-model.mjs +3 -4
- package/dist/drizzle/oauth-model.mjs.map +1 -1
- package/dist/drizzle/oauth-proxy.d.mts +1 -1
- package/dist/drizzle/oauth-proxy.mjs +1 -1
- package/dist/drizzle/oauth-target.d.mts +9 -6
- package/dist/drizzle/oauth-target.mjs +47 -15
- package/dist/drizzle/oauth-target.mjs.map +1 -1
- package/dist/drizzle/passkey/target.d.mts +14 -0
- package/dist/drizzle/passkey/target.mjs +52 -0
- package/dist/drizzle/passkey/target.mjs.map +1 -0
- package/dist/drizzle/passkey/write-target.d.mts +11 -0
- package/dist/drizzle/passkey/write-target.mjs +28 -0
- package/dist/drizzle/passkey/write-target.mjs.map +1 -0
- package/dist/drizzle/passkey-drivers.mjs +2 -4
- package/dist/drizzle/passkey-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-model.d.mts +5 -26
- package/dist/drizzle/passkey-model.mjs +2 -8
- package/dist/drizzle/passkey-registration-ceremony-model.d.mts +3 -6
- package/dist/drizzle/passkey-write-drivers.mjs +2 -3
- package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-model.d.mts +7 -9
- package/dist/drizzle/passkey-write-model.mjs +1 -3
- package/dist/drizzle/passkey-write-model.mjs.map +1 -1
- package/dist/drizzle/password-drivers.mjs +31 -0
- package/dist/drizzle/password-drivers.mjs.map +1 -0
- package/dist/drizzle/password-model.d.mts +7 -10
- package/dist/drizzle/password-target.d.mts +7 -8
- package/dist/drizzle/password-target.mjs +23 -68
- package/dist/drizzle/password-target.mjs.map +1 -1
- package/dist/drizzle/pg-identity.mjs +3 -6
- package/dist/drizzle/pg-identity.mjs.map +1 -1
- package/dist/drizzle/phone-drivers.mjs +24 -0
- package/dist/drizzle/phone-drivers.mjs.map +1 -0
- package/dist/drizzle/phone-model.d.mts +13 -104
- package/dist/drizzle/phone-model.mjs +5 -33
- package/dist/drizzle/phone-model.mjs.map +1 -1
- package/dist/drizzle/phone-target.mjs +22 -171
- package/dist/drizzle/phone-target.mjs.map +1 -1
- package/dist/drizzle/proof-drivers.mjs +24 -0
- package/dist/drizzle/proof-drivers.mjs.map +1 -0
- package/dist/drizzle/proof-model.d.mts +7 -15
- package/dist/drizzle/proof-target.d.mts +5 -5
- package/dist/drizzle/proof-target.mjs +14 -28
- package/dist/drizzle/proof-target.mjs.map +1 -1
- package/dist/drizzle/session-drivers.mjs +97 -0
- package/dist/drizzle/session-drivers.mjs.map +1 -0
- package/dist/drizzle/session-model.d.mts +11 -22
- package/dist/drizzle/sqlite-do-database.d.mts +3 -3
- package/dist/drizzle/sqlite-do-database.mjs +6 -1
- package/dist/drizzle/sqlite-do-database.mjs.map +1 -1
- package/dist/drizzle/sqlite-identity.mjs +3 -5
- package/dist/drizzle/sqlite-identity.mjs.map +1 -1
- package/dist/drizzle/step-up-model.d.mts +2 -5
- package/dist/drizzle/storage-validation.mjs +2 -1
- package/dist/drizzle/storage-validation.mjs.map +1 -1
- package/dist/drizzle/totp-model.d.mts +7 -74
- package/dist/drizzle/totp-model.mjs +1 -5
- package/dist/drizzle/totp-model.mjs.map +1 -1
- package/dist/drizzle/totp-target.mjs +39 -75
- package/dist/drizzle/totp-target.mjs.map +1 -1
- package/dist/drizzle/transaction-handle.mjs +13 -0
- package/dist/drizzle/transaction-handle.mjs.map +1 -0
- package/dist/drizzle/transaction-mysql.mjs +43 -12
- package/dist/drizzle/transaction-mysql.mjs.map +1 -1
- package/dist/index.d.mts +17 -22
- package/dist/index.mjs +10 -16
- package/dist/internal/drizzle-postgres.mjs +4 -6
- package/dist/internal/drizzle-postgres.mjs.map +1 -1
- package/dist/internal/drizzle-sqlite.mjs +4 -6
- package/dist/internal/drizzle-sqlite.mjs.map +1 -1
- package/package.json +1 -1
- package/src/D1.ts +77 -74
- package/src/Libsql.ts +65 -105
- package/src/Mysql2.ts +52 -87
- package/src/Pglite.ts +74 -81
- package/src/Postgres.ts +74 -81
- package/src/SqliteBun.ts +65 -113
- package/src/SqliteDo.ts +58 -106
- package/src/SqliteNode.ts +65 -113
- package/src/SqliteWasm.ts +65 -113
- package/src/drizzle/d1-identity.ts +2 -2
- package/src/drizzle/driver-types.ts +26 -0
- package/src/drizzle/email-drivers.ts +320 -0
- package/src/drizzle/email-model.ts +24 -78
- package/src/drizzle/email-target.ts +118 -211
- package/src/drizzle/model.ts +0 -2
- package/src/drizzle/mysql-identity.ts +4 -24
- package/src/drizzle/native-clock.ts +21 -0
- package/src/drizzle/native-database.ts +59 -18
- package/src/drizzle/native-sql-table.ts +104 -87
- package/src/drizzle/native-target.ts +120 -0
- package/src/drizzle/oauth-connected-drivers.ts +24 -233
- package/src/drizzle/oauth-connected-model.ts +3 -93
- package/src/drizzle/oauth-connected-reference.ts +16 -25
- package/src/drizzle/oauth-drivers.ts +58 -99
- package/src/drizzle/oauth-model.ts +27 -132
- package/src/drizzle/oauth-target.ts +250 -33
- package/src/drizzle/passkey/target.ts +205 -0
- package/src/drizzle/passkey/write-target.ts +91 -0
- package/src/drizzle/passkey-drivers.ts +35 -133
- package/src/drizzle/passkey-model.ts +3 -81
- package/src/drizzle/passkey-registration-ceremony-model.ts +5 -25
- package/src/drizzle/passkey-write-drivers.ts +32 -102
- package/src/drizzle/passkey-write-model.ts +10 -44
- package/src/drizzle/password-drivers.ts +286 -0
- package/src/drizzle/password-model.ts +10 -44
- package/src/drizzle/password-target.ts +85 -239
- package/src/drizzle/pg-identity.ts +4 -19
- package/src/drizzle/phone-drivers.ts +142 -0
- package/src/drizzle/phone-model.ts +22 -162
- package/src/drizzle/phone-target.ts +51 -493
- package/src/drizzle/proof-drivers.ts +123 -0
- package/src/drizzle/proof-model.ts +12 -123
- package/src/drizzle/proof-target.ts +38 -102
- package/src/drizzle/session-drivers.ts +696 -0
- package/src/drizzle/session-model.ts +54 -118
- package/src/drizzle/sqlite-do-database.ts +8 -0
- package/src/drizzle/sqlite-identity.ts +4 -22
- package/src/drizzle/step-up-model.ts +13 -37
- package/src/drizzle/storage-validation.ts +2 -1
- package/src/drizzle/totp-model.ts +20 -77
- package/src/drizzle/totp-target.ts +121 -261
- package/src/drizzle/transaction-handle.ts +41 -0
- package/src/drizzle/transaction-mysql.ts +90 -25
- package/src/index.ts +7 -122
- package/src/internal/drizzle-postgres.ts +4 -7
- package/src/internal/drizzle-sqlite.ts +4 -7
- package/dist/drizzle/crypto.mjs +0 -11
- package/dist/drizzle/crypto.mjs.map +0 -1
- package/dist/drizzle/d1-emails.d.mts +0 -62
- package/dist/drizzle/d1-emails.mjs +0 -626
- package/dist/drizzle/d1-emails.mjs.map +0 -1
- package/dist/drizzle/d1-generated-statement.mjs +0 -79
- package/dist/drizzle/d1-generated-statement.mjs.map +0 -1
- package/dist/drizzle/d1-oauth.d.mts +0 -331
- package/dist/drizzle/d1-oauth.mjs +0 -79
- package/dist/drizzle/d1-oauth.mjs.map +0 -1
- package/dist/drizzle/d1-passkey.d.mts +0 -37
- package/dist/drizzle/d1-passkey.mjs +0 -98
- package/dist/drizzle/d1-passkey.mjs.map +0 -1
- package/dist/drizzle/d1-password-prepared.d.mts +0 -25
- package/dist/drizzle/d1-password-prepared.mjs +0 -473
- package/dist/drizzle/d1-password-prepared.mjs.map +0 -1
- package/dist/drizzle/d1-passwords.d.mts +0 -70
- package/dist/drizzle/d1-passwords.mjs +0 -808
- package/dist/drizzle/d1-passwords.mjs.map +0 -1
- package/dist/drizzle/d1-phone.d.mts +0 -23
- package/dist/drizzle/d1-phone.mjs +0 -33
- package/dist/drizzle/d1-phone.mjs.map +0 -1
- package/dist/drizzle/d1-planning.d.mts +0 -11
- package/dist/drizzle/d1-planning.mjs +0 -43
- package/dist/drizzle/d1-planning.mjs.map +0 -1
- package/dist/drizzle/d1-proofs.d.mts +0 -80
- package/dist/drizzle/d1-proofs.mjs +0 -842
- package/dist/drizzle/d1-proofs.mjs.map +0 -1
- package/dist/drizzle/d1-sessions.d.mts +0 -68
- package/dist/drizzle/d1-sessions.mjs +0 -987
- package/dist/drizzle/d1-sessions.mjs.map +0 -1
- package/dist/drizzle/d1-totp.d.mts +0 -23
- package/dist/drizzle/d1-totp.mjs +0 -30
- package/dist/drizzle/d1-totp.mjs.map +0 -1
- package/dist/drizzle/email-registration.d.mts +0 -33
- package/dist/drizzle/email-registration.mjs +0 -281
- package/dist/drizzle/email-registration.mjs.map +0 -1
- package/dist/drizzle/email-sql.d.mts +0 -1
- package/dist/drizzle/email-sql.mjs +0 -9
- package/dist/drizzle/email-sql.mjs.map +0 -1
- package/dist/drizzle/mysql-emails.d.mts +0 -71
- package/dist/drizzle/mysql-emails.mjs +0 -43
- package/dist/drizzle/mysql-emails.mjs.map +0 -1
- package/dist/drizzle/mysql-password-prepared.d.mts +0 -30
- package/dist/drizzle/mysql-password-prepared.mjs +0 -21
- package/dist/drizzle/mysql-password-prepared.mjs.map +0 -1
- package/dist/drizzle/mysql-passwords.d.mts +0 -71
- package/dist/drizzle/mysql-passwords.mjs +0 -43
- package/dist/drizzle/mysql-passwords.mjs.map +0 -1
- package/dist/drizzle/mysql-proofs.d.mts +0 -75
- package/dist/drizzle/mysql-proofs.mjs +0 -28
- package/dist/drizzle/mysql-proofs.mjs.map +0 -1
- package/dist/drizzle/mysql-sessions.d.mts +0 -92
- package/dist/drizzle/mysql-sessions.mjs +0 -58
- package/dist/drizzle/mysql-sessions.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-model.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-target.d.mts +0 -6
- package/dist/drizzle/oauth-connected-target.mjs +0 -12
- package/dist/drizzle/oauth-connected-target.mjs.map +0 -1
- package/dist/drizzle/oauth-kernel.mjs +0 -11
- package/dist/drizzle/oauth-kernel.mjs.map +0 -1
- package/dist/drizzle/oauth-mysql.mjs +0 -8
- package/dist/drizzle/oauth-mysql.mjs.map +0 -1
- package/dist/drizzle/passkey-kernel.mjs +0 -8
- package/dist/drizzle/passkey-kernel.mjs.map +0 -1
- package/dist/drizzle/passkey-model.mjs.map +0 -1
- package/dist/drizzle/passkey-registration-ceremony-model.mjs +0 -2
- package/dist/drizzle/passkey-state.mjs +0 -7
- package/dist/drizzle/passkey-state.mjs.map +0 -1
- package/dist/drizzle/passkey-target.d.mts +0 -2
- package/dist/drizzle/passkey-target.mjs +0 -7
- package/dist/drizzle/passkey-target.mjs.map +0 -1
- package/dist/drizzle/passkey-write-target.d.mts +0 -5
- package/dist/drizzle/passkey-write-target.mjs +0 -7
- package/dist/drizzle/passkey-write-target.mjs.map +0 -1
- package/dist/drizzle/password-prepared-model.d.mts +0 -92
- package/dist/drizzle/password-prepared-model.mjs +0 -11
- package/dist/drizzle/password-prepared-model.mjs.map +0 -1
- package/dist/drizzle/password-prepared-sql.mjs +0 -395
- package/dist/drizzle/password-prepared-sql.mjs.map +0 -1
- package/dist/drizzle/password-prepared-state.mjs +0 -104
- package/dist/drizzle/password-prepared-state.mjs.map +0 -1
- package/dist/drizzle/password-prepared-target.d.mts +0 -13
- package/dist/drizzle/password-prepared-target.mjs +0 -62
- package/dist/drizzle/password-prepared-target.mjs.map +0 -1
- package/dist/drizzle/password-registration.d.mts +0 -7
- package/dist/drizzle/password-registration.mjs +0 -137
- package/dist/drizzle/password-registration.mjs.map +0 -1
- package/dist/drizzle/password-sql.d.mts +0 -1
- package/dist/drizzle/password-sql.mjs +0 -10
- package/dist/drizzle/password-sql.mjs.map +0 -1
- package/dist/drizzle/pg-emails.d.mts +0 -72
- package/dist/drizzle/pg-emails.mjs +0 -43
- package/dist/drizzle/pg-emails.mjs.map +0 -1
- package/dist/drizzle/pg-password-prepared.d.mts +0 -31
- package/dist/drizzle/pg-password-prepared.mjs +0 -21
- package/dist/drizzle/pg-password-prepared.mjs.map +0 -1
- package/dist/drizzle/pg-passwords.d.mts +0 -72
- package/dist/drizzle/pg-passwords.mjs +0 -43
- package/dist/drizzle/pg-passwords.mjs.map +0 -1
- package/dist/drizzle/pg-proofs.d.mts +0 -76
- package/dist/drizzle/pg-proofs.mjs +0 -27
- package/dist/drizzle/pg-proofs.mjs.map +0 -1
- package/dist/drizzle/pg-sessions.d.mts +0 -93
- package/dist/drizzle/pg-sessions.mjs +0 -58
- package/dist/drizzle/pg-sessions.mjs.map +0 -1
- package/dist/drizzle/phone-state.mjs +0 -14
- package/dist/drizzle/phone-state.mjs.map +0 -1
- package/dist/drizzle/phone-target.d.mts +0 -15
- package/dist/drizzle/proof-sql.d.mts +0 -1
- package/dist/drizzle/proof-sql.mjs +0 -8
- package/dist/drizzle/proof-sql.mjs.map +0 -1
- package/dist/drizzle/query-operations.mjs +0 -31
- package/dist/drizzle/query-operations.mjs.map +0 -1
- package/dist/drizzle/session-sql.d.mts +0 -1
- package/dist/drizzle/session-sql.mjs +0 -9
- package/dist/drizzle/session-sql.mjs.map +0 -1
- package/dist/drizzle/session-target.d.mts +0 -30
- package/dist/drizzle/session-target.mjs +0 -49
- package/dist/drizzle/session-target.mjs.map +0 -1
- package/dist/drizzle/sqlite-emails.mjs +0 -50
- package/dist/drizzle/sqlite-emails.mjs.map +0 -1
- package/dist/drizzle/sqlite-password-prepared.mjs +0 -26
- package/dist/drizzle/sqlite-password-prepared.mjs.map +0 -1
- package/dist/drizzle/sqlite-passwords.mjs +0 -54
- package/dist/drizzle/sqlite-passwords.mjs.map +0 -1
- package/dist/drizzle/sqlite-proofs.mjs +0 -34
- package/dist/drizzle/sqlite-proofs.mjs.map +0 -1
- package/dist/drizzle/sqlite-sessions.mjs +0 -79
- package/dist/drizzle/sqlite-sessions.mjs.map +0 -1
- package/dist/drizzle/standalone-guard.d.mts +0 -2
- package/dist/drizzle/standalone-guard.mjs +0 -21
- package/dist/drizzle/standalone-guard.mjs.map +0 -1
- package/dist/drizzle/totp-state.d.mts +0 -37
- package/dist/drizzle/totp-state.mjs +0 -287
- package/dist/drizzle/totp-state.mjs.map +0 -1
- package/dist/drizzle/totp-target.d.mts +0 -15
- package/dist/drizzle/transaction-execution.d.mts +0 -2
- package/dist/drizzle/transaction-execution.mjs +0 -11
- package/dist/drizzle/transaction-execution.mjs.map +0 -1
- package/dist/drizzle/transaction-owner.d.mts +0 -1
- package/dist/drizzle/transaction-owner.mjs +0 -8
- package/dist/drizzle/transaction-owner.mjs.map +0 -1
- package/src/drizzle/crypto.ts +0 -14
- package/src/drizzle/d1-emails.ts +0 -1945
- package/src/drizzle/d1-generated-statement.ts +0 -129
- package/src/drizzle/d1-oauth.ts +0 -360
- package/src/drizzle/d1-passkey.ts +0 -383
- package/src/drizzle/d1-password-prepared.ts +0 -1265
- package/src/drizzle/d1-passwords.ts +0 -2060
- package/src/drizzle/d1-phone.ts +0 -103
- package/src/drizzle/d1-planning.ts +0 -104
- package/src/drizzle/d1-proofs.ts +0 -2354
- package/src/drizzle/d1-sessions.ts +0 -2940
- package/src/drizzle/d1-totp.ts +0 -88
- package/src/drizzle/email-registration.ts +0 -850
- package/src/drizzle/email-sql.ts +0 -25
- package/src/drizzle/mysql-emails.ts +0 -343
- package/src/drizzle/mysql-password-prepared.ts +0 -198
- package/src/drizzle/mysql-passwords.ts +0 -343
- package/src/drizzle/mysql-proofs.ts +0 -196
- package/src/drizzle/mysql-sessions.ts +0 -780
- package/src/drizzle/oauth-connected-target.ts +0 -21
- package/src/drizzle/oauth-kernel.ts +0 -10
- package/src/drizzle/oauth-mysql.ts +0 -10
- package/src/drizzle/passkey-kernel.ts +0 -4
- package/src/drizzle/passkey-state.ts +0 -3
- package/src/drizzle/passkey-target.ts +0 -23
- package/src/drizzle/passkey-write-target.ts +0 -9
- package/src/drizzle/password-prepared-model.ts +0 -241
- package/src/drizzle/password-prepared-sql.ts +0 -1201
- package/src/drizzle/password-prepared-state.ts +0 -231
- package/src/drizzle/password-prepared-target.ts +0 -169
- package/src/drizzle/password-registration.ts +0 -369
- package/src/drizzle/password-sql.ts +0 -16
- package/src/drizzle/pg-emails.ts +0 -343
- package/src/drizzle/pg-password-prepared.ts +0 -199
- package/src/drizzle/pg-passwords.ts +0 -342
- package/src/drizzle/pg-proofs.ts +0 -206
- package/src/drizzle/pg-sessions.ts +0 -789
- package/src/drizzle/phone-state.ts +0 -21
- package/src/drizzle/proof-sql.ts +0 -10
- package/src/drizzle/query-operations.ts +0 -49
- package/src/drizzle/session-sql.ts +0 -15
- package/src/drizzle/session-target.ts +0 -337
- package/src/drizzle/sqlite-emails.ts +0 -393
- package/src/drizzle/sqlite-password-prepared.ts +0 -230
- package/src/drizzle/sqlite-passwords.ts +0 -497
- package/src/drizzle/sqlite-proofs.ts +0 -229
- package/src/drizzle/sqlite-sessions.ts +0 -1013
- package/src/drizzle/totp-state.ts +0 -525
- package/src/drizzle/transaction-execution.ts +0 -13
- package/src/drizzle/transaction-owner.ts +0 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-drivers.mjs","names":[],"sources":["../../src/drizzle/password-drivers.ts"],"sourcesContent":["import type { PasswordRegistrationAuthority } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport { PasswordPersistence, type PasswordUnavailable } from \"@yielded/auth/Password\";\nimport type { Table } from \"drizzle-orm\";\nimport { type Context, Effect, type Crypto } from \"effect\";\n\nimport type { NativeDriverDatabase, NativeDriverTransaction } from \"./driver-types\";\nimport { NativeDatabase, nativeDatabase } from \"./native-database\";\nimport type { NativeTargetConfiguration } from \"./native-target\";\nimport type {\n AnyPasswordPersistenceMapping,\n AnyPasswordRegistrationMapping,\n PasswordPersistenceMapping,\n PasswordRegistrationMapping,\n} from \"./password-model\";\nimport {\n coordinateTargetPasswordPersistence,\n coordinateTargetPasswordRegistration,\n makeTargetPasswordPersistenceServices,\n makeTargetPasswordRegistrationServices,\n} from \"./password-target\";\nimport type { AnyProofPersistenceMapping, ProofPersistenceMapping } from \"./proof-model\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype ProofOption<Proof extends Table, Subject extends Table, NativeId> = {\n readonly proofMapping?: ProofPersistenceMapping<Proof, Subject, NativeId>;\n};\n\n/** Foreign table callback variance is erased only after these public signatures;\n * the target validates physical metadata and the workflow invokes row codecs. */\nexport const makePasswordTarget = <DatabaseId, D extends NativeDriverDatabase>(\n databaseService: Context.Service<DatabaseId, D>,\n configuration: NativeTargetConfiguration,\n) => {\n function coordinatePasswordPersistence<\n Database extends D,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n Proof extends Table,\n PS extends Table,\n PN,\n A,\n E,\n R,\n DE,\n DR,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PasswordPersistenceMapping<S, I, C, AC, N>;\n readonly transaction?: never;\n } & ProofOption<Proof, PS, PN>,\n body: Effect.Effect<A, E, R>,\n ): Effect.Effect<\n A,\n E | DE | PasswordUnavailable,\n Exclude<R, PasswordPersistence> | DR | LifecycleHooks | Crypto.Crypto\n >;\n function coordinatePasswordPersistence<\n Database extends D,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n Proof extends Table,\n PS extends Table,\n PN,\n A,\n E,\n R,\n DE,\n DR,\n TxId,\n TxShape,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PasswordPersistenceMapping<S, I, C, AC, N>;\n readonly transaction: SuppliedService<\n TxId,\n NoInfer<NativeDriverTransaction<Database>>,\n TxShape\n >;\n } & ProofOption<Proof, PS, PN>,\n body: Effect.Effect<A, E, R>,\n ): Effect.Effect<\n A,\n E | DE | PasswordUnavailable,\n Exclude<R, PasswordPersistence | TxId> | DR | LifecycleHooks | Crypto.Crypto\n >;\n function coordinatePasswordPersistence<\n Database extends D,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n Proof extends Table,\n PS extends Table,\n PN,\n A,\n E,\n R,\n DE,\n DR,\n TxId,\n TxShape,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PasswordPersistenceMapping<S, I, C, AC, N>;\n readonly transaction?: SuppliedService<\n TxId,\n NoInfer<NativeDriverTransaction<Database>>,\n TxShape\n >;\n } & ProofOption<Proof, PS, PN>,\n body: Effect.Effect<A, E, R>,\n ) {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasswordPersistence(\n database,\n options.mapping as unknown as AnyPasswordPersistenceMapping,\n configuration,\n (transaction: NativeDriverTransaction<Database>, services) => {\n const work = Effect.provideService(\n body,\n PasswordPersistence,\n services.passwordPersistence,\n );\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n options.proofMapping as unknown as AnyProofPersistenceMapping | undefined,\n ),\n );\n }\n\n function coordinatePasswordRegistration<\n TargetId,\n Registration,\n Database extends D,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n A,\n E,\n R,\n DE,\n DR,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, N>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n ): Effect.Effect<\n A,\n E | DE | PasswordUnavailable,\n Exclude<R, TargetId> | DR | LifecycleHooks | Crypto.Crypto\n >;\n function coordinatePasswordRegistration<\n TargetId,\n Registration,\n Database extends D,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n A,\n E,\n R,\n DE,\n DR,\n TxId,\n TxShape,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, N>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction: SuppliedService<\n TxId,\n NoInfer<NativeDriverTransaction<Database>>,\n TxShape\n >;\n },\n body: Effect.Effect<A, E, R>,\n ): Effect.Effect<\n A,\n E | DE | PasswordUnavailable,\n Exclude<R, TargetId | TxId> | DR | LifecycleHooks | Crypto.Crypto\n >;\n function coordinatePasswordRegistration<\n TargetId,\n Registration,\n Database extends D,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n A,\n E,\n R,\n DE,\n DR,\n TxId,\n TxShape,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, N>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction?: SuppliedService<\n TxId,\n NoInfer<NativeDriverTransaction<Database>>,\n TxShape\n >;\n },\n body: Effect.Effect<A, E, R>,\n ) {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasswordRegistration(\n database,\n options.mapping as unknown as AnyPasswordRegistrationMapping<Registration>,\n configuration,\n (transaction: NativeDriverTransaction<Database>, services) => {\n const work = Effect.provideService(body, options.target, services.registrationAuthority);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n }\n\n return {\n makePasswordPersistenceServices: <\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n Proof extends Table,\n PS extends Table,\n PN,\n >(\n mapping: PasswordPersistenceMapping<S, I, C, AC, N>,\n proofMapping?: ProofPersistenceMapping<Proof, PS, PN>,\n ) =>\n makeTargetPasswordPersistenceServices(\n mapping as unknown as AnyPasswordPersistenceMapping,\n configuration,\n proofMapping as unknown as AnyProofPersistenceMapping | undefined,\n ).pipe(Effect.provideServiceEffect(NativeDatabase, nativeDatabase(databaseService))),\n makePasswordRegistrationServices: <\n Registration,\n S extends Table,\n I extends Table,\n C extends Table,\n AC extends Table,\n N,\n >(\n mapping: PasswordRegistrationMapping<Registration, S, I, C, AC, N>,\n ) =>\n makeTargetPasswordRegistrationServices(\n mapping as unknown as AnyPasswordRegistrationMapping<Registration>,\n configuration,\n ).pipe(Effect.provideServiceEffect(NativeDatabase, nativeDatabase(databaseService))),\n coordinatePasswordPersistence,\n coordinatePasswordRegistration,\n };\n};\n"],"mappings":";;;;;;;AA8BA,MAAa,sBACX,iBACA,kBACG;CA6DH,SAAS,8BAkBP,SACA,SAQA,MACA;EACA,OAAO,OAAO,QAAQ,eAAe,OAAO,IAAI,aAC9C,oCACE,UACA,QAAQ,SACR,gBACC,aAAgD,aAAa;GAC5D,MAAM,OAAO,OAAO,eAClB,MACA,qBACA,SAAS,mBACX;GAEA,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;EAC1F,GACA,QAAQ,YACV,CACF;CACF;CA8DA,SAAS,+BAiBP,SACA,SASA,MACA;EACA,OAAO,OAAO,QAAQ,eAAe,OAAO,IAAI,aAC9C,qCACE,UACA,QAAQ,SACR,gBACC,aAAgD,aAAa;GAC5D,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ,QAAQ,SAAS,qBAAqB;GAEvF,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;EAC1F,CACF,CACF;CACF;CAEA,OAAO;EACL,kCAUE,SACA,iBAEA,sCACE,SACA,eACA,YACF,CAAC,CAAC,KAAK,OAAO,qBAAqB,gBAAgB,eAAe,eAAe,CAAC,CAAC;EACrF,mCAQE,YAEA,uCACE,SACA,aACF,CAAC,CAAC,KAAK,OAAO,qBAAqB,gBAAgB,eAAe,eAAe,CAAC,CAAC;EACrF;EACA;CACF;AACF"}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
+
import { ClockMapping } from "./native-clock.mjs";
|
|
1
2
|
import { DrizzleTableModel } from "./table-model.mjs";
|
|
2
3
|
import * as Shared from "@yielded/auth-persistence/Adapter";
|
|
3
|
-
import {
|
|
4
|
+
import { PasswordRegistrationConstraintClassifier, PasswordRegistrationIntent, RequiredPasswordConstraints, RequiredPasswordRegistrationConstraints, requiredPasswordConstraints, requiredPasswordRegistrationConstraints } from "@yielded/auth-persistence/Adapter";
|
|
4
5
|
import { SQL, Table } from "drizzle-orm";
|
|
5
6
|
//#region src/drizzle/password-model.d.ts
|
|
6
7
|
export type PasswordSubjectTable<Subject extends Table, _NativeSubjectId> = Shared.PasswordSubjectTable<DrizzleTableModel<Subject>, _NativeSubjectId>;
|
|
7
8
|
export type PasswordIdentifierTable<Identifier extends Table, NativeSubjectId> = Shared.PasswordIdentifierTable<DrizzleTableModel<Identifier>, NativeSubjectId, SQL>;
|
|
8
9
|
export type PasswordAuthorityCredentialTable<Credential extends Table, NativeSubjectId> = Shared.PasswordAuthorityCredentialTable<DrizzleTableModel<Credential>, NativeSubjectId>;
|
|
9
10
|
export type PasswordCredentialTable<Subject extends Table, Identifier extends Table, Credential extends Table, NativeSubjectId> = Shared.PasswordCredentialTable<DrizzleTableModel<Subject>, DrizzleTableModel<Identifier>, DrizzleTableModel<Credential>, NativeSubjectId>;
|
|
10
|
-
export type
|
|
11
|
-
export type PasswordD1Clock = Shared.PasswordD1Clock<SQL>;
|
|
12
|
-
export type PasswordPersistenceMapping<Subject extends Table, Identifier extends Table, Credential extends Table, AuthorityCredential extends Table, Command extends Table, NativeSubjectId> = Shared.PasswordPersistenceMapping<DrizzleTableModel<Subject>, DrizzleTableModel<Identifier>, DrizzleTableModel<Credential>, DrizzleTableModel<AuthorityCredential>, DrizzleTableModel<Command>, NativeSubjectId, SQL>;
|
|
13
|
-
export type D1PasswordPersistenceMapping<Subject extends Table, Identifier extends Table, Credential extends Table, AuthorityCredential extends Table, Command extends Table, NativeSubjectId> = Shared.D1PasswordPersistenceMapping<DrizzleTableModel<Subject>, DrizzleTableModel<Identifier>, DrizzleTableModel<Credential>, DrizzleTableModel<AuthorityCredential>, DrizzleTableModel<Command>, NativeSubjectId, SQL>;
|
|
14
|
-
export type PasswordRegistrationTable<Registration, Request extends Table, NativeSubjectId> = Shared.PasswordRegistrationTable<Registration, DrizzleTableModel<Request>, NativeSubjectId>;
|
|
11
|
+
export type PasswordPersistenceMapping<Subject extends Table, Identifier extends Table, Credential extends Table, AuthorityCredential extends Table, NativeSubjectId> = ClockMapping<Shared.PasswordPersistenceMapping<DrizzleTableModel<Subject>, DrizzleTableModel<Identifier>, DrizzleTableModel<Credential>, DrizzleTableModel<AuthorityCredential>, NativeSubjectId, SQL>>;
|
|
15
12
|
export type PasswordRegistrationProvisioning<Registration, Subject extends Table, NativeSubjectId> = Shared.PasswordRegistrationProvisioning<Registration, DrizzleTableModel<Subject>, NativeSubjectId>;
|
|
16
|
-
export type PasswordRegistrationMapping<Registration, Subject extends Table, Identifier extends Table, Credential extends Table, AuthorityCredential extends Table,
|
|
17
|
-
export type AnyPasswordPersistenceMapping = PasswordPersistenceMapping<Table, Table, Table, Table,
|
|
18
|
-
export type AnyPasswordRegistrationMapping<Registration = unknown> = PasswordRegistrationMapping<Registration, Table, Table, Table, Table,
|
|
13
|
+
export type PasswordRegistrationMapping<Registration, Subject extends Table, Identifier extends Table, Credential extends Table, AuthorityCredential extends Table, NativeSubjectId> = Shared.PasswordRegistrationMapping<Registration, DrizzleTableModel<Subject>, DrizzleTableModel<Identifier>, DrizzleTableModel<Credential>, DrizzleTableModel<AuthorityCredential>, NativeSubjectId, SQL>;
|
|
14
|
+
export type AnyPasswordPersistenceMapping = PasswordPersistenceMapping<Table, Table, Table, Table, unknown>;
|
|
15
|
+
export type AnyPasswordRegistrationMapping<Registration = unknown> = PasswordRegistrationMapping<Registration, Table, Table, Table, Table, unknown>;
|
|
19
16
|
//#endregion
|
|
20
|
-
export { type
|
|
17
|
+
export { type PasswordRegistrationConstraintClassifier, type PasswordRegistrationIntent, type RequiredPasswordConstraints, type RequiredPasswordRegistrationConstraints, requiredPasswordConstraints, requiredPasswordRegistrationConstraints };
|
|
21
18
|
//# sourceMappingURL=password-model.d.mts.map
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./proof-
|
|
3
|
-
import "./
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import "./password-model.mjs";
|
|
2
|
+
import "./proof-model.mjs";
|
|
3
|
+
import "./native-database.mjs";
|
|
4
|
+
import "./D1BatchStatements.mjs";
|
|
5
|
+
import "./native-target.mjs";
|
|
6
|
+
import { PasswordRegistrationAuthority, requireStandalone } from "@yielded/auth-persistence/Adapter";
|
|
6
7
|
import { Context, Effect, Layer } from "effect";
|
|
7
|
-
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
8
8
|
import { PasswordPersistence, PasswordUnavailable } from "@yielded/auth/Password";
|
|
9
|
-
import "effect/sql/SqlError";
|
|
10
9
|
//#region src/drizzle/password-target.d.ts
|
|
11
10
|
export declare const passwordPersistenceLayer: <E, R>(services: Effect.Effect<{
|
|
12
11
|
readonly passwordPersistence: PasswordPersistence["Service"];
|
|
13
12
|
}, E, R>) => Layer.Layer<PasswordPersistence, E, Exclude<R, import("effect/Scope").Scope>>;
|
|
14
|
-
export declare const passwordRegistrationLayer: <Id, Registration, E, R>(
|
|
13
|
+
export declare const passwordRegistrationLayer: <Id, Registration, E, R>(target: Context.Key<Id, PasswordRegistrationAuthority<Registration>>, services: Effect.Effect<{
|
|
15
14
|
readonly registrationAuthority: PasswordRegistrationAuthority<Registration>;
|
|
16
15
|
}, E, R>) => Layer.Layer<Id, E, Exclude<R, import("effect/Scope").Scope>>;
|
|
17
16
|
//#endregion
|
|
@@ -1,78 +1,33 @@
|
|
|
1
|
+
import { nativeClock } from "./native-clock.mjs";
|
|
2
|
+
import { coordinateNativeTarget, nativeTarget } from "./native-target.mjs";
|
|
1
3
|
import { validateDrizzleStorage } from "./storage-validation.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { CurrentPasswordPreparedTransaction, PasswordPreparedPostconditions } from "@yielded/auth-persistence/Adapter";
|
|
6
|
-
import { Cause, Effect, Layer } from "effect";
|
|
7
|
-
import { LifecycleHooks, coordinateCommit, hasCommitScope } from "@yielded/auth/Hooks";
|
|
4
|
+
import { nativeProofMapping } from "./proof-target.mjs";
|
|
5
|
+
import { makeNativePasswordRegistrationServices, makeNativePasswordServices } from "@yielded/auth-persistence/Adapter";
|
|
6
|
+
import { Effect, Layer } from "effect";
|
|
8
7
|
import { PasswordPersistence, PasswordUnavailable } from "@yielded/auth/Password";
|
|
9
8
|
//#region src/drizzle/password-target.ts
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,
|
|
15
|
-
insertIfAbsent: configuration.insertIfAbsent,
|
|
16
|
-
coordinated,
|
|
17
|
-
...proofMapping === void 0 ? {} : { proof: {
|
|
18
|
-
mapping: proofMapping,
|
|
19
|
-
configuration: {
|
|
20
|
-
mode: configuration.proof.mode,
|
|
21
|
-
locking: configuration.proof.locking,
|
|
22
|
-
standaloneGuard: Effect.void,
|
|
23
|
-
coordinated,
|
|
24
|
-
insertIfAbsent: configuration.proof.insertIfAbsent
|
|
25
|
-
}
|
|
26
|
-
} }
|
|
9
|
+
const unavailable = () => PasswordUnavailable.make({});
|
|
10
|
+
const mapped = (value) => ({
|
|
11
|
+
...value,
|
|
12
|
+
clock: nativeClock(value.clock)
|
|
27
13
|
});
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
14
|
+
const makeTargetPasswordPersistenceServices = Effect.fnUntraced(function* (mapping, configuration, proofs) {
|
|
15
|
+
yield* validateDrizzleStorage(mapping).pipe(Effect.mapError(unavailable));
|
|
16
|
+
if (proofs !== void 0) yield* validateDrizzleStorage(proofs).pipe(Effect.mapError(unavailable));
|
|
17
|
+
if (configuration.mode === "batch" && (mapping.d1?.primary !== true || proofs !== void 0 && proofs.d1?.primary !== true)) return yield* unavailable();
|
|
18
|
+
const target = yield* nativeTarget(configuration);
|
|
19
|
+
return yield* target.provide(makeNativePasswordServices(target.tables, mapped(mapping), proofs === void 0 ? void 0 : nativeProofMapping(proofs)));
|
|
34
20
|
});
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return { registrationAuthority: yield* makeSqlPasswordRegistrationAuthority(mapping, registrationOptions(configuration)) };
|
|
40
|
-
});
|
|
41
|
-
/** Native transaction acquisition exposes SqlError; caller errors propagate unchanged. */
|
|
42
|
-
const coordinateTargetPasswordPersistence = (database, mapping, configuration, proofMapping, owner) => Effect.gen(function* () {
|
|
43
|
-
const hooks = yield* LifecycleHooks;
|
|
44
|
-
if (yield* hasCommitScope) return yield* PasswordUnavailable.make({});
|
|
45
|
-
yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;
|
|
46
|
-
yield* validateDrizzleStorage({
|
|
47
|
-
...mapping,
|
|
48
|
-
proof: proofMapping
|
|
49
|
-
}).pipe(Effect.mapError(() => PasswordUnavailable.make({})));
|
|
50
|
-
return (yield* coordinateCommit(() => database.transaction((transaction) => Effect.gen(function* () {
|
|
51
|
-
const postconditions = [];
|
|
52
|
-
let acceptingPostconditions = true;
|
|
53
|
-
const value = yield* owner(transaction, { passwordPersistence: yield* makeSqlPasswordPersistence(mapping, passwordOptions(configuration, proofMapping, true)).pipe(Effect.provideService(CurrentPasswordSql, transaction)) }).pipe(Effect.provideService(PasswordPreparedPostconditions, { register: (check) => {
|
|
54
|
-
if (!acceptingPostconditions) return false;
|
|
55
|
-
postconditions.push(check);
|
|
56
|
-
return true;
|
|
57
|
-
} }), Effect.ensuring(Effect.sync(() => {
|
|
58
|
-
acceptingPostconditions = false;
|
|
59
|
-
})));
|
|
60
|
-
for (const check of postconditions) yield* check.pipe(Effect.provideService(CurrentPasswordPreparedTransaction, transaction), Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, () => PasswordUnavailable.make({})))));
|
|
61
|
-
return value;
|
|
62
|
-
})), { mode: configuration.mode }).pipe(Effect.provideService(LifecycleHooks, hooks))).value;
|
|
63
|
-
});
|
|
64
|
-
const coordinateTargetPasswordRegistration = (database, mapping, configuration, owner) => Effect.gen(function* () {
|
|
65
|
-
const hooks = yield* LifecycleHooks;
|
|
66
|
-
if (yield* hasCommitScope) return yield* PasswordUnavailable.make({});
|
|
67
|
-
yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;
|
|
68
|
-
yield* validateDrizzleStorage(mapping).pipe(Effect.mapError(() => PasswordUnavailable.make({})));
|
|
69
|
-
return (yield* coordinateCommit(() => database.transaction((transaction) => Effect.gen(function* () {
|
|
70
|
-
return yield* owner(transaction, { registrationAuthority: yield* makeSqlPasswordRegistrationAuthority(mapping, registrationOptions(configuration, true)).pipe(Effect.provideService(CurrentPasswordSql, transaction)) });
|
|
71
|
-
})), { mode: configuration.mode }).pipe(Effect.provideService(LifecycleHooks, hooks))).value;
|
|
21
|
+
const makeTargetPasswordRegistrationServices = Effect.fnUntraced(function* (mapping, configuration) {
|
|
22
|
+
yield* validateDrizzleStorage(mapping).pipe(Effect.mapError(unavailable));
|
|
23
|
+
const target = yield* nativeTarget(configuration);
|
|
24
|
+
return yield* target.provide(makeNativePasswordRegistrationServices(target.tables, mapping, target.batch));
|
|
72
25
|
});
|
|
26
|
+
const coordinateTargetPasswordPersistence = (database, mapping, configuration, body, proofs) => coordinateNativeTarget(unavailable, database, configuration, makeTargetPasswordPersistenceServices(mapping, configuration, proofs), body);
|
|
27
|
+
const coordinateTargetPasswordRegistration = (database, mapping, configuration, body) => coordinateNativeTarget(unavailable, database, configuration, makeTargetPasswordRegistrationServices(mapping, configuration), body);
|
|
73
28
|
const passwordPersistenceLayer = (services) => Layer.effect(PasswordPersistence, Effect.map(services, (value) => value.passwordPersistence));
|
|
74
|
-
const passwordRegistrationLayer = (
|
|
29
|
+
const passwordRegistrationLayer = (target, services) => Layer.effect(target, Effect.map(services, (value) => value.registrationAuthority));
|
|
75
30
|
//#endregion
|
|
76
|
-
export { coordinateTargetPasswordPersistence, coordinateTargetPasswordRegistration, makeTargetPasswordPersistenceServices, makeTargetPasswordRegistrationServices,
|
|
31
|
+
export { coordinateTargetPasswordPersistence, coordinateTargetPasswordRegistration, makeTargetPasswordPersistenceServices, makeTargetPasswordRegistrationServices, passwordPersistenceLayer, passwordRegistrationLayer };
|
|
77
32
|
|
|
78
33
|
//# sourceMappingURL=password-target.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-target.mjs","names":[],"sources":["../../src/drizzle/password-target.ts"],"sourcesContent":["import {\n CurrentPasswordPreparedTransaction,\n type NativeDatabase,\n type PasswordPreparedPostcondition,\n PasswordPreparedPostconditions,\n} from \"@yielded/auth-persistence/Adapter\";\nimport {\n coordinateCommit,\n hasCommitScope,\n LifecycleHooks,\n type HookConfigurationError,\n} from \"@yielded/auth/Hooks\";\nimport { PasswordUnavailable, PasswordPersistence } from \"@yielded/auth/Password\";\n/* oxlint-disable no-explicit-any -- public driver wrappers restore concrete Drizzle generics. */\nimport { Cause, type Context, Effect, Layer } from \"effect\";\nimport type * as SqlError from \"effect/sql/SqlError\";\n\nimport {\n makeSqlPasswordRegistrationAuthority,\n type PasswordRegistrationAuthority,\n type PasswordRegistrationConfiguration,\n} from \"./password-registration\";\nimport {\n CurrentPasswordSql,\n makeSqlPasswordPersistence,\n type PasswordSqlConfiguration,\n type PasswordSqlDatabase,\n type PasswordSqlQuery,\n} from \"./password-sql\";\nimport type { ProofTargetConfiguration } from \"./proof-target\";\nimport { sqlClientStandaloneGuard, type TransactionService } from \"./standalone-guard\";\nimport { validateDrizzleStorage } from \"./storage-validation\";\n\nexport interface PasswordTargetConfiguration {\n readonly mode: \"interactive\" | \"synchronous\";\n readonly locking: boolean;\n readonly standaloneGuard: Effect.Effect<void, PasswordUnavailable>;\n readonly coordinatorGuard?: Effect.Effect<void, PasswordUnavailable>;\n readonly insertIfAbsent: (\n query: PasswordSqlQuery,\n selfKey: string,\n selfValue: unknown,\n ) => PasswordSqlQuery;\n readonly generatedSubjectRows: (query: PasswordSqlQuery) => PasswordSqlQuery;\n readonly proof: ProofTargetConfiguration;\n}\n\ninterface TransactionOwner<Transaction> {\n readonly transaction: <A, E, R>(\n body: (transaction: Transaction) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SqlError.SqlError, R>;\n}\n\nexport type PasswordCoordinatorError<E> =\n | E\n | PasswordUnavailable\n | HookConfigurationError\n | SqlError.SqlError;\n\nexport const sqlClientPasswordStandaloneGuard = (\n service: TransactionService | undefined,\n): Effect.Effect<void, PasswordUnavailable> =>\n sqlClientStandaloneGuard(service, () => PasswordUnavailable.make({}));\n\nexport const passwordOptions = (\n configuration: PasswordTargetConfiguration,\n proofMapping?: any,\n coordinated = false,\n): PasswordSqlConfiguration => ({\n mode: configuration.mode,\n locking: configuration.locking,\n\n standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,\n insertIfAbsent: configuration.insertIfAbsent,\n coordinated,\n ...(proofMapping === undefined\n ? {}\n : {\n proof: {\n mapping: proofMapping,\n configuration: {\n mode: configuration.proof.mode,\n locking: configuration.proof.locking,\n\n standaloneGuard: Effect.void,\n\n coordinated,\n insertIfAbsent: configuration.proof.insertIfAbsent,\n },\n },\n }),\n});\n\nconst registrationOptions = (\n configuration: PasswordTargetConfiguration,\n coordinated = false,\n): PasswordRegistrationConfiguration => ({\n mode: configuration.mode,\n locking: configuration.locking,\n\n standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,\n generatedSubjectRows: configuration.generatedSubjectRows,\n coordinated,\n});\n\nexport const makeTargetPasswordPersistenceServices = (\n mapping: any,\n configuration: PasswordTargetConfiguration,\n proofMapping?: any,\n) =>\n Effect.gen(function* () {\n return {\n passwordPersistence: yield* makeSqlPasswordPersistence(\n mapping,\n passwordOptions(configuration, proofMapping),\n ),\n };\n });\n\nexport const makeTargetPasswordRegistrationServices = <Registration>(\n mapping: any,\n configuration: PasswordTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n registrationAuthority: yield* makeSqlPasswordRegistrationAuthority<Registration>(\n mapping,\n registrationOptions(configuration),\n ),\n };\n });\n\n/** Native transaction acquisition exposes SqlError; caller errors propagate unchanged. */\nexport const coordinateTargetPasswordPersistence = <Transaction, A, E, R>(\n database: TransactionOwner<Transaction>,\n mapping: any,\n configuration: PasswordTargetConfiguration,\n proofMapping: any | undefined,\n owner: (\n transaction: Transaction,\n services: { readonly passwordPersistence: PasswordPersistence[\"Service\"] },\n ) => Effect.Effect<A, E, R>,\n): Effect.Effect<A, PasswordCoordinatorError<E>, R | LifecycleHooks | NativeDatabase> =>\n Effect.gen(function* (): Effect.fn.Return<\n A,\n PasswordCoordinatorError<E>,\n R | LifecycleHooks | NativeDatabase\n > {\n const hooks = yield* LifecycleHooks;\n\n if (yield* hasCommitScope) return yield* PasswordUnavailable.make({});\n yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;\n\n yield* validateDrizzleStorage({ ...mapping, proof: proofMapping }).pipe(\n Effect.mapError(() => PasswordUnavailable.make({})),\n );\n\n const result = yield* coordinateCommit(\n () =>\n database.transaction((transaction) =>\n Effect.gen(function* () {\n const postconditions: Array<PasswordPreparedPostcondition> = [];\n let acceptingPostconditions = true;\n\n const value = yield* owner(transaction, {\n passwordPersistence: yield* makeSqlPasswordPersistence(\n mapping,\n passwordOptions(configuration, proofMapping, true),\n ).pipe(\n Effect.provideService(\n CurrentPasswordSql,\n transaction as unknown as PasswordSqlDatabase,\n ),\n ),\n }).pipe(\n Effect.provideService(PasswordPreparedPostconditions, {\n register: (check) => {\n if (!acceptingPostconditions) return false;\n postconditions.push(check);\n\n return true;\n },\n }),\n Effect.ensuring(\n Effect.sync(() => {\n acceptingPostconditions = false;\n }),\n ),\n );\n\n // Application work in this transaction must not change what the\n // password mutations committed to; a failure here rolls back both.\n for (const check of postconditions)\n yield* check.pipe(\n Effect.provideService(\n CurrentPasswordPreparedTransaction,\n transaction as unknown as PasswordSqlDatabase,\n ),\n Effect.catchCause((cause) =>\n Effect.failCause(Cause.map(cause, () => PasswordUnavailable.make({}))),\n ),\n );\n\n return value;\n }),\n ),\n { mode: configuration.mode },\n ).pipe(Effect.provideService(LifecycleHooks, hooks));\n\n return result.value;\n });\n\nexport const coordinateTargetPasswordRegistration = <Registration, Transaction, A, E, R>(\n database: TransactionOwner<Transaction>,\n mapping: any,\n configuration: PasswordTargetConfiguration,\n owner: (\n transaction: Transaction,\n services: {\n readonly registrationAuthority: PasswordRegistrationAuthority<Registration>;\n },\n ) => Effect.Effect<A, E, R>,\n): Effect.Effect<A, PasswordCoordinatorError<E>, R | LifecycleHooks | NativeDatabase> =>\n Effect.gen(function* (): Effect.fn.Return<\n A,\n PasswordCoordinatorError<E>,\n R | LifecycleHooks | NativeDatabase\n > {\n const hooks = yield* LifecycleHooks;\n\n if (yield* hasCommitScope) return yield* PasswordUnavailable.make({});\n yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.mapError(() => PasswordUnavailable.make({})),\n );\n\n const result = yield* coordinateCommit(\n () =>\n database.transaction((transaction) =>\n Effect.gen(function* () {\n return yield* owner(transaction, {\n registrationAuthority: yield* makeSqlPasswordRegistrationAuthority<Registration>(\n mapping,\n registrationOptions(configuration, true),\n ).pipe(\n Effect.provideService(\n CurrentPasswordSql,\n transaction as unknown as PasswordSqlDatabase,\n ),\n ),\n });\n }),\n ),\n { mode: configuration.mode },\n ).pipe(Effect.provideService(LifecycleHooks, hooks));\n\n return result.value;\n });\n\nexport const passwordPersistenceLayer = <E, R>(\n services: Effect.Effect<{ readonly passwordPersistence: PasswordPersistence[\"Service\"] }, E, R>,\n) =>\n Layer.effect(\n PasswordPersistence,\n Effect.map(services, (value) => value.passwordPersistence),\n );\n\nexport const passwordRegistrationLayer = <Id, Registration, E, R>(\n tag: Context.Key<Id, PasswordRegistrationAuthority<Registration>>,\n services: Effect.Effect<\n { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },\n E,\n R\n >,\n) =>\n Layer.effect(\n tag,\n Effect.map(services, (value) => value.registrationAuthority),\n );\n"],"mappings":";;;;;;;;;AA2DA,MAAa,oCACX,YAEA,yBAAyB,eAAe,oBAAoB,KAAK,CAAC,CAAC,CAAC;AAEtE,MAAa,mBACX,eACA,cACA,cAAc,WACgB;CAC9B,MAAM,cAAc;CACpB,SAAS,cAAc;CAEvB,iBAAiB,CAAC,cAAc,cAAc,kBAAkB,OAAO;CACvE,gBAAgB,cAAc;CAC9B;CACA,GAAI,iBAAiB,KAAA,IACjB,CAAC,IACD,EACE,OAAO;EACL,SAAS;EACT,eAAe;GACb,MAAM,cAAc,MAAM;GAC1B,SAAS,cAAc,MAAM;GAE7B,iBAAiB,OAAO;GAExB;GACA,gBAAgB,cAAc,MAAM;EACtC;CACF,EACF;AACN;AAEA,MAAM,uBACJ,eACA,cAAc,WACyB;CACvC,MAAM,cAAc;CACpB,SAAS,cAAc;CAEvB,iBAAiB,CAAC,cAAc,cAAc,kBAAkB,OAAO;CACvE,sBAAsB,cAAc;CACpC;AACF;AAEA,MAAa,yCACX,SACA,eACA,iBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,qBAAqB,OAAO,2BAC1B,SACA,gBAAgB,eAAe,YAAY,CAC7C,EACF;AACF,CAAC;AAEH,MAAa,0CACX,SACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,uBAAuB,OAAO,qCAC5B,SACA,oBAAoB,aAAa,CACnC,EACF;AACF,CAAC;;AAGH,MAAa,uCACX,UACA,SACA,eACA,cACA,UAKA,OAAO,IAAI,aAIT;CACA,MAAM,QAAQ,OAAO;CAErB,IAAI,OAAO,gBAAgB,OAAO,OAAO,oBAAoB,KAAK,CAAC,CAAC;CACpE,OAAO,cAAc,oBAAoB,cAAc;CAEvD,OAAO,uBAAuB;EAAE,GAAG;EAAS,OAAO;CAAa,CAAC,CAAC,CAAC,KACjE,OAAO,eAAe,oBAAoB,KAAK,CAAC,CAAC,CAAC,CACpD;CAsDA,QAAO,OApDe,uBAElB,SAAS,aAAa,gBACpB,OAAO,IAAI,aAAa;EACtB,MAAM,iBAAuD,CAAC;EAC9D,IAAI,0BAA0B;EAE9B,MAAM,QAAQ,OAAO,MAAM,aAAa,EACtC,qBAAqB,OAAO,2BAC1B,SACA,gBAAgB,eAAe,cAAc,IAAI,CACnD,CAAC,CAAC,KACA,OAAO,eACL,oBACA,WACF,CACF,EACF,CAAC,CAAC,CAAC,KACD,OAAO,eAAe,gCAAgC,EACpD,WAAW,UAAU;GACnB,IAAI,CAAC,yBAAyB,OAAO;GACrC,eAAe,KAAK,KAAK;GAEzB,OAAO;EACT,EACF,CAAC,GACD,OAAO,SACL,OAAO,WAAW;GAChB,0BAA0B;EAC5B,CAAC,CACH,CACF;EAIA,KAAK,MAAM,SAAS,gBAClB,OAAO,MAAM,KACX,OAAO,eACL,oCACA,WACF,GACA,OAAO,YAAY,UACjB,OAAO,UAAU,MAAM,IAAI,aAAa,oBAAoB,KAAK,CAAC,CAAC,CAAC,CAAC,CACvE,CACF;EAEF,OAAO;CACT,CAAC,CACH,GACF,EAAE,MAAM,cAAc,KAAK,CAC7B,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,KAAK,CAAC,EAAA,CAErC;AAChB,CAAC;AAEH,MAAa,wCACX,UACA,SACA,eACA,UAOA,OAAO,IAAI,aAIT;CACA,MAAM,QAAQ,OAAO;CAErB,IAAI,OAAO,gBAAgB,OAAO,OAAO,oBAAoB,KAAK,CAAC,CAAC;CACpE,OAAO,cAAc,oBAAoB,cAAc;CAEvD,OAAO,uBAAuB,OAAO,CAAC,CAAC,KACrC,OAAO,eAAe,oBAAoB,KAAK,CAAC,CAAC,CAAC,CACpD;CAsBA,QAAO,OApBe,uBAElB,SAAS,aAAa,gBACpB,OAAO,IAAI,aAAa;EACtB,OAAO,OAAO,MAAM,aAAa,EAC/B,uBAAuB,OAAO,qCAC5B,SACA,oBAAoB,eAAe,IAAI,CACzC,CAAC,CAAC,KACA,OAAO,eACL,oBACA,WACF,CACF,EACF,CAAC;CACH,CAAC,CACH,GACF,EAAE,MAAM,cAAc,KAAK,CAC7B,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,KAAK,CAAC,EAAA,CAErC;AAChB,CAAC;AAEH,MAAa,4BACX,aAEA,MAAM,OACJ,qBACA,OAAO,IAAI,WAAW,UAAU,MAAM,mBAAmB,CAC3D;AAEF,MAAa,6BACX,KACA,aAMA,MAAM,OACJ,KACA,OAAO,IAAI,WAAW,UAAU,MAAM,qBAAqB,CAC7D"}
|
|
1
|
+
{"version":3,"file":"password-target.mjs","names":[],"sources":["../../src/drizzle/password-target.ts"],"sourcesContent":["import {\n makeNativePasswordServices,\n makeNativePasswordRegistrationServices,\n requireStandalone,\n type AnyPasswordPersistenceMapping as SharedPasswordMapping,\n type PasswordRegistrationAuthority,\n} from \"@yielded/auth-persistence/Adapter\";\nimport { PasswordPersistence, PasswordUnavailable } from \"@yielded/auth/Password\";\nimport { type Context, Effect, Layer } from \"effect\";\n\nimport { nativeClock } from \"./native-clock\";\nimport type { NativeDatabaseHandle } from \"./native-database\";\nimport {\n nativeTarget,\n coordinateNativeTarget,\n type NativeTargetConfiguration,\n} from \"./native-target\";\nimport type {\n AnyPasswordPersistenceMapping,\n AnyPasswordRegistrationMapping,\n} from \"./password-model\";\nimport type { AnyProofPersistenceMapping } from \"./proof-model\";\nimport { nativeProofMapping } from \"./proof-target\";\nimport { validateDrizzleStorage } from \"./storage-validation\";\n\nconst unavailable = () => PasswordUnavailable.make({});\n\nexport const sqlClientPasswordStandaloneGuard = (marker: Parameters<typeof requireStandalone>[1]) =>\n requireStandalone(unavailable, marker);\n\nconst mapped = (value: AnyPasswordPersistenceMapping): SharedPasswordMapping => ({\n ...value,\n clock: nativeClock(value.clock),\n});\n\nexport const makeTargetPasswordPersistenceServices = Effect.fnUntraced(function* (\n mapping: AnyPasswordPersistenceMapping,\n configuration: NativeTargetConfiguration,\n proofs?: AnyProofPersistenceMapping,\n) {\n yield* validateDrizzleStorage(mapping).pipe(Effect.mapError(unavailable));\n if (proofs !== undefined)\n yield* validateDrizzleStorage(proofs).pipe(Effect.mapError(unavailable));\n if (\n configuration.mode === \"batch\" &&\n (mapping.d1?.primary !== true || (proofs !== undefined && proofs.d1?.primary !== true))\n )\n return yield* unavailable();\n const target = yield* nativeTarget(configuration);\n\n return yield* target.provide(\n makeNativePasswordServices(\n target.tables,\n mapped(mapping),\n proofs === undefined ? undefined : nativeProofMapping(proofs),\n ),\n );\n});\n\nexport const makeTargetPasswordRegistrationServices = Effect.fnUntraced(function* <Registration>(\n mapping: AnyPasswordRegistrationMapping<Registration>,\n configuration: NativeTargetConfiguration,\n) {\n yield* validateDrizzleStorage(mapping).pipe(Effect.mapError(unavailable));\n const target = yield* nativeTarget(configuration);\n\n return yield* target.provide(\n makeNativePasswordRegistrationServices(target.tables, mapping, target.batch),\n );\n});\n\nexport const coordinateTargetPasswordPersistence = <Transaction, A, E, R>(\n database: NativeDatabaseHandle,\n mapping: AnyPasswordPersistenceMapping,\n configuration: NativeTargetConfiguration,\n body: (\n transaction: Transaction,\n services: { readonly passwordPersistence: PasswordPersistence[\"Service\"] },\n ) => Effect.Effect<A, E, R>,\n proofs?: AnyProofPersistenceMapping,\n) =>\n coordinateNativeTarget(\n unavailable,\n database,\n configuration,\n makeTargetPasswordPersistenceServices(mapping, configuration, proofs),\n body,\n );\n\nexport const coordinateTargetPasswordRegistration = <Registration, Transaction, A, E, R>(\n database: NativeDatabaseHandle,\n mapping: AnyPasswordRegistrationMapping<Registration>,\n configuration: NativeTargetConfiguration,\n body: (\n transaction: Transaction,\n services: { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },\n ) => Effect.Effect<A, E, R>,\n) =>\n coordinateNativeTarget(\n unavailable,\n database,\n configuration,\n makeTargetPasswordRegistrationServices(mapping, configuration),\n body,\n );\n\nexport const passwordPersistenceLayer = <E, R>(\n services: Effect.Effect<{ readonly passwordPersistence: PasswordPersistence[\"Service\"] }, E, R>,\n) =>\n Layer.effect(\n PasswordPersistence,\n Effect.map(services, (value) => value.passwordPersistence),\n );\n\nexport const passwordRegistrationLayer = <Id, Registration, E, R>(\n target: Context.Key<Id, PasswordRegistrationAuthority<Registration>>,\n services: Effect.Effect<\n { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },\n E,\n R\n >,\n) =>\n Layer.effect(\n target,\n Effect.map(services, (value) => value.registrationAuthority),\n );\n"],"mappings":";;;;;;;;AAyBA,MAAM,oBAAoB,oBAAoB,KAAK,CAAC,CAAC;AAKrD,MAAM,UAAU,WAAiE;CAC/E,GAAG;CACH,OAAO,YAAY,MAAM,KAAK;AAChC;AAEA,MAAa,wCAAwC,OAAO,WAAW,WACrE,SACA,eACA,QACA;CACA,OAAO,uBAAuB,OAAO,CAAC,CAAC,KAAK,OAAO,SAAS,WAAW,CAAC;CACxE,IAAI,WAAW,KAAA,GACb,OAAO,uBAAuB,MAAM,CAAC,CAAC,KAAK,OAAO,SAAS,WAAW,CAAC;CACzE,IACE,cAAc,SAAS,YACtB,QAAQ,IAAI,YAAY,QAAS,WAAW,KAAA,KAAa,OAAO,IAAI,YAAY,OAEjF,OAAO,OAAO,YAAY;CAC5B,MAAM,SAAS,OAAO,aAAa,aAAa;CAEhD,OAAO,OAAO,OAAO,QACnB,2BACE,OAAO,QACP,OAAO,OAAO,GACd,WAAW,KAAA,IAAY,KAAA,IAAY,mBAAmB,MAAM,CAC9D,CACF;AACF,CAAC;AAED,MAAa,yCAAyC,OAAO,WAAW,WACtE,SACA,eACA;CACA,OAAO,uBAAuB,OAAO,CAAC,CAAC,KAAK,OAAO,SAAS,WAAW,CAAC;CACxE,MAAM,SAAS,OAAO,aAAa,aAAa;CAEhD,OAAO,OAAO,OAAO,QACnB,uCAAuC,OAAO,QAAQ,SAAS,OAAO,KAAK,CAC7E;AACF,CAAC;AAED,MAAa,uCACX,UACA,SACA,eACA,MAIA,WAEA,uBACE,aACA,UACA,eACA,sCAAsC,SAAS,eAAe,MAAM,GACpE,IACF;AAEF,MAAa,wCACX,UACA,SACA,eACA,SAKA,uBACE,aACA,UACA,eACA,uCAAuC,SAAS,aAAa,GAC7D,IACF;AAEF,MAAa,4BACX,aAEA,MAAM,OACJ,qBACA,OAAO,IAAI,WAAW,UAAU,MAAM,mBAAmB,CAC3D;AAEF,MAAa,6BACX,QACA,aAMA,MAAM,OACJ,QACA,OAAO,IAAI,WAAW,UAAU,MAAM,qBAAqB,CAC7D"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PersistenceMappingError as PersistenceMappingError$1, column, isMappedConstraintConflict, provisioningFingerprint } from "./model.mjs";
|
|
2
|
+
import { NativeDatabase, nativeDatabase } from "./native-database.mjs";
|
|
2
3
|
import { validateDrizzleStorage } from "./storage-validation.mjs";
|
|
3
|
-
import { nativeDatabase } from "./native-database.mjs";
|
|
4
4
|
import { Database } from "./pg-database.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { withStorageValidation } from "@yielded/auth-persistence/Adapter";
|
|
6
6
|
import { ExternalIdentityMutation, IdentityConflict, IdentityUnavailable, SubjectProvisioned, SubjectProvisioner } from "@yielded/auth/Identity";
|
|
7
7
|
import { and, eq } from "drizzle-orm";
|
|
8
8
|
import { Cause, Effect, Schema } from "effect";
|
|
@@ -21,8 +21,6 @@ const makePgSubjectProvisioningServices = Effect.fnUntraced(function* (mapping)
|
|
|
21
21
|
const requestFingerprintColumn = column(requestTable, mapping.provisioningRequest.fingerprint);
|
|
22
22
|
const requestSubjectColumn = column(requestTable, mapping.provisioningRequest.subjectId);
|
|
23
23
|
const identifierTable = mapping.identifier.table;
|
|
24
|
-
const identifierNamespaceColumn = column(identifierTable, mapping.identifier.namespace);
|
|
25
|
-
const identifierValueColumn = column(identifierTable, mapping.identifier.value);
|
|
26
24
|
const findReceipt = Effect.fn("DrizzlePgIdentity.findReceipt")(function* (requestId) {
|
|
27
25
|
return (yield* db.select({
|
|
28
26
|
fingerprint: requestFingerprintColumn,
|
|
@@ -51,8 +49,7 @@ const makePgSubjectProvisioningServices = Effect.fnUntraced(function* (mapping)
|
|
|
51
49
|
if (cause.reasons.length === 0 || !cause.reasons.every((reason) => Cause.isFailReason(reason) && isMappedConstraintConflict(mapping.isConstraintConflict, reason.error))) return Effect.failCause(cause);
|
|
52
50
|
return findReceipt(input.requestId).pipe(Effect.flatMap((receipt) => {
|
|
53
51
|
if (receipt !== void 0 && receipt.fingerprint === fingerprint) return Effect.succeed(receipt.subjectId);
|
|
54
|
-
|
|
55
|
-
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()));
|
|
52
|
+
return IdentityConflict.make();
|
|
56
53
|
}));
|
|
57
54
|
}));
|
|
58
55
|
const subjectId = yield* mapping.subjectId.toSubject(nativeId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-identity.mjs","names":["DatabaseService","PersistenceMappingError"],"sources":["../../src/drizzle/pg-identity.ts"],"sourcesContent":["import { withStorageValidation, NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport {\n ExternalIdentityMutation,\n IdentityConflict,\n IdentityUnavailable,\n SubjectProvisioned,\n type ExternalIdentity,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n} from \"@yielded/auth/Identity\";\nimport { reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport type { SubjectId } 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 { and, eq } from \"drizzle-orm\";\nimport type { EffectPgDatabase as PgDatabase } from \"drizzle-orm/effect-postgres\";\nimport { type AnyPgTable, type PgColumn } from \"drizzle-orm/pg-core\";\nimport { Cause, Effect, Schema } from \"effect\";\n\nimport {\n column,\n PersistenceMappingError,\n isMappedConstraintConflict,\n provisioningFingerprint,\n type ExternalIdentityTables,\n type IdentityTables,\n type SubjectProvisioningTables,\n} from \"./model\";\nimport { nativeDatabase } from \"./native-database\";\nimport { Database as DatabaseService } from \"./pg-database\";\nimport { validateDrizzleStorage } from \"./storage-validation\";\n\ntype RuntimeDatabase = PgDatabase<any>;\n\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\nexport const makePgSubjectProvisioningServices = Effect.fnUntraced(function* <\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\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 = Effect.fnUntraced(function* <\n Subject extends AnyPgTable,\n External extends AnyPgTable,\n NativeId,\n>(mapping: ExternalIdentityTables<Subject, External, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\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 = Effect.fnUntraced(function* <\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n External extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {\n return {\n ...(yield* makePgSubjectProvisioningServices(mapping)),\n ...(yield* makePgExternalIdentityServices(mapping)),\n };\n}, withStorageValidation);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pg-identity.mjs","names":["DatabaseService","PersistenceMappingError"],"sources":["../../src/drizzle/pg-identity.ts"],"sourcesContent":["import { withStorageValidation } from \"@yielded/auth-persistence/Adapter\";\nimport {\n ExternalIdentityMutation,\n IdentityConflict,\n IdentityUnavailable,\n SubjectProvisioned,\n type ExternalIdentity,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n} from \"@yielded/auth/Identity\";\nimport { reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport type { SubjectId } 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 { and, eq } from \"drizzle-orm\";\nimport type { EffectPgDatabase as PgDatabase } from \"drizzle-orm/effect-postgres\";\nimport { type AnyPgTable, type PgColumn } from \"drizzle-orm/pg-core\";\nimport { Cause, Effect, Schema } from \"effect\";\n\nimport {\n column,\n PersistenceMappingError,\n isMappedConstraintConflict,\n provisioningFingerprint,\n type ExternalIdentityTables,\n type IdentityTables,\n type SubjectProvisioningTables,\n} from \"./model\";\nimport { NativeDatabase, nativeDatabase } from \"./native-database\";\nimport { Database as DatabaseService } from \"./pg-database\";\nimport { validateDrizzleStorage } from \"./storage-validation\";\n\ntype RuntimeDatabase = PgDatabase<any>;\n\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\nexport const makePgSubjectProvisioningServices = Effect.fnUntraced(function* <\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\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\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\n return 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 = Effect.fnUntraced(function* <\n Subject extends AnyPgTable,\n External extends AnyPgTable,\n NativeId,\n>(mapping: ExternalIdentityTables<Subject, External, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\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 = Effect.fnUntraced(function* <\n Subject extends AnyPgTable,\n Identifier extends AnyPgTable,\n External extends AnyPgTable,\n Request extends AnyPgTable,\n NativeId,\n>(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {\n return {\n ...(yield* makePgSubjectProvisioningServices(mapping)),\n ...(yield* makePgExternalIdentityServices(mapping)),\n };\n}, withStorageValidation);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { NativeDatabase, nativeDatabase } from "./native-database.mjs";
|
|
2
|
+
import { coordinateTargetPhonePersistence, makeTargetPhonePersistenceServices } from "./phone-target.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
import { PhonePersistence, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
|
|
5
|
+
//#region src/drizzle/phone-drivers.ts
|
|
6
|
+
/** Physical driver selection; the phone workflow has one implementation.
|
|
7
|
+
* Erase only foreign table/ID callback variance at the validated mapping boundary;
|
|
8
|
+
* decoded phone and subject values still pass through their owning codecs. */
|
|
9
|
+
const makePhoneTarget = (databaseService, configuration) => {
|
|
10
|
+
function coordinatePhonePersistence(acquire, options, body) {
|
|
11
|
+
return Effect.flatMap(nativeDatabase(acquire), (database) => coordinateTargetPhonePersistence(database, options.mapping, configuration, (transaction, services) => {
|
|
12
|
+
const work = body.pipe(Effect.provideService(PhonePersistence, services.phonePersistence), Effect.provideService(PhoneSignInTargets, services.phoneSignInTargets));
|
|
13
|
+
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
makePhonePersistenceServices: (mapping) => makeTargetPhonePersistenceServices(mapping, configuration).pipe(Effect.provideServiceEffect(NativeDatabase, nativeDatabase(databaseService))),
|
|
18
|
+
coordinatePhonePersistence
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { makePhoneTarget };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=phone-drivers.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phone-drivers.mjs","names":[],"sources":["../../src/drizzle/phone-drivers.ts"],"sourcesContent":["import type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n PhonePersistence,\n PhoneSignInTargets,\n type PhoneConfigurationError,\n type PhoneOtpUnavailable,\n} from \"@yielded/auth/PhoneOtp\";\nimport type { Table } from \"drizzle-orm\";\nimport { type Context, Effect, type Crypto } from \"effect\";\n\nimport type { NativeDriverDatabase, NativeDriverTransaction } from \"./driver-types\";\nimport { NativeDatabase, nativeDatabase } from \"./native-database\";\nimport type { NativeTargetConfiguration } from \"./native-target\";\nimport type { AnyPhoneMapping, PhoneMapping } from \"./phone-model\";\nimport {\n coordinateTargetPhonePersistence,\n makeTargetPhonePersistenceServices,\n} from \"./phone-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\n/** Physical driver selection; the phone workflow has one implementation.\n * Erase only foreign table/ID callback variance at the validated mapping boundary;\n * decoded phone and subject values still pass through their owning codecs. */\nexport const makePhoneTarget = <DatabaseId, D extends NativeDriverDatabase>(\n databaseService: Context.Service<DatabaseId, D>,\n configuration: NativeTargetConfiguration,\n) => {\n function coordinatePhonePersistence<\n Database extends D,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n Proof extends Table,\n NativeId,\n A,\n E,\n R,\n DE,\n DR,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PhoneMapping<Subject, Identifier, Credential, Proof, NativeId>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n ): Effect.Effect<\n A,\n E | DE | PhoneOtpUnavailable | PhoneConfigurationError,\n Exclude<R, PhonePersistence | PhoneSignInTargets> | DR | LifecycleHooks | Crypto.Crypto\n >;\n function coordinatePhonePersistence<\n Database extends D,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n Proof extends Table,\n NativeId,\n A,\n E,\n R,\n DE,\n DR,\n TxId,\n TxShape,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PhoneMapping<Subject, Identifier, Credential, Proof, NativeId>;\n readonly transaction: SuppliedService<\n TxId,\n NoInfer<NativeDriverTransaction<Database>>,\n TxShape\n >;\n },\n body: Effect.Effect<A, E, R>,\n ): Effect.Effect<\n A,\n E | DE | PhoneOtpUnavailable | PhoneConfigurationError,\n Exclude<R, PhonePersistence | PhoneSignInTargets | TxId> | DR | LifecycleHooks | Crypto.Crypto\n >;\n function coordinatePhonePersistence<\n Database extends D,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n Proof extends Table,\n NativeId,\n A,\n E,\n R,\n DE,\n DR,\n TxId,\n TxShape,\n >(\n acquire: Effect.Effect<Database, DE, DR>,\n options: {\n readonly mapping: PhoneMapping<Subject, Identifier, Credential, Proof, NativeId>;\n readonly transaction?: SuppliedService<\n TxId,\n NoInfer<NativeDriverTransaction<Database>>,\n TxShape\n >;\n },\n body: Effect.Effect<A, E, R>,\n ) {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPhonePersistence(\n database,\n options.mapping as unknown as AnyPhoneMapping,\n configuration,\n (transaction: NativeDriverTransaction<Database>, services) => {\n const work = body.pipe(\n Effect.provideService(PhonePersistence, services.phonePersistence),\n Effect.provideService(PhoneSignInTargets, services.phoneSignInTargets),\n );\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n }\n\n return {\n makePhonePersistenceServices: <\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n Proof extends Table,\n NativeId,\n >(\n mapping: PhoneMapping<Subject, Identifier, Credential, Proof, NativeId>,\n ) =>\n makeTargetPhonePersistenceServices(mapping as unknown as AnyPhoneMapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(databaseService)),\n ),\n coordinatePhonePersistence,\n };\n};\n"],"mappings":";;;;;;;;AAuBA,MAAa,mBACX,iBACA,kBACG;CAuDH,SAAS,2BAeP,SACA,SAQA,MACA;EACA,OAAO,OAAO,QAAQ,eAAe,OAAO,IAAI,aAC9C,iCACE,UACA,QAAQ,SACR,gBACC,aAAgD,aAAa;GAC5D,MAAM,OAAO,KAAK,KAChB,OAAO,eAAe,kBAAkB,SAAS,gBAAgB,GACjE,OAAO,eAAe,oBAAoB,SAAS,kBAAkB,CACvE;GAEA,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;EAC1F,CACF,CACF;CACF;CAEA,OAAO;EACL,+BAOE,YAEA,mCAAmC,SAAuC,aAAa,CAAC,CAAC,KACvF,OAAO,qBAAqB,gBAAgB,eAAe,eAAe,CAAC,CAC7E;EACF;CACF;AACF"}
|
|
@@ -1,113 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { DrizzleTableModel } from "./table-model.mjs";
|
|
2
|
+
import { ProofPersistenceMapping } from "./proof-model.mjs";
|
|
3
|
+
import { PersistenceMappingError as PersistenceMappingError$1 } from "./model.mjs";
|
|
4
|
+
import * as Shared from "@yielded/auth-persistence/Adapter";
|
|
5
|
+
import { requiredPhoneConstraints } from "@yielded/auth-persistence/Adapter";
|
|
6
|
+
import { SQL, Table } from "drizzle-orm";
|
|
4
7
|
import { Effect, Layer } from "effect";
|
|
5
|
-
import {
|
|
6
|
-
import { SubjectId } from "@yielded/auth/Schema";
|
|
7
|
-
import { PhoneAdmission, PhoneAdmissionPolicy, PhoneLifecyclePolicy, PhoneNumber, PhonePersistence, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
|
|
8
|
+
import { PhonePersistence, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
|
|
8
9
|
//#region src/drizzle/phone-model.d.ts
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
readonly [proofMapping]: AnyProofPersistenceMapping;
|
|
13
|
-
}
|
|
14
|
-
export declare const phoneProofCompletionMapping: <Rq extends Table, S extends Table, G extends Table, Cn extends Table, Rs extends Table, A extends Table, F extends Table, C extends Table, Sub extends Table, I extends Table, Cr extends Table, N>(mapping: ProofPersistenceMapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, N>) => PhoneProofCompletionMapping;
|
|
15
|
-
export type PhoneColumn<T extends Table> = Extract<keyof T["_"]["columns"], string>;
|
|
16
|
-
export type PhoneMappingSource<M, R = never> = M | Effect.Effect<M, PersistenceMappingError, R>;
|
|
17
|
-
export declare const requiredPhoneConstraints: {
|
|
18
|
-
readonly subject: "unique(id)";
|
|
19
|
-
readonly identifier: "unique(namespace,value)";
|
|
20
|
-
readonly credential: "unique(credentialId)";
|
|
21
|
-
readonly state: "unique(scope)";
|
|
10
|
+
export type PhoneMappingSource<M, R = never> = M | Effect.Effect<M, PersistenceMappingError$1, R>;
|
|
11
|
+
export type PhoneMapping<S extends Table, I extends Table, C extends Table, P extends Table, N> = Omit<Shared.PhoneMapping<DrizzleTableModel<S>, DrizzleTableModel<I>, DrizzleTableModel<C>, DrizzleTableModel<P>, N, SQL>, "proofs"> & {
|
|
12
|
+
readonly proofs: ProofPersistenceMapping<P, S, N>;
|
|
22
13
|
};
|
|
23
|
-
/** Consumer-owned schema; encoders and allocators are synchronous and side-effect free.
|
|
24
|
-
* State stores permanent number custody and command tombstones, plus bounded admission
|
|
25
|
-
* counters. Never delete custody rows to make a recycled number eligible. A consumer's
|
|
26
|
-
* explicit recovery workflow may resolve custody only after independent authentication.
|
|
27
|
-
* Subject defaults own account provisioning; no email/profile schema is prescribed. */
|
|
28
|
-
export interface PhoneMapping<S extends Table, I extends Table, C extends Table, T extends Table, N> {
|
|
29
|
-
readonly moduleId: string;
|
|
30
|
-
readonly policy: PhoneLifecyclePolicy;
|
|
31
|
-
readonly admission: PhoneAdmissionPolicy;
|
|
32
|
-
readonly constraints: typeof requiredPhoneConstraints;
|
|
33
|
-
readonly proofs: PhoneProofCompletionMapping;
|
|
34
|
-
readonly subjectIds: {
|
|
35
|
-
readonly toNative: (id: SubjectId) => N;
|
|
36
|
-
readonly toSubject: (id: N) => SubjectId;
|
|
37
|
-
readonly allocate: () => N;
|
|
38
|
-
};
|
|
39
|
-
readonly subject: {
|
|
40
|
-
readonly table: S;
|
|
41
|
-
readonly id: PhoneColumn<S>;
|
|
42
|
-
readonly securityRevision: PhoneColumn<S>;
|
|
43
|
-
readonly activeCondition: SQL;
|
|
44
|
-
readonly decodeRequirement: (row: InferSelectModel<S>) => AuthenticationRequirement;
|
|
45
|
-
/** Current action policy, independently from primary sign-in assurance. */
|
|
46
|
-
readonly decodeActionRequirement?: (row: InferSelectModel<S>, action: "verify" | "change") => AuthenticationRequirement;
|
|
47
|
-
readonly encodeInsert: (input: {
|
|
48
|
-
readonly id: N;
|
|
49
|
-
readonly securityRevision: string;
|
|
50
|
-
readonly phoneNumber: PhoneNumber;
|
|
51
|
-
}) => InferInsertModel<S>;
|
|
52
|
-
};
|
|
53
|
-
readonly identifier: {
|
|
54
|
-
readonly table: I;
|
|
55
|
-
readonly namespace: PhoneColumn<I>;
|
|
56
|
-
readonly value: PhoneColumn<I>;
|
|
57
|
-
readonly subjectId: PhoneColumn<I>;
|
|
58
|
-
readonly revision: PhoneColumn<I>;
|
|
59
|
-
readonly verifiedAt: PhoneColumn<I>;
|
|
60
|
-
readonly status: PhoneColumn<I>;
|
|
61
|
-
readonly activeCondition: SQL;
|
|
62
|
-
readonly encodeStatus: (active: boolean) => unknown;
|
|
63
|
-
readonly encodeInsert: (input: {
|
|
64
|
-
readonly phoneNumber: PhoneNumber;
|
|
65
|
-
readonly subjectId: N;
|
|
66
|
-
readonly revision: string;
|
|
67
|
-
readonly verifiedAtMillis: number;
|
|
68
|
-
readonly active: boolean;
|
|
69
|
-
}) => InferInsertModel<I>;
|
|
70
|
-
};
|
|
71
|
-
readonly credential: {
|
|
72
|
-
readonly table: C;
|
|
73
|
-
readonly id: PhoneColumn<C>;
|
|
74
|
-
readonly subjectId: PhoneColumn<C>;
|
|
75
|
-
readonly revision: PhoneColumn<C>;
|
|
76
|
-
readonly status: PhoneColumn<C>;
|
|
77
|
-
readonly activeCondition: SQL;
|
|
78
|
-
readonly encodeStatus: (active: boolean) => unknown;
|
|
79
|
-
readonly encodeInsert: (input: {
|
|
80
|
-
readonly credentialId: string;
|
|
81
|
-
readonly subjectId: N;
|
|
82
|
-
readonly revision: string;
|
|
83
|
-
readonly active: boolean;
|
|
84
|
-
}) => InferInsertModel<C>;
|
|
85
|
-
};
|
|
86
|
-
readonly state: {
|
|
87
|
-
readonly table: T;
|
|
88
|
-
readonly scope: PhoneColumn<T>;
|
|
89
|
-
readonly state: PhoneColumn<T>;
|
|
90
|
-
readonly version: PhoneColumn<T>;
|
|
91
|
-
readonly encodeInsert: (input: {
|
|
92
|
-
readonly scope: string;
|
|
93
|
-
readonly state: string;
|
|
94
|
-
readonly version: string;
|
|
95
|
-
}) => InferInsertModel<T>;
|
|
96
|
-
};
|
|
97
|
-
readonly encodeInstant: (millis: number) => unknown;
|
|
98
|
-
readonly engineNowMillis: SQL;
|
|
99
|
-
}
|
|
100
|
-
export interface D1PhoneMapping {
|
|
101
|
-
readonly d1: {
|
|
102
|
-
readonly primary: true;
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
14
|
export interface PhonePersistenceServices {
|
|
106
15
|
readonly phonePersistence: PhonePersistence["Service"];
|
|
107
|
-
readonly phoneAdmission: PhoneAdmission["Service"];
|
|
108
16
|
readonly phoneSignInTargets: PhoneSignInTargets["Service"];
|
|
109
17
|
}
|
|
110
|
-
/** Bundle phone storage
|
|
111
|
-
export declare const phonePersistenceLayer: <E, R>(services: Effect.Effect<PhonePersistenceServices, E, R>) => Layer.Layer<
|
|
18
|
+
/** Bundle phone storage and lookup with empty hook defaults. */
|
|
19
|
+
export declare const phonePersistenceLayer: <E, R>(services: Effect.Effect<PhonePersistenceServices, E, R>) => Layer.Layer<PhonePersistence | PhoneSignInTargets, E, Exclude<Exclude<R, import("effect/Scope").Scope>, import("@yielded/auth/Hooks").LifecycleHooks>>;
|
|
112
20
|
//#endregion
|
|
21
|
+
export { requiredPhoneConstraints };
|
|
113
22
|
//# sourceMappingURL=phone-model.d.mts.map
|
|
@@ -1,39 +1,11 @@
|
|
|
1
|
+
import { requiredPhoneConstraints } from "@yielded/auth-persistence/Adapter";
|
|
1
2
|
import { Effect, Layer } from "effect";
|
|
2
3
|
import { hooksLayer } from "@yielded/auth/Persistence";
|
|
3
|
-
import {
|
|
4
|
+
import { PhonePersistence, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
|
|
4
5
|
//#region src/drizzle/phone-model.ts
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
...mapping,
|
|
8
|
-
request: Object.freeze({ ...mapping.request }),
|
|
9
|
-
series: Object.freeze({ ...mapping.series }),
|
|
10
|
-
generation: Object.freeze({ ...mapping.generation }),
|
|
11
|
-
continuation: Object.freeze({ ...mapping.continuation }),
|
|
12
|
-
rateScope: Object.freeze({ ...mapping.rateScope }),
|
|
13
|
-
abuseEvent: Object.freeze({ ...mapping.abuseEvent }),
|
|
14
|
-
failureEvent: Object.freeze({ ...mapping.failureEvent }),
|
|
15
|
-
command: Object.freeze({ ...mapping.command }),
|
|
16
|
-
constraints: Object.freeze({ ...mapping.constraints }),
|
|
17
|
-
authority: Object.freeze({
|
|
18
|
-
...mapping.authority,
|
|
19
|
-
identifier: Object.freeze({ ...mapping.authority.identifier }),
|
|
20
|
-
...mapping.authority.subject === void 0 ? {} : { subject: Object.freeze({ ...mapping.authority.subject }) },
|
|
21
|
-
...mapping.authority.credential === void 0 ? {} : { credential: Object.freeze({ ...mapping.authority.credential }) },
|
|
22
|
-
...mapping.authority.subjectId === void 0 ? {} : { subjectId: Object.freeze({ ...mapping.authority.subjectId }) }
|
|
23
|
-
}),
|
|
24
|
-
...mapping.d1 === void 0 ? {} : { d1: Object.freeze({ ...mapping.d1 }) }
|
|
25
|
-
}) });
|
|
26
|
-
/** @internal */
|
|
27
|
-
const phoneProofs = (mapping) => mapping[proofMapping];
|
|
28
|
-
const requiredPhoneConstraints = {
|
|
29
|
-
subject: "unique(id)",
|
|
30
|
-
identifier: "unique(namespace,value)",
|
|
31
|
-
credential: "unique(credentialId)",
|
|
32
|
-
state: "unique(scope)"
|
|
33
|
-
};
|
|
34
|
-
/** Bundle phone storage, admission, and lookup with empty hook defaults. */
|
|
35
|
-
const phonePersistenceLayer = (services) => Layer.unwrap(Effect.map(services, (value) => Layer.mergeAll(Layer.succeed(PhonePersistence, value.phonePersistence), Layer.succeed(PhoneAdmission, value.phoneAdmission), Layer.succeed(PhoneSignInTargets, value.phoneSignInTargets)))).pipe(Layer.provide(hooksLayer));
|
|
6
|
+
/** Bundle phone storage and lookup with empty hook defaults. */
|
|
7
|
+
const phonePersistenceLayer = (services) => Layer.unwrap(Effect.map(services, (value) => Layer.mergeAll(Layer.succeed(PhonePersistence, value.phonePersistence), Layer.succeed(PhoneSignInTargets, value.phoneSignInTargets)))).pipe(Layer.provide(hooksLayer));
|
|
36
8
|
//#endregion
|
|
37
|
-
export { phonePersistenceLayer,
|
|
9
|
+
export { phonePersistenceLayer, requiredPhoneConstraints };
|
|
38
10
|
|
|
39
11
|
//# sourceMappingURL=phone-model.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phone-model.mjs","names":[],"sources":["../../src/drizzle/phone-model.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"phone-model.mjs","names":[],"sources":["../../src/drizzle/phone-model.ts"],"sourcesContent":["import type * as Shared from \"@yielded/auth-persistence/Adapter\";\nimport { hooksLayer } from \"@yielded/auth/Persistence\";\nimport { PhonePersistence, PhoneSignInTargets } from \"@yielded/auth/PhoneOtp\";\nimport type { SQL, Table } from \"drizzle-orm\";\nimport { Effect, Layer } from \"effect\";\n\nimport type { PersistenceMappingError } from \"./model\";\nimport type { ProofPersistenceMapping } from \"./proof-model\";\nimport type { DrizzleTableModel } from \"./table-model\";\n\nexport { requiredPhoneConstraints } from \"@yielded/auth-persistence/Adapter\";\nexport type PhoneMappingSource<M, R = never> = M | Effect.Effect<M, PersistenceMappingError, R>;\n\nexport type PhoneMapping<\n S extends Table,\n I extends Table,\n C extends Table,\n P extends Table,\n N,\n> = Omit<\n Shared.PhoneMapping<\n DrizzleTableModel<S>,\n DrizzleTableModel<I>,\n DrizzleTableModel<C>,\n DrizzleTableModel<P>,\n N,\n SQL\n >,\n \"proofs\"\n> & { readonly proofs: ProofPersistenceMapping<P, S, N> };\n\nexport type AnyPhoneMapping = PhoneMapping<Table, Table, Table, Table, unknown>;\n\nexport interface PhonePersistenceServices {\n readonly phonePersistence: PhonePersistence[\"Service\"];\n readonly phoneSignInTargets: PhoneSignInTargets[\"Service\"];\n}\n\n/** Bundle phone storage and lookup with empty hook defaults. */\nexport const phonePersistenceLayer = <E, R>(\n services: Effect.Effect<PhonePersistenceServices, E, R>,\n) =>\n Layer.unwrap(\n Effect.map(services, (value) =>\n Layer.mergeAll(\n Layer.succeed(PhonePersistence, value.phonePersistence),\n Layer.succeed(PhoneSignInTargets, value.phoneSignInTargets),\n ),\n ),\n ).pipe(Layer.provide(hooksLayer));\n"],"mappings":";;;;;;AAuCA,MAAa,yBACX,aAEA,MAAM,OACJ,OAAO,IAAI,WAAW,UACpB,MAAM,SACJ,MAAM,QAAQ,kBAAkB,MAAM,gBAAgB,GACtD,MAAM,QAAQ,oBAAoB,MAAM,kBAAkB,CAC5D,CACF,CACF,CAAC,CAAC,KAAK,MAAM,QAAQ,UAAU,CAAC"}
|