@yielded/auth-persistence 0.1.0-beta.24 → 0.1.0-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -8
- package/dist/Adapter.d.mts +47 -33
- package/dist/Adapter.mjs +36 -23
- package/dist/OAuthPersistence.d.mts +35 -51
- package/dist/OAuthPersistence.mjs +60 -68
- package/dist/OAuthPersistence.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/internal/browser-login.d.mts +1 -1
- package/dist/internal/browser-login.mjs +29 -9
- package/dist/internal/browser-login.mjs.map +1 -1
- package/dist/internal/configuration.d.mts +13 -8
- package/dist/internal/configuration.mjs.map +1 -1
- package/dist/internal/crypto.d.mts +1 -0
- package/dist/internal/crypto.mjs +1 -1
- package/dist/internal/d1-planning.mjs +8 -0
- package/dist/internal/d1-planning.mjs.map +1 -0
- package/dist/internal/email-native-state.mjs +135 -0
- package/dist/internal/email-native-state.mjs.map +1 -0
- package/dist/internal/email-native.d.mts +17 -0
- package/dist/internal/email-native.mjs +245 -0
- package/dist/internal/email-native.mjs.map +1 -0
- package/dist/internal/email-policy.mjs +92 -0
- package/dist/internal/email-policy.mjs.map +1 -0
- package/dist/internal/email-registration-native.d.mts +38 -0
- package/dist/internal/email-registration-native.mjs +171 -0
- package/dist/internal/email-registration-native.mjs.map +1 -0
- package/dist/internal/models/email-model.d.mts +40 -104
- package/dist/internal/models/email-model.mjs +3 -5
- package/dist/internal/models/email-model.mjs.map +1 -1
- package/dist/internal/models/oauth-connected-model.d.mts +44 -213
- package/dist/internal/models/oauth-connected-model.mjs +6 -14
- package/dist/internal/models/oauth-connected-model.mjs.map +1 -1
- package/dist/internal/models/oauth-model.d.mts +95 -244
- package/dist/internal/models/oauth-model.mjs +28 -22
- package/dist/internal/models/oauth-model.mjs.map +1 -1
- package/dist/internal/models/passkey-model.d.mts +11 -147
- package/dist/internal/models/passkey-model.mjs +5 -24
- package/dist/internal/models/passkey-model.mjs.map +1 -1
- package/dist/internal/models/passkey-registration-ceremony-model.d.mts +5 -39
- package/dist/internal/models/passkey-write-model.d.mts +17 -75
- package/dist/internal/models/passkey-write-model.mjs +1 -7
- package/dist/internal/models/passkey-write-model.mjs.map +1 -1
- package/dist/internal/models/password-model.d.mts +16 -82
- package/dist/internal/models/password-model.mjs +1 -4
- package/dist/internal/models/password-model.mjs.map +1 -1
- package/dist/internal/models/phone-model.d.mts +86 -0
- package/dist/internal/models/phone-model.mjs +10 -0
- package/dist/internal/models/phone-model.mjs.map +1 -0
- package/dist/internal/models/proof-model.d.mts +43 -272
- package/dist/internal/models/proof-model.mjs +2 -10
- package/dist/internal/models/proof-model.mjs.map +1 -1
- package/dist/internal/models/session-model.d.mts +74 -93
- package/dist/internal/models/session-model.mjs +3 -11
- package/dist/internal/models/session-model.mjs.map +1 -1
- package/dist/internal/models/step-up-model.d.mts +12 -50
- package/dist/internal/models/step-up-model.mjs +2 -4
- package/dist/internal/models/step-up-model.mjs.map +1 -1
- package/dist/internal/models/totp-model.d.mts +76 -0
- package/dist/internal/models/totp-model.mjs +10 -0
- package/dist/internal/models/totp-model.mjs.map +1 -0
- package/dist/internal/native-sql-table.d.mts +21 -4
- package/dist/internal/native-sql-table.mjs +9 -5
- package/dist/internal/native-sql-table.mjs.map +1 -1
- package/dist/internal/oauth/native-accounts.d.mts +17 -0
- package/dist/internal/oauth/native-accounts.mjs +290 -0
- package/dist/internal/oauth/native-accounts.mjs.map +1 -0
- package/dist/internal/oauth/native-connected-state.d.mts +11 -0
- package/dist/internal/oauth/native-connected-state.mjs +146 -0
- package/dist/internal/oauth/native-connected-state.mjs.map +1 -0
- package/dist/internal/oauth/native-connected.d.mts +15 -0
- package/dist/internal/oauth/native-connected.mjs +462 -0
- package/dist/internal/oauth/native-connected.mjs.map +1 -0
- package/dist/internal/oauth/native-flow.mjs +138 -0
- package/dist/internal/oauth/native-flow.mjs.map +1 -0
- package/dist/internal/oauth/native-layers.d.mts +24 -0
- package/dist/internal/oauth/native-layers.mjs +13 -0
- package/dist/internal/oauth/native-layers.mjs.map +1 -0
- package/dist/internal/oauth/native-mutation.mjs +122 -0
- package/dist/internal/oauth/native-mutation.mjs.map +1 -0
- package/dist/internal/oauth/native-registration.d.mts +24 -0
- package/dist/internal/oauth/native-registration.mjs +328 -0
- package/dist/internal/oauth/native-registration.mjs.map +1 -0
- package/dist/internal/oauth/native-revocations.d.mts +17 -0
- package/dist/internal/oauth/native-revocations.mjs +106 -0
- package/dist/internal/oauth/native-revocations.mjs.map +1 -0
- package/dist/internal/oauth/native-sign-in.d.mts +17 -0
- package/dist/internal/oauth/native-sign-in.mjs +50 -0
- package/dist/internal/oauth/native-sign-in.mjs.map +1 -0
- package/dist/internal/oauth/native-state.d.mts +10 -0
- package/dist/internal/oauth/native-state.mjs +214 -0
- package/dist/internal/oauth/native-state.mjs.map +1 -0
- package/dist/internal/oauth/state.d.mts +10 -0
- package/dist/internal/oauth/state.mjs +3 -27
- package/dist/internal/oauth/state.mjs.map +1 -1
- package/dist/internal/passkey-actions.mjs +55 -0
- package/dist/internal/passkey-actions.mjs.map +1 -0
- package/dist/internal/passkey-inputs.mjs +73 -0
- package/dist/internal/passkey-inputs.mjs.map +1 -0
- package/dist/internal/passkey-managed.mjs +224 -0
- package/dist/internal/passkey-managed.mjs.map +1 -0
- package/dist/internal/passkey-native-ceremony.d.mts +35 -0
- package/dist/internal/passkey-native-ceremony.mjs +38 -0
- package/dist/internal/passkey-native-ceremony.mjs.map +1 -0
- package/dist/internal/passkey-native-flow.mjs +91 -0
- package/dist/internal/passkey-native-flow.mjs.map +1 -0
- package/dist/internal/passkey-native-registration.d.mts +10 -0
- package/dist/internal/passkey-native-registration.mjs +114 -0
- package/dist/internal/passkey-native-registration.mjs.map +1 -0
- package/dist/internal/passkey-native-state.d.mts +15 -0
- package/dist/internal/passkey-native-state.mjs +186 -0
- package/dist/internal/passkey-native-state.mjs.map +1 -0
- package/dist/internal/passkey-native-write.d.mts +82 -0
- package/dist/internal/passkey-native-write.mjs +330 -0
- package/dist/internal/passkey-native-write.mjs.map +1 -0
- package/dist/internal/passkey-native.d.mts +835 -0
- package/dist/internal/passkey-native.mjs +175 -0
- package/dist/internal/passkey-native.mjs.map +1 -0
- package/dist/internal/passkey-policy.mjs +115 -0
- package/dist/internal/passkey-policy.mjs.map +1 -0
- package/dist/internal/password-credentials.mjs +38 -9
- package/dist/internal/password-credentials.mjs.map +1 -1
- package/dist/internal/password-native.d.mts +14 -0
- package/dist/internal/password-native.mjs +292 -0
- package/dist/internal/password-native.mjs.map +1 -0
- package/dist/internal/password-policy.mjs +93 -0
- package/dist/internal/password-policy.mjs.map +1 -0
- package/dist/internal/password-registration-native.d.mts +22 -0
- package/dist/internal/password-registration-native.mjs +142 -0
- package/dist/internal/password-registration-native.mjs.map +1 -0
- package/dist/internal/persistence.d.mts +6 -19
- package/dist/internal/persistence.mjs +199 -166
- package/dist/internal/persistence.mjs.map +1 -1
- package/dist/internal/phone-composed.mjs +79 -0
- package/dist/internal/phone-composed.mjs.map +1 -0
- package/dist/internal/phone-native.d.mts +15 -0
- package/dist/internal/phone-native.mjs +354 -0
- package/dist/internal/phone-native.mjs.map +1 -0
- package/dist/internal/proof-native.d.mts +15 -0
- package/dist/internal/proof-native.mjs +289 -0
- package/dist/internal/proof-native.mjs.map +1 -0
- package/dist/internal/registration.mjs +50 -60
- package/dist/internal/registration.mjs.map +1 -1
- package/dist/internal/session-native-authority.d.mts +15 -0
- package/dist/internal/session-native-authority.mjs +91 -0
- package/dist/internal/session-native-authority.mjs.map +1 -0
- package/dist/internal/session-native-cleanup.d.mts +14 -0
- package/dist/internal/session-native-cleanup.mjs +48 -0
- package/dist/internal/session-native-cleanup.mjs.map +1 -0
- package/dist/internal/session-native-login.d.mts +15 -0
- package/dist/internal/session-native-login.mjs +87 -0
- package/dist/internal/session-native-login.mjs.map +1 -0
- package/dist/internal/session-native-pending-read.mjs +42 -0
- package/dist/internal/session-native-pending-read.mjs.map +1 -0
- package/dist/internal/session-native-pending.mjs +134 -0
- package/dist/internal/session-native-pending.mjs.map +1 -0
- package/dist/internal/session-native-record.mjs +79 -0
- package/dist/internal/session-native-record.mjs.map +1 -0
- package/dist/internal/session-native-state.mjs +130 -0
- package/dist/internal/session-native-state.mjs.map +1 -0
- package/dist/internal/session-native-stateful.d.mts +16 -0
- package/dist/internal/session-native-stateful.mjs +225 -0
- package/dist/internal/session-native-stateful.mjs.map +1 -0
- package/dist/internal/session-native-step-up.d.mts +15 -0
- package/dist/internal/session-native-step-up.mjs +212 -0
- package/dist/internal/session-native-step-up.mjs.map +1 -0
- package/dist/internal/session-native-validity.d.mts +15 -0
- package/dist/internal/session-native-validity.mjs +97 -0
- package/dist/internal/session-native-validity.mjs.map +1 -0
- package/dist/internal/session-policy.mjs +29 -0
- package/dist/internal/session-policy.mjs.map +1 -0
- package/dist/internal/sql-authority.d.mts +16 -0
- package/dist/internal/sql-authority.mjs +32 -0
- package/dist/internal/sql-authority.mjs.map +1 -0
- package/dist/internal/sql-change.mjs +21 -0
- package/dist/internal/sql-change.mjs.map +1 -0
- package/dist/internal/sql-cleanup.mjs +35 -0
- package/dist/internal/sql-cleanup.mjs.map +1 -0
- package/dist/internal/sql-commit.d.mts +72 -0
- package/dist/internal/sql-commit.mjs +176 -0
- package/dist/internal/sql-commit.mjs.map +1 -0
- package/dist/internal/sql-expression.d.mts +17 -0
- package/dist/internal/sql-expression.mjs +49 -0
- package/dist/internal/sql-expression.mjs.map +1 -0
- package/dist/internal/sql-oauth-connected-model.d.mts +7 -23
- package/dist/internal/sql-oauth-model.d.mts +27 -52
- package/dist/internal/sql-oauth-model.mjs +3 -4
- package/dist/internal/sql-oauth-model.mjs.map +1 -1
- package/dist/internal/sql-persistence.mjs +5 -9
- package/dist/internal/sql-persistence.mjs.map +1 -1
- package/dist/internal/sql-storage-validation.mjs +1 -2
- package/dist/internal/sql-storage-validation.mjs.map +1 -1
- package/dist/internal/sql-table.d.mts +3 -16
- package/dist/internal/sql-table.mjs +21 -42
- package/dist/internal/sql-table.mjs.map +1 -1
- package/dist/internal/standalone.mjs +2 -3
- package/dist/internal/standalone.mjs.map +1 -1
- package/dist/internal/step-up-state.mjs +5 -8
- package/dist/internal/step-up-state.mjs.map +1 -1
- package/dist/internal/storage-clock.mjs +44 -0
- package/dist/internal/storage-clock.mjs.map +1 -0
- package/dist/internal/storage-mapping.d.mts +11 -8
- package/dist/internal/storage-mapping.mjs +88 -302
- package/dist/internal/storage-mapping.mjs.map +1 -1
- package/dist/internal/storage-plans.mjs +15 -73
- package/dist/internal/storage-plans.mjs.map +1 -1
- package/dist/internal/storage-tables.d.mts +37 -520
- package/dist/internal/storage-tables.mjs +31 -211
- package/dist/internal/storage-tables.mjs.map +1 -1
- package/dist/internal/storage-validation.d.mts +1 -6
- package/dist/internal/storage-validation.mjs +1 -42
- package/dist/internal/storage-validation.mjs.map +1 -1
- package/dist/internal/table-model.d.mts +21 -0
- package/dist/internal/totp-native.d.mts +15 -0
- package/dist/internal/totp-native.mjs +401 -0
- package/dist/internal/totp-native.mjs.map +1 -0
- package/package.json +1 -1
- package/src/Adapter.ts +143 -199
- package/src/OAuthPersistence.ts +128 -271
- package/src/index.ts +1 -1
- package/src/internal/browser-login.ts +54 -24
- package/src/internal/configuration.ts +16 -31
- package/src/internal/d1-planning.ts +7 -0
- package/src/internal/email-native-state.ts +247 -0
- package/src/internal/email-native.ts +514 -0
- package/src/internal/email-policy.ts +235 -0
- package/src/internal/email-registration-native.ts +386 -0
- package/src/internal/models/email-model.ts +76 -214
- package/src/internal/models/oauth-connected-model.ts +50 -288
- package/src/internal/models/oauth-model.ts +147 -368
- package/src/internal/models/passkey-model.ts +11 -208
- package/src/internal/models/passkey-registration-ceremony-model.ts +6 -60
- package/src/internal/models/passkey-write-model.ts +14 -95
- package/src/internal/models/password-model.ts +28 -148
- package/src/internal/models/phone-model.ts +110 -0
- package/src/internal/models/proof-model.ts +48 -404
- package/src/internal/models/session-model.ts +102 -200
- package/src/internal/models/step-up-model.ts +17 -96
- package/src/internal/models/totp-model.ts +82 -0
- package/src/internal/native-sql-table.ts +32 -11
- package/src/internal/oauth/native-accounts.ts +576 -0
- package/src/internal/oauth/native-connected-state.ts +288 -0
- package/src/internal/oauth/native-connected.ts +888 -0
- package/src/internal/oauth/native-flow.ts +253 -0
- package/src/internal/oauth/native-layers.ts +83 -0
- package/src/internal/oauth/native-mutation.ts +222 -0
- package/src/internal/oauth/native-registration.ts +545 -0
- package/src/internal/oauth/native-revocations.ts +190 -0
- package/src/internal/oauth/native-sign-in.ts +111 -0
- package/src/internal/oauth/native-state.ts +346 -0
- package/src/internal/oauth/state.ts +2 -70
- package/src/internal/passkey-actions.ts +70 -0
- package/src/internal/passkey-inputs.ts +56 -0
- package/src/internal/passkey-managed.ts +360 -0
- package/src/internal/passkey-native-ceremony.ts +66 -0
- package/src/internal/passkey-native-flow.ts +140 -0
- package/src/internal/passkey-native-registration.ts +221 -0
- package/src/internal/passkey-native-state.ts +335 -0
- package/src/internal/passkey-native-write.ts +611 -0
- package/src/internal/passkey-native.ts +372 -0
- package/src/internal/passkey-policy.ts +246 -0
- package/src/internal/password-credentials.ts +52 -10
- package/src/internal/password-native.ts +571 -0
- package/src/internal/password-policy.ts +307 -0
- package/src/internal/password-registration-native.ts +322 -0
- package/src/internal/persistence.ts +336 -290
- package/src/internal/phone-composed.ts +86 -0
- package/src/internal/phone-native.ts +659 -0
- package/src/internal/proof-native.ts +448 -0
- package/src/internal/registration.ts +96 -143
- package/src/internal/session-native-authority.ts +247 -0
- package/src/internal/session-native-cleanup.ts +65 -0
- package/src/internal/session-native-login.ts +205 -0
- package/src/internal/session-native-pending-read.ts +68 -0
- package/src/internal/session-native-pending.ts +223 -0
- package/src/internal/session-native-record.ts +141 -0
- package/src/internal/session-native-state.ts +259 -0
- package/src/internal/session-native-stateful.ts +512 -0
- package/src/internal/session-native-step-up.ts +450 -0
- package/src/internal/session-native-validity.ts +208 -0
- package/src/internal/session-policy.ts +59 -0
- package/src/internal/sql-authority.ts +56 -0
- package/src/internal/sql-change.ts +38 -0
- package/src/internal/sql-cleanup.ts +56 -0
- package/src/internal/sql-commit.ts +435 -0
- package/src/internal/sql-expression.ts +94 -0
- package/src/internal/sql-metadata.ts +100 -0
- package/src/internal/sql-oauth-connected-model.ts +6 -95
- package/src/internal/sql-oauth-model.ts +31 -134
- package/src/internal/sql-persistence.ts +2 -6
- package/src/internal/sql-storage-validation.ts +1 -2
- package/src/internal/sql-table.ts +19 -52
- package/src/internal/standalone.ts +2 -11
- package/src/internal/step-up-state.ts +4 -17
- package/src/internal/storage-clock.ts +58 -0
- package/src/internal/storage-mapping.ts +125 -340
- package/src/internal/storage-plans.ts +14 -80
- package/src/internal/storage-tables.ts +28 -212
- package/src/internal/storage-validation.ts +0 -58
- package/src/internal/table-model.ts +24 -0
- package/src/internal/totp-native.ts +701 -0
- package/dist/internal/PasswordPreparedPostconditions.d.mts +0 -22
- package/dist/internal/PasswordPreparedPostconditions.mjs +0 -12
- package/dist/internal/PasswordPreparedPostconditions.mjs.map +0 -1
- package/dist/internal/authority-snapshot.mjs +0 -53
- package/dist/internal/authority-snapshot.mjs.map +0 -1
- package/dist/internal/email-kernel.d.mts +0 -276
- package/dist/internal/email-kernel.mjs +0 -497
- package/dist/internal/email-kernel.mjs.map +0 -1
- package/dist/internal/models/passkey-registration-ceremony-model.mjs +0 -18
- package/dist/internal/models/passkey-registration-ceremony-model.mjs.map +0 -1
- package/dist/internal/oauth/accounts.d.mts +0 -8
- package/dist/internal/oauth/accounts.mjs +0 -379
- package/dist/internal/oauth/accounts.mjs.map +0 -1
- package/dist/internal/oauth/connected-access.d.mts +0 -9
- package/dist/internal/oauth/connected-access.mjs +0 -229
- package/dist/internal/oauth/connected-access.mjs.map +0 -1
- package/dist/internal/oauth/connected-collection.d.mts +0 -7
- package/dist/internal/oauth/connected-collection.mjs +0 -214
- package/dist/internal/oauth/connected-collection.mjs.map +0 -1
- package/dist/internal/oauth/connected-custody.d.mts +0 -6
- package/dist/internal/oauth/connected-custody.mjs +0 -165
- package/dist/internal/oauth/connected-custody.mjs.map +0 -1
- package/dist/internal/oauth/connected-flow.d.mts +0 -7
- package/dist/internal/oauth/connected-flow.mjs +0 -324
- package/dist/internal/oauth/connected-flow.mjs.map +0 -1
- package/dist/internal/oauth/connected-input.mjs +0 -122
- package/dist/internal/oauth/connected-input.mjs.map +0 -1
- package/dist/internal/oauth/connected-keys.d.mts +0 -2
- package/dist/internal/oauth/connected-keys.mjs +0 -22
- package/dist/internal/oauth/connected-keys.mjs.map +0 -1
- package/dist/internal/oauth/connected-maintenance.d.mts +0 -9
- package/dist/internal/oauth/connected-maintenance.mjs +0 -226
- package/dist/internal/oauth/connected-maintenance.mjs.map +0 -1
- package/dist/internal/oauth/connected-management.d.mts +0 -9
- package/dist/internal/oauth/connected-management.mjs +0 -243
- package/dist/internal/oauth/connected-management.mjs.map +0 -1
- package/dist/internal/oauth/connected-reference.mjs +0 -63
- package/dist/internal/oauth/connected-reference.mjs.map +0 -1
- package/dist/internal/oauth/connected-settlement.d.mts +0 -8
- package/dist/internal/oauth/connected-settlement.mjs +0 -141
- package/dist/internal/oauth/connected-settlement.mjs.map +0 -1
- package/dist/internal/oauth/connected-sign-in.d.mts +0 -10
- package/dist/internal/oauth/connected-sign-in.mjs +0 -281
- package/dist/internal/oauth/connected-sign-in.mjs.map +0 -1
- package/dist/internal/oauth/connected-state.d.mts +0 -14
- package/dist/internal/oauth/connected-state.mjs +0 -469
- package/dist/internal/oauth/connected-state.mjs.map +0 -1
- package/dist/internal/oauth/connected-target.d.mts +0 -21
- package/dist/internal/oauth/connected-target.mjs +0 -117
- package/dist/internal/oauth/connected-target.mjs.map +0 -1
- package/dist/internal/oauth/flow.d.mts +0 -5
- package/dist/internal/oauth/flow.mjs +0 -279
- package/dist/internal/oauth/flow.mjs.map +0 -1
- package/dist/internal/oauth/input.mjs +0 -127
- package/dist/internal/oauth/input.mjs.map +0 -1
- package/dist/internal/oauth/owner.d.mts +0 -10
- package/dist/internal/oauth/owner.mjs +0 -10
- package/dist/internal/oauth/owner.mjs.map +0 -1
- package/dist/internal/oauth/query-compiler.d.mts +0 -7
- package/dist/internal/oauth/query-compiler.mjs +0 -9
- package/dist/internal/oauth/query-compiler.mjs.map +0 -1
- package/dist/internal/oauth/registration.d.mts +0 -7
- package/dist/internal/oauth/registration.mjs +0 -393
- package/dist/internal/oauth/registration.mjs.map +0 -1
- package/dist/internal/oauth/target.d.mts +0 -31
- package/dist/internal/oauth/target.mjs +0 -273
- package/dist/internal/oauth/target.mjs.map +0 -1
- package/dist/internal/oauth-kernel.d.mts +0 -1423
- package/dist/internal/oauth-kernel.mjs +0 -187
- package/dist/internal/oauth-kernel.mjs.map +0 -1
- package/dist/internal/passkey/admission.d.mts +0 -6
- package/dist/internal/passkey/admission.mjs +0 -220
- package/dist/internal/passkey/admission.mjs.map +0 -1
- package/dist/internal/passkey/credentials.d.mts +0 -14
- package/dist/internal/passkey/credentials.mjs +0 -249
- package/dist/internal/passkey/credentials.mjs.map +0 -1
- package/dist/internal/passkey/enrollment.mjs +0 -138
- package/dist/internal/passkey/enrollment.mjs.map +0 -1
- package/dist/internal/passkey/flow.d.mts +0 -21
- package/dist/internal/passkey/flow.mjs +0 -452
- package/dist/internal/passkey/flow.mjs.map +0 -1
- package/dist/internal/passkey/management.mjs +0 -231
- package/dist/internal/passkey/management.mjs.map +0 -1
- package/dist/internal/passkey/registration-ceremony.d.mts +0 -9
- package/dist/internal/passkey/registration-ceremony.mjs +0 -129
- package/dist/internal/passkey/registration-ceremony.mjs.map +0 -1
- package/dist/internal/passkey/registration-custody.d.mts +0 -2
- package/dist/internal/passkey/registration-custody.mjs +0 -52
- package/dist/internal/passkey/registration-custody.mjs.map +0 -1
- package/dist/internal/passkey/registration-write.mjs +0 -211
- package/dist/internal/passkey/registration-write.mjs.map +0 -1
- package/dist/internal/passkey/state.d.mts +0 -10
- package/dist/internal/passkey/state.mjs +0 -234
- package/dist/internal/passkey/state.mjs.map +0 -1
- package/dist/internal/passkey/target.d.mts +0 -20
- package/dist/internal/passkey/target.mjs +0 -200
- package/dist/internal/passkey/target.mjs.map +0 -1
- package/dist/internal/passkey/write-state.d.mts +0 -17
- package/dist/internal/passkey/write-state.mjs +0 -346
- package/dist/internal/passkey/write-state.mjs.map +0 -1
- package/dist/internal/passkey/write-target.mjs +0 -192
- package/dist/internal/passkey/write-target.mjs.map +0 -1
- package/dist/internal/passkey-kernel.d.mts +0 -6045
- package/dist/internal/passkey-kernel.mjs +0 -49
- package/dist/internal/passkey-kernel.mjs.map +0 -1
- package/dist/internal/passkeys.d.mts +0 -7
- package/dist/internal/passkeys.mjs +0 -387
- package/dist/internal/passkeys.mjs.map +0 -1
- package/dist/internal/password-credentials.d.mts +0 -11
- package/dist/internal/password-kernel.d.mts +0 -278
- package/dist/internal/password-kernel.mjs +0 -508
- package/dist/internal/password-kernel.mjs.map +0 -1
- package/dist/internal/phone-kernel.d.mts +0 -162
- package/dist/internal/phone-kernel.mjs +0 -437
- package/dist/internal/phone-kernel.mjs.map +0 -1
- package/dist/internal/proof-kernel.d.mts +0 -94
- package/dist/internal/proof-kernel.mjs +0 -624
- package/dist/internal/proof-kernel.mjs.map +0 -1
- package/dist/internal/query-operations.d.mts +0 -68
- package/dist/internal/session-kernel.d.mts +0 -62
- package/dist/internal/session-kernel.mjs +0 -820
- package/dist/internal/session-kernel.mjs.map +0 -1
- package/dist/internal/sql-oauth-connected-model.mjs +0 -7
- package/dist/internal/sql-oauth-connected-model.mjs.map +0 -1
- package/dist/internal/sql-query.d.mts +0 -12
- package/dist/internal/sql-query.mjs +0 -206
- package/dist/internal/sql-query.mjs.map +0 -1
- package/dist/internal/step-up-state.d.mts +0 -49
- package/dist/internal/transaction-execution-kernel.d.mts +0 -37
- package/dist/internal/transaction-execution-kernel.mjs +0 -120
- package/dist/internal/transaction-execution-kernel.mjs.map +0 -1
- package/dist/internal/transaction-kernel.d.mts +0 -81
- package/dist/internal/transaction-kernel.mjs +0 -264
- package/dist/internal/transaction-kernel.mjs.map +0 -1
- package/src/internal/PasswordPreparedPostconditions.ts +0 -30
- package/src/internal/authority-snapshot.ts +0 -91
- package/src/internal/email-kernel.ts +0 -1555
- package/src/internal/oauth/accounts.ts +0 -838
- package/src/internal/oauth/connected-access.ts +0 -388
- package/src/internal/oauth/connected-collection.ts +0 -345
- package/src/internal/oauth/connected-custody.ts +0 -308
- package/src/internal/oauth/connected-flow.ts +0 -562
- package/src/internal/oauth/connected-input.ts +0 -147
- package/src/internal/oauth/connected-keys.ts +0 -31
- package/src/internal/oauth/connected-maintenance.ts +0 -379
- package/src/internal/oauth/connected-management.ts +0 -391
- package/src/internal/oauth/connected-reference.ts +0 -135
- package/src/internal/oauth/connected-settlement.ts +0 -278
- package/src/internal/oauth/connected-sign-in.ts +0 -472
- package/src/internal/oauth/connected-state.ts +0 -924
- package/src/internal/oauth/connected-target.ts +0 -307
- package/src/internal/oauth/flow.ts +0 -505
- package/src/internal/oauth/input.ts +0 -201
- package/src/internal/oauth/owner.ts +0 -22
- package/src/internal/oauth/query-compiler.ts +0 -15
- package/src/internal/oauth/registration.ts +0 -676
- package/src/internal/oauth/target.ts +0 -803
- package/src/internal/oauth-kernel.ts +0 -294
- package/src/internal/passkey/admission.ts +0 -368
- package/src/internal/passkey/credentials.ts +0 -511
- package/src/internal/passkey/enrollment.ts +0 -326
- package/src/internal/passkey/flow.ts +0 -1062
- package/src/internal/passkey/management.ts +0 -426
- package/src/internal/passkey/registration-ceremony.ts +0 -283
- package/src/internal/passkey/registration-custody.ts +0 -91
- package/src/internal/passkey/registration-write.ts +0 -426
- package/src/internal/passkey/state.ts +0 -351
- package/src/internal/passkey/target.ts +0 -598
- package/src/internal/passkey/write-state.ts +0 -678
- package/src/internal/passkey/write-target.ts +0 -450
- package/src/internal/passkey-kernel.ts +0 -112
- package/src/internal/passkeys.ts +0 -652
- package/src/internal/password-kernel.ts +0 -1522
- package/src/internal/phone-kernel.ts +0 -872
- package/src/internal/proof-kernel.ts +0 -1992
- package/src/internal/query-operations.ts +0 -91
- package/src/internal/session-kernel.ts +0 -2406
- package/src/internal/sql-query.ts +0 -304
- package/src/internal/transaction-execution-kernel.ts +0 -335
- package/src/internal/transaction-kernel.ts +0 -603
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
import { __exportAll } from "./_virtual/_rolldown/runtime.mjs";
|
|
2
2
|
import { PersistenceConfigurationError } from "./internal/configuration.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { Table } from "./internal/sql-table.mjs";
|
|
4
|
+
import { SqlExpression, and, eq, sql } from "./internal/sql-expression.mjs";
|
|
4
5
|
import { makeNativeSqlTables } from "./internal/native-sql-table.mjs";
|
|
5
6
|
import { requireStandalone } from "./internal/standalone.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import { makeSqlCommitExecutor } from "./internal/sql-commit.mjs";
|
|
8
|
+
import { requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints } from "./internal/models/oauth-model.mjs";
|
|
9
|
+
import { captureOAuthMapping } from "./internal/oauth/state.mjs";
|
|
10
|
+
import { makeNativeOAuthSignInServices } from "./internal/oauth/native-sign-in.mjs";
|
|
11
|
+
import { makeNativeOAuthAccountsServices } from "./internal/oauth/native-accounts.mjs";
|
|
12
|
+
import { makeNativeOAuthConnectedServices } from "./internal/oauth/native-connected.mjs";
|
|
13
|
+
import { makeNativeOAuthRegistrationIntentServices, makeNativeOAuthRegistrationServices } from "./internal/oauth/native-registration.mjs";
|
|
14
|
+
import { makeNativeOAuthRevocationServices } from "./internal/oauth/native-revocations.mjs";
|
|
11
15
|
import { validateSqlStorage } from "./internal/sql-storage-validation.mjs";
|
|
12
|
-
import { oauthCleanupTable, oauthEligibilityTable,
|
|
16
|
+
import { oauthCleanupTable, oauthEligibilityTable, oauthRegistrationGuardTable } from "./internal/sql-oauth-model.mjs";
|
|
13
17
|
import { requiredOAuthConnectedConstraints, requiredOAuthConnectedRevocationConstraints } from "./internal/models/oauth-connected-model.mjs";
|
|
14
|
-
import {
|
|
18
|
+
import { oauthAccountsPersistenceLayer, oauthConnectedPersistenceLayer, oauthConnectedRevocationsLayer, oauthRegistrationAuthorityLayer, oauthRegistrationIntentsLayer, oauthSignInPersistenceLayer } from "./internal/oauth/native-layers.mjs";
|
|
19
|
+
import { makeAuthenticationAuthorityServices } from "./internal/sql-authority.mjs";
|
|
15
20
|
import { Effect, Predicate, Schema } from "effect";
|
|
16
21
|
import { SqlClient } from "effect/sql";
|
|
17
|
-
import {
|
|
22
|
+
import { hasCommitScope } from "@yielded/auth/Hooks";
|
|
18
23
|
import { OAuthAccountsPersistence, OAuthConnectedPersistence, OAuthConnectedRevocations, OAuthRegistrationIntents, OAuthSignInPersistence, OAuthUnavailable } from "@yielded/auth/OAuth";
|
|
19
24
|
//#region src/OAuthPersistence.ts
|
|
25
|
+
/** Direct PostgreSQL and SQLite owners for upstream OAuth. Provider exchange stays outside these transactions. */
|
|
20
26
|
var OAuthPersistence_exports = /* @__PURE__ */ __exportAll({
|
|
21
27
|
and: () => and,
|
|
22
28
|
clock: () => clock,
|
|
@@ -38,88 +44,74 @@ var OAuthPersistence_exports = /* @__PURE__ */ __exportAll({
|
|
|
38
44
|
oauthCleanupTable: () => oauthCleanupTable,
|
|
39
45
|
oauthConnectedOwnershipReferences: () => oauthConnectedOwnershipReferences,
|
|
40
46
|
oauthConnectedPersistenceLayer: () => oauthConnectedPersistenceLayer,
|
|
41
|
-
oauthConnectedPolicyGuard: () => oauthConnectedPolicyGuard,
|
|
42
47
|
oauthConnectedRevocationsLayer: () => oauthConnectedRevocationsLayer,
|
|
43
48
|
oauthEligibilityTable: () => oauthEligibilityTable,
|
|
44
|
-
oauthReferenceGuardTable: () => oauthReferenceGuardTable,
|
|
45
49
|
oauthRegistrationAuthorityLayer: () => oauthRegistrationAuthorityLayer,
|
|
46
50
|
oauthRegistrationGuardTable: () => oauthRegistrationGuardTable,
|
|
47
51
|
oauthRegistrationIntentsLayer: () => oauthRegistrationIntentsLayer,
|
|
48
52
|
oauthSignInPersistenceLayer: () => oauthSignInPersistenceLayer,
|
|
49
|
-
requiredOAuthAccountsConstraints: () => requiredOAuthAccountsConstraints,
|
|
50
53
|
requiredOAuthConnectedConstraints: () => requiredOAuthConnectedConstraints,
|
|
51
54
|
requiredOAuthConnectedRevocationConstraints: () => requiredOAuthConnectedRevocationConstraints,
|
|
52
55
|
requiredOAuthRegistrationConstraints: () => requiredOAuthRegistrationConstraints,
|
|
53
56
|
requiredOAuthSignInConstraints: () => requiredOAuthSignInConstraints,
|
|
54
|
-
requiredOAuthTupleConstraints: () => requiredOAuthTupleConstraints,
|
|
55
57
|
sql: () => sql,
|
|
56
58
|
table: () => table
|
|
57
59
|
});
|
|
58
|
-
/** Physical identifiers and representations only; applications own migrations. */
|
|
59
60
|
const table = (definition) => new Table(definition.name, definition.columns, definition.unique, definition.schema);
|
|
60
|
-
/** Integer-millisecond engine clock, sampled after locks on either supported dialect. */
|
|
61
61
|
const clock = {
|
|
62
62
|
encodeInstant: Schema.encodeSync(Schema.Int),
|
|
63
63
|
decodeInstant: Schema.decodeUnknownSync(Schema.Int),
|
|
64
|
-
engineNowMillis: new
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const kernels = {
|
|
71
|
-
pg: makeOAuthKernel(operations, () => "pg"),
|
|
72
|
-
sqlite: makeOAuthKernel(operations, () => "sqlite")
|
|
64
|
+
engineNowMillis: new SqlExpression((client) => client.onDialectOrElse({
|
|
65
|
+
pg: () => client`cast(extract(epoch from clock_timestamp()) * 1000 as bigint)`,
|
|
66
|
+
orElse: () => client`cast(round((julianday('now') - 2440587.5) * 86400000) as integer)`
|
|
67
|
+
})),
|
|
68
|
+
toMillis: (expression) => expression,
|
|
69
|
+
fromMillis: (expression) => expression
|
|
73
70
|
};
|
|
74
71
|
const acquire = Effect.gen(function* () {
|
|
75
72
|
const client = yield* SqlClient.SqlClient;
|
|
76
|
-
|
|
77
|
-
pg: () =>
|
|
78
|
-
sqlite: () =>
|
|
79
|
-
orElse: () =>
|
|
80
|
-
});
|
|
81
|
-
if (dialect === void 0 || Predicate.hasProperty(client, "~@effect/sql-d1/D1Client")) return yield* PersistenceConfigurationError.make({ reason: "OAuth persistence requires PostgreSQL or SQLite with interactive transactions" });
|
|
73
|
+
if (!client.onDialectOrElse({
|
|
74
|
+
pg: () => true,
|
|
75
|
+
sqlite: () => true,
|
|
76
|
+
orElse: () => false
|
|
77
|
+
}) || Predicate.hasProperty(client, "~@effect/sql-d1/D1Client")) return yield* PersistenceConfigurationError.make({ reason: "OAuth persistence requires PostgreSQL or SQLite with interactive transactions" });
|
|
82
78
|
return {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
mode: "interactive",
|
|
86
|
-
dialect,
|
|
87
|
-
locking: dialect === "pg",
|
|
88
|
-
standaloneGuard: (service) => requireStandalone(() => OAuthUnavailable.make({}), service)
|
|
89
|
-
},
|
|
90
|
-
kernel: kernels[dialect]
|
|
79
|
+
client,
|
|
80
|
+
tables: makeNativeSqlTables(client)
|
|
91
81
|
};
|
|
92
82
|
});
|
|
93
|
-
const using = (
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
83
|
+
const using = (original, make) => Effect.gen(function* () {
|
|
84
|
+
const target = yield* acquire;
|
|
85
|
+
const mapping = captureOAuthMapping(original);
|
|
86
|
+
yield* validateSqlStorage(mapping).pipe(Effect.mapError(() => OAuthUnavailable.make({})));
|
|
87
|
+
return yield* make(target.tables, mapping);
|
|
88
|
+
});
|
|
89
|
+
const coordinate = (make, body) => Effect.gen(function* () {
|
|
90
|
+
const { client } = yield* acquire;
|
|
91
|
+
if (yield* hasCommitScope) return yield* OAuthUnavailable.make({});
|
|
92
|
+
yield* requireStandalone(() => OAuthUnavailable.make({}), client.transactionService);
|
|
93
|
+
return yield* (yield* makeSqlCommitExecutor(() => OAuthUnavailable.make({}))).coordinate(Effect.flatMap(make.pipe(Effect.mapError(() => OAuthUnavailable.make({}))), body));
|
|
94
|
+
});
|
|
95
|
+
const makeOAuthSignInServices = (mapping) => using(mapping, (tables, value) => makeNativeOAuthSignInServices(tables, value));
|
|
96
|
+
const coordinateOAuthSignIn = (options, body) => coordinate(makeOAuthSignInServices(options.mapping), (services) => Effect.provideService(body, OAuthSignInPersistence, services.oauthSignInPersistence));
|
|
97
|
+
const makeOAuthAccountsServices = (mapping) => using(mapping, (tables, value) => makeNativeOAuthAccountsServices(tables, value));
|
|
98
|
+
const coordinateOAuthAccounts = (options, body) => coordinate(makeOAuthAccountsServices(options.mapping), (services) => Effect.provideService(body, OAuthAccountsPersistence, services.oauthAccountsPersistence));
|
|
99
|
+
const makeOAuthRegistrationIntentServices = (mapping) => using(mapping, (tables, value) => makeNativeOAuthRegistrationIntentServices(tables, value));
|
|
100
|
+
const coordinateOAuthRegistrationIntents = (options, body) => coordinate(makeOAuthRegistrationIntentServices(options.mapping), (services) => Effect.provideService(body, OAuthRegistrationIntents, services.oauthRegistrationIntents));
|
|
101
|
+
const makeOAuthConnectedServices = (mapping) => using(mapping, (tables, value) => makeNativeOAuthConnectedServices(tables, value));
|
|
102
|
+
const coordinateOAuthConnected = (options, body) => coordinate(makeOAuthConnectedServices(options.mapping), (services) => Effect.provideService(body, OAuthConnectedPersistence, services.oauthConnectedPersistence));
|
|
103
|
+
const makeOAuthConnectedRevocationServices = (mapping) => using(mapping, (tables, value) => makeNativeOAuthRevocationServices(tables, value));
|
|
104
|
+
const coordinateOAuthConnectedRevocations = (options, body) => coordinate(makeOAuthConnectedRevocationServices(options.mapping), (services) => Effect.provideService(body, OAuthConnectedRevocations, services.oauthConnectedRevocations));
|
|
105
|
+
const makeOAuthRegistrationServices = (mapping) => using(mapping, (tables, value) => makeNativeOAuthRegistrationServices(tables, value));
|
|
106
|
+
const coordinateOAuthRegistration = (options, body) => coordinate(makeOAuthRegistrationServices(options.mapping), (services) => Effect.provideService(body, options.target, services.registrationAuthority));
|
|
107
|
+
const oauthConnectedOwnershipReferences = (mapping) => ({ connectedReference: (input) => {
|
|
108
|
+
const g = mapping.grant;
|
|
109
|
+
const grant = sql`exists(select 1 from ${g.table} where ${g.table.columns[g.identityKey]} = ${input.identityKey} and ${g.table.columns[g.subjectId]} = ${input.subjectId})`;
|
|
110
|
+
if (mapping.revocation.mode === "unsupported") return grant;
|
|
111
|
+
const j = mapping.revocation.job;
|
|
112
|
+
return sql`(${grant}) or exists(select 1 from ${j.table} where ${j.table.columns[j.identityKey]} = ${input.identityKey} and ${j.table.columns[j.subjectId]} = ${input.subjectId})`;
|
|
113
|
+
} });
|
|
122
114
|
//#endregion
|
|
123
|
-
export { OAuthPersistence_exports, and, clock, coordinateOAuthAccounts, coordinateOAuthConnected, coordinateOAuthConnectedRevocations, coordinateOAuthRegistration, coordinateOAuthRegistrationIntents, coordinateOAuthSignIn, eq, makeAuthenticationAuthorityServices, makeOAuthAccountsServices, makeOAuthConnectedRevocationServices, makeOAuthConnectedServices, makeOAuthRegistrationIntentServices, makeOAuthRegistrationServices, makeOAuthSignInServices, oauthAccountsPersistenceLayer, oauthCleanupTable, oauthConnectedOwnershipReferences, oauthConnectedPersistenceLayer,
|
|
115
|
+
export { OAuthPersistence_exports, and, clock, coordinateOAuthAccounts, coordinateOAuthConnected, coordinateOAuthConnectedRevocations, coordinateOAuthRegistration, coordinateOAuthRegistrationIntents, coordinateOAuthSignIn, eq, makeAuthenticationAuthorityServices, makeOAuthAccountsServices, makeOAuthConnectedRevocationServices, makeOAuthConnectedServices, makeOAuthRegistrationIntentServices, makeOAuthRegistrationServices, makeOAuthSignInServices, oauthAccountsPersistenceLayer, oauthCleanupTable, oauthConnectedOwnershipReferences, oauthConnectedPersistenceLayer, oauthConnectedRevocationsLayer, oauthEligibilityTable, oauthRegistrationAuthorityLayer, oauthRegistrationGuardTable, oauthRegistrationIntentsLayer, oauthSignInPersistenceLayer, requiredOAuthConnectedConstraints, requiredOAuthConnectedRevocationConstraints, requiredOAuthRegistrationConstraints, requiredOAuthSignInConstraints, sql, table };
|
|
124
116
|
|
|
125
117
|
//# sourceMappingURL=OAuthPersistence.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OAuthPersistence.mjs","names":[],"sources":["../src/OAuthPersistence.ts"],"sourcesContent":["/** Direct Effect SQL persistence for upstream OAuth accounts. PostgreSQL and SQLite\n * require interactive transactions; provider exchanges occur outside coordinators. */\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n OAuthAccountsPersistence,\n OAuthSignInPersistence,\n OAuthRegistrationIntents,\n OAuthConnectedPersistence,\n OAuthConnectedRevocations,\n OAuthUnavailable,\n} from \"@yielded/auth/OAuth\";\nimport type { AuthenticationAuthority } from \"@yielded/auth/Sessions\";\nimport { SessionUnavailable } from \"@yielded/auth/Sessions\";\nimport { type Context, type Crypto, Effect, Predicate, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport { PersistenceConfigurationError } from \"./internal/configuration\";\nimport type { AuthenticationAuthorityMapping as AuthorityMapping } from \"./internal/models/session-model\";\nimport { makeNativeSqlTables } from \"./internal/native-sql-table\";\nimport { makeOAuthKernel } from \"./internal/oauth-kernel\";\nimport type { OAuthCoordinatorError, OAuthTargetConfiguration } from \"./internal/oauth/target\";\nimport {\n CurrentSessionSql,\n makeSessionKernel,\n type SessionSqlDatabase,\n} from \"./internal/session-kernel\";\nimport type {\n OAuthConnectedMapping,\n OAuthConnectedRevocationMapping,\n} from \"./internal/sql-oauth-connected-model\";\nimport type {\n SqlTableModel,\n OAuthAccountsMapping,\n OAuthSignInMapping,\n OAuthRegistrationIntentMapping,\n OAuthRegistrationMapping,\n OAuthRegistrationAuthority,\n OAuthReferenceGuardDescriptor,\n} from \"./internal/sql-oauth-model\";\nimport { makeSqlDatabase, sqlQueryOperations, sql } from \"./internal/sql-query\";\nimport { validateSqlStorage } from \"./internal/sql-storage-validation\";\nimport { Table, Fragment } from \"./internal/sql-table\";\nimport { requireStandalone } from \"./internal/standalone\";\nimport type { StorageTable } from \"./internal/storage-tables\";\nimport { NativeDatabase } from \"./internal/transaction-kernel\";\nimport type { TransactionNativeDatabase } from \"./internal/transaction-kernel\";\nexport * from \"./internal/sql-oauth-model\";\nexport * from \"./internal/sql-oauth-connected-model\";\nexport { sql };\nexport { and, eq } from \"./internal/sql-query\";\n\n/** Physical identifiers and representations only; applications own migrations. */\nexport const table = (definition: StorageTable) =>\n new Table(definition.name, definition.columns, definition.unique, definition.schema);\n\n/** Integer-millisecond engine clock, sampled after locks on either supported dialect. */\nexport const clock = {\n encodeInstant: Schema.encodeSync(Schema.Int),\n decodeInstant: Schema.decodeUnknownSync(Schema.Int),\n engineNowMillis: new Fragment((compiler) =>\n compiler.dialect === \"pg\"\n ? \"cast(extract(epoch from clock_timestamp()) * 1000 as bigint)\"\n : \"cast(round((julianday('now') - 2440587.5) * 86400000) as integer)\",\n ),\n};\n\nconst operations = { ...sqlQueryOperations, validateStorage: validateSqlStorage };\n\nconst kernels = {\n pg: makeOAuthKernel(operations, () => \"pg\"),\n sqlite: makeOAuthKernel(operations, () => \"sqlite\"),\n};\n\nconst acquire = Effect.gen(function* () {\n const client = yield* SqlClient.SqlClient;\n\n const dialect = client.onDialectOrElse({\n pg: () => \"pg\" as const,\n sqlite: () => \"sqlite\" as const,\n orElse: () => undefined,\n });\n\n // D1 exposes the SQLite compiler but its public driver brand identifies a\n // batch-only client. Keep the default package free of a D1 runtime dependency.\n if (dialect === undefined || Predicate.hasProperty(client, \"~@effect/sql-d1/D1Client\"))\n return yield* PersistenceConfigurationError.make({\n reason: \"OAuth persistence requires PostgreSQL or SQLite with interactive transactions\",\n });\n\n const database = yield* makeSqlDatabase(dialect);\n\n const configuration: OAuthTargetConfiguration = {\n mode: \"interactive\",\n dialect,\n locking: dialect === \"pg\",\n standaloneGuard: (service) => requireStandalone(() => OAuthUnavailable.make({}), service),\n };\n\n // Erase only the query-builder handle; batch methods are never selected by this adapter.\n return {\n database: database as unknown as TransactionNativeDatabase,\n configuration,\n kernel: kernels[dialect],\n };\n});\n\nconst using = <A, E, R>(body: (input: Effect.Success<typeof acquire>) => Effect.Effect<A, E, R>) =>\n Effect.flatMap(acquire, (input) =>\n body(input).pipe(Effect.provideService(NativeDatabase, input.database)),\n );\n\nexport const makeOAuthSignInServices = <N>(\n mapping: OAuthSignInMapping<Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthSignInPersistence: OAuthSignInPersistence[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration }) =>\n kernel.target.makeTargetOAuthSignInServices(mapping, configuration),\n );\n\n/** Run auth and application SQL in one adapter-owned transaction and commit journal. */\nexport const coordinateOAuthSignIn = <N, A, E, R>(\n options: { readonly mapping: OAuthSignInMapping<Table, Table, Table, Table, Table, N> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | PersistenceConfigurationError,\n Exclude<R, OAuthSignInPersistence> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration, database }) =>\n kernel.target.coordinateTargetOAuthSignIn(\n database,\n options.mapping,\n configuration,\n (_transaction, services) =>\n Effect.provideService(body, OAuthSignInPersistence, services.oauthSignInPersistence),\n ),\n );\n\nexport const makeOAuthRegistrationIntentServices = <N>(\n mapping: OAuthRegistrationIntentMapping<Table, Table, Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthRegistrationIntents: OAuthRegistrationIntents[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration }) =>\n kernel.target.makeTargetOAuthRegistrationIntentServices(mapping, configuration),\n );\n\n/** Run auth and application SQL in one adapter-owned transaction and commit journal. */\nexport const coordinateOAuthRegistrationIntents = <N, A, E, R>(\n options: {\n readonly mapping: OAuthRegistrationIntentMapping<\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | PersistenceConfigurationError,\n Exclude<R, OAuthRegistrationIntents> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration, database }) =>\n kernel.target.coordinateTargetOAuthRegistrationIntents(\n database,\n options.mapping,\n configuration,\n (_transaction, services) =>\n Effect.provideService(body, OAuthRegistrationIntents, services.oauthRegistrationIntents),\n ),\n );\n\nexport const makeOAuthAccountsServices = <N>(\n mapping: OAuthAccountsMapping<Table, Table, Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthAccountsPersistence: OAuthAccountsPersistence[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration }) =>\n kernel.target.makeTargetOAuthAccountsServices(mapping, configuration),\n );\n\n/** Run auth and application SQL in one adapter-owned transaction and commit journal. */\nexport const coordinateOAuthAccounts = <N, A, E, R>(\n options: {\n readonly mapping: OAuthAccountsMapping<Table, Table, Table, Table, Table, Table, Table, N>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | PersistenceConfigurationError,\n Exclude<R, OAuthAccountsPersistence> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration, database }) =>\n kernel.target.coordinateTargetOAuthAccounts(\n database,\n options.mapping,\n configuration,\n (_transaction, services) =>\n Effect.provideService(body, OAuthAccountsPersistence, services.oauthAccountsPersistence),\n ),\n );\n\nexport const makeOAuthConnectedServices = <N>(\n mapping: OAuthConnectedMapping<\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N,\n Table\n >,\n): Effect.Effect<\n { readonly oauthConnectedPersistence: OAuthConnectedPersistence[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration }) =>\n kernel.connectedTarget.makeTargetOAuthConnectedServices(mapping, configuration),\n );\n\n/** Run auth and application SQL in one adapter-owned transaction and commit journal. */\nexport const coordinateOAuthConnected = <N, A, E, R>(\n options: {\n readonly mapping: OAuthConnectedMapping<\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N,\n Table\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | PersistenceConfigurationError,\n Exclude<R, OAuthConnectedPersistence> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration, database }) =>\n kernel.connectedTarget.coordinateTargetOAuthConnected(\n database,\n options.mapping,\n configuration,\n (_transaction, services) =>\n Effect.provideService(body, OAuthConnectedPersistence, services.oauthConnectedPersistence),\n ),\n );\n\nexport const makeOAuthConnectedRevocationServices = <N>(\n mapping: OAuthConnectedRevocationMapping<Table, Table, Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthConnectedRevocations: OAuthConnectedRevocations[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration }) =>\n kernel.connectedTarget.makeTargetOAuthConnectedRevocationServices(mapping, configuration),\n );\n\n/** Run auth and application SQL in one adapter-owned transaction and commit journal. */\nexport const coordinateOAuthConnectedRevocations = <N, A, E, R>(\n options: {\n readonly mapping: OAuthConnectedRevocationMapping<\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | PersistenceConfigurationError,\n Exclude<R, OAuthConnectedRevocations> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration, database }) =>\n kernel.connectedTarget.coordinateTargetOAuthConnectedRevocations(\n database,\n options.mapping,\n configuration,\n (_transaction, services) =>\n Effect.provideService(body, OAuthConnectedRevocations, services.oauthConnectedRevocations),\n ),\n );\n\nexport const makeOAuthRegistrationServices = <Registration, N>(\n mapping: OAuthRegistrationMapping<\n Registration,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N\n >,\n): Effect.Effect<\n { readonly registrationAuthority: OAuthRegistrationAuthority<Registration> },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration }) =>\n kernel.target.makeTargetOAuthRegistrationServices<Registration>(mapping, configuration),\n );\n\nexport const coordinateOAuthRegistration = <Id, Registration, N, A, E, R>(\n options: {\n readonly mapping: OAuthRegistrationMapping<\n NoInfer<Registration>,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N\n >;\n readonly target: Context.Key<Id, OAuthRegistrationAuthority<Registration>>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | PersistenceConfigurationError,\n Exclude<R, Id> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ kernel, configuration, database }) =>\n kernel.target.coordinateTargetOAuthRegistration<Registration, unknown, A, E, Exclude<R, Id>>(\n database,\n options.mapping,\n configuration,\n (_transaction, services) =>\n Effect.provideService(body, options.target, services.registrationAuthority),\n ),\n );\n\n/** Include these guards when login ownership may also hold retained grants. */\nexport const oauthConnectedOwnershipReferences = <N>(\n mapping: OAuthConnectedMapping<\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n Table,\n N,\n Table\n >,\n dialect: \"pg\" | \"sqlite\",\n) =>\n // The selected compiler supplies Fragment handles; domain values retain their codecs.\n kernels[dialect].connectedReference.oauthConnectedOwnershipReferences(mapping) as {\n readonly connectedReferenceGuards: ReadonlyArray<OAuthReferenceGuardDescriptor<N>>;\n readonly connectedReference: (input: {\n readonly identityKey: string;\n readonly subjectId: N;\n }) => Fragment;\n };\n\nexport const {\n oauthAccountsPersistenceLayer,\n oauthSignInPersistenceLayer,\n oauthRegistrationIntentsLayer,\n oauthRegistrationAuthorityLayer,\n} = kernels.sqlite.target;\n\nexport const { oauthConnectedPersistenceLayer, oauthConnectedRevocationsLayer } =\n kernels.sqlite.connectedTarget;\n\n/** Shared session issuance must validate the same subject and credential authority\n * as OAuth. Supply this service when it is not already provided by session storage. */\nexport const makeAuthenticationAuthorityServices = <Claims, N>(\n mapping: AuthorityMapping<Claims, SqlTableModel, SqlTableModel, SqlTableModel, SqlTableModel, N>,\n): Effect.Effect<\n { readonly authenticationAuthority: AuthenticationAuthority[\"Service\"] },\n SessionUnavailable | PersistenceConfigurationError,\n LifecycleHooks | SqlClient.SqlClient\n> =>\n using(({ database, configuration }) =>\n makeSessionKernel(operations, (client) => makeNativeSqlTables(client))\n .makeSqlAuthenticationAuthority(mapping, {\n mode: \"interactive\",\n locking: configuration.locking,\n standaloneGuard: requireStandalone(\n () => SessionUnavailable.make({}),\n database.$client.transactionService,\n ),\n })\n .pipe(\n // Both kernels capture the same raw SQL query-builder handle and client.\n Effect.provideService(CurrentSessionSql, database as unknown as SessionSqlDatabase),\n Effect.map((authenticationAuthority) => ({ authenticationAuthority })),\n ),\n );\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OAuthPersistence.mjs","names":[],"sources":["../src/OAuthPersistence.ts"],"sourcesContent":["/** Direct PostgreSQL and SQLite owners for upstream OAuth. Provider exchange stays outside these transactions. */\nimport { hasCommitScope, type LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n OAuthAccountsPersistence,\n OAuthSignInPersistence,\n OAuthRegistrationIntents,\n OAuthConnectedPersistence,\n OAuthConnectedRevocations,\n OAuthUnavailable,\n} from \"@yielded/auth/OAuth\";\nimport { type Context, type Crypto, Effect, Predicate, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport { PersistenceConfigurationError } from \"./internal/configuration\";\nimport { makeNativeSqlTables } from \"./internal/native-sql-table\";\nimport {\n makeNativeOAuthAccountsServices,\n type OAuthNativeAccountsMapping,\n} from \"./internal/oauth/native-accounts\";\nimport { makeNativeOAuthConnectedServices } from \"./internal/oauth/native-connected\";\nimport type { OAuthNativeConnectedMapping } from \"./internal/oauth/native-connected-state\";\nimport {\n makeNativeOAuthRegistrationIntentServices,\n makeNativeOAuthRegistrationServices,\n type OAuthNativeRegistrationIntentMapping,\n type OAuthNativeRegistrationMapping,\n} from \"./internal/oauth/native-registration\";\nimport {\n makeNativeOAuthRevocationServices,\n type OAuthNativeRevocationMapping,\n} from \"./internal/oauth/native-revocations\";\nimport { makeNativeOAuthSignInServices } from \"./internal/oauth/native-sign-in\";\nimport { type OAuthNativeReadMapping } from \"./internal/oauth/native-state\";\nimport { captureOAuthMapping } from \"./internal/oauth/state\";\nimport { makeSqlCommitExecutor } from \"./internal/sql-commit\";\nimport { sql, SqlExpression } from \"./internal/sql-expression\";\nimport type {\n OAuthConnectedMapping,\n OAuthConnectedRevocationMapping,\n} from \"./internal/sql-oauth-connected-model\";\nimport type {\n OAuthAccountsMapping,\n OAuthSignInMapping,\n OAuthRegistrationIntentMapping,\n OAuthRegistrationMapping,\n OAuthRegistrationAuthority,\n} from \"./internal/sql-oauth-model\";\nimport { validateSqlStorage } from \"./internal/sql-storage-validation\";\nimport { Table } from \"./internal/sql-table\";\nimport { requireStandalone } from \"./internal/standalone\";\nimport type { StorageTable } from \"./internal/storage-tables\";\nexport * from \"./internal/sql-oauth-model\";\nexport * from \"./internal/sql-oauth-connected-model\";\nexport * from \"./internal/oauth/native-layers\";\nexport { sql, and, eq } from \"./internal/sql-expression\";\nexport { makeAuthenticationAuthorityServices } from \"./internal/sql-authority\";\n\nexport const table = (definition: StorageTable) =>\n new Table(definition.name, definition.columns, definition.unique, definition.schema);\n\nexport const clock = {\n encodeInstant: Schema.encodeSync(Schema.Int),\n decodeInstant: Schema.decodeUnknownSync(Schema.Int),\n engineNowMillis: new SqlExpression((client) =>\n client.onDialectOrElse({\n pg: () => client`cast(extract(epoch from clock_timestamp()) * 1000 as bigint)`,\n orElse: () => client`cast(round((julianday('now') - 2440587.5) * 86400000) as integer)`,\n }),\n ),\n toMillis: (expression: SqlExpression) => expression,\n fromMillis: (expression: SqlExpression) => expression,\n};\n\nconst acquire = Effect.gen(function* () {\n const client = yield* SqlClient.SqlClient;\n\n if (\n !client.onDialectOrElse({ pg: () => true, sqlite: () => true, orElse: () => false }) ||\n Predicate.hasProperty(client, \"~@effect/sql-d1/D1Client\")\n )\n return yield* PersistenceConfigurationError.make({\n reason: \"OAuth persistence requires PostgreSQL or SQLite with interactive transactions\",\n });\n\n return { client, tables: makeNativeSqlTables(client) };\n});\n\nconst using = <M, A, E, R>(\n original: M,\n make: (tables: ReturnType<typeof makeNativeSqlTables>, mapping: M) => Effect.Effect<A, E, R>,\n) =>\n Effect.gen(function* () {\n const target = yield* acquire;\n const mapping = captureOAuthMapping(original);\n\n yield* validateSqlStorage(mapping).pipe(Effect.mapError(() => OAuthUnavailable.make({})));\n\n return yield* make(target.tables, mapping);\n });\n\nconst coordinate = <S, A, E, R, ES, RS>(\n make: Effect.Effect<S, ES, RS>,\n body: (services: S) => Effect.Effect<A, E, R>,\n) =>\n Effect.gen(function* () {\n const { client } = yield* acquire;\n\n if (yield* hasCommitScope) return yield* OAuthUnavailable.make({});\n yield* requireStandalone(() => OAuthUnavailable.make({}), client.transactionService);\n const executor = yield* makeSqlCommitExecutor(() => OAuthUnavailable.make({}));\n\n return yield* executor.coordinate(\n Effect.flatMap(make.pipe(Effect.mapError(() => OAuthUnavailable.make({}))), body),\n );\n });\n\nexport const makeOAuthSignInServices = <N>(\n mapping: OAuthSignInMapping<Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthSignInPersistence: OAuthSignInPersistence[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(mapping, (tables, value) =>\n makeNativeOAuthSignInServices(tables, value as unknown as OAuthNativeReadMapping),\n );\n\nexport const coordinateOAuthSignIn = <N, A, E, R>(\n options: { readonly mapping: OAuthSignInMapping<Table, Table, Table, Table, Table, N> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | OAuthUnavailable | PersistenceConfigurationError,\n Exclude<R, OAuthSignInPersistence> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n coordinate(makeOAuthSignInServices(options.mapping), (services) =>\n Effect.provideService(body, OAuthSignInPersistence, services.oauthSignInPersistence),\n );\n\nexport const makeOAuthAccountsServices = <N>(\n mapping: OAuthAccountsMapping<Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthAccountsPersistence: OAuthAccountsPersistence[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(mapping, (tables, value) =>\n makeNativeOAuthAccountsServices(tables, value as unknown as OAuthNativeAccountsMapping),\n );\n\nexport const coordinateOAuthAccounts = <N, A, E, R>(\n options: { readonly mapping: OAuthAccountsMapping<Table, Table, Table, Table, Table, N> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | OAuthUnavailable | PersistenceConfigurationError,\n Exclude<R, OAuthAccountsPersistence> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n coordinate(makeOAuthAccountsServices(options.mapping), (services) =>\n Effect.provideService(body, OAuthAccountsPersistence, services.oauthAccountsPersistence),\n );\n\nexport const makeOAuthRegistrationIntentServices = <N>(\n mapping: OAuthRegistrationIntentMapping<Table, Table, N>,\n): Effect.Effect<\n { readonly oauthRegistrationIntents: OAuthRegistrationIntents[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(mapping, (tables, value) =>\n makeNativeOAuthRegistrationIntentServices(\n tables,\n value as unknown as OAuthNativeRegistrationIntentMapping,\n ),\n );\n\nexport const coordinateOAuthRegistrationIntents = <N, A, E, R>(\n options: { readonly mapping: OAuthRegistrationIntentMapping<Table, Table, N> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | OAuthUnavailable | PersistenceConfigurationError,\n Exclude<R, OAuthRegistrationIntents> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n coordinate(makeOAuthRegistrationIntentServices(options.mapping), (services) =>\n Effect.provideService(body, OAuthRegistrationIntents, services.oauthRegistrationIntents),\n );\n\nexport const makeOAuthConnectedServices = <N>(\n mapping: OAuthConnectedMapping<Table, Table, Table, Table, Table, N, Table>,\n): Effect.Effect<\n { readonly oauthConnectedPersistence: OAuthConnectedPersistence[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(mapping, (tables, value) =>\n makeNativeOAuthConnectedServices(tables, value as unknown as OAuthNativeConnectedMapping),\n );\n\nexport const coordinateOAuthConnected = <N, A, E, R>(\n options: { readonly mapping: OAuthConnectedMapping<Table, Table, Table, Table, Table, N, Table> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | OAuthUnavailable | PersistenceConfigurationError,\n Exclude<R, OAuthConnectedPersistence> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n coordinate(makeOAuthConnectedServices(options.mapping), (services) =>\n Effect.provideService(body, OAuthConnectedPersistence, services.oauthConnectedPersistence),\n );\n\nexport const makeOAuthConnectedRevocationServices = <N>(\n mapping: OAuthConnectedRevocationMapping<Table, Table, Table, N>,\n): Effect.Effect<\n { readonly oauthConnectedRevocations: OAuthConnectedRevocations[\"Service\"] },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(mapping, (tables, value) =>\n makeNativeOAuthRevocationServices(tables, value as unknown as OAuthNativeRevocationMapping),\n );\n\nexport const coordinateOAuthConnectedRevocations = <N, A, E, R>(\n options: { readonly mapping: OAuthConnectedRevocationMapping<Table, Table, Table, N> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | OAuthUnavailable | PersistenceConfigurationError,\n Exclude<R, OAuthConnectedRevocations> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n coordinate(makeOAuthConnectedRevocationServices(options.mapping), (services) =>\n Effect.provideService(body, OAuthConnectedRevocations, services.oauthConnectedRevocations),\n );\n\nexport const makeOAuthRegistrationServices = <Registration, N>(\n mapping: OAuthRegistrationMapping<Registration, Table, Table, Table, Table, Table, N>,\n): Effect.Effect<\n { readonly registrationAuthority: OAuthRegistrationAuthority<Registration> },\n OAuthUnavailable | PersistenceConfigurationError,\n Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n using(mapping, (tables, value) =>\n makeNativeOAuthRegistrationServices(\n tables,\n value as unknown as OAuthNativeRegistrationMapping<Registration>,\n ),\n );\n\nexport const coordinateOAuthRegistration = <Id, Registration, N, A, E, R>(\n options: {\n readonly mapping: OAuthRegistrationMapping<\n NoInfer<Registration>,\n Table,\n Table,\n Table,\n Table,\n Table,\n N\n >;\n readonly target: Context.Key<Id, OAuthRegistrationAuthority<Registration>>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | OAuthUnavailable | PersistenceConfigurationError,\n Exclude<R, Id> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n> =>\n coordinate(makeOAuthRegistrationServices(options.mapping), (services) =>\n Effect.provideService(body, options.target, services.registrationAuthority),\n );\n\nexport const oauthConnectedOwnershipReferences = <N>(\n mapping: OAuthConnectedMapping<Table, Table, Table, Table, Table, N, Table>,\n) => ({\n connectedReference: (input: { readonly identityKey: string; readonly subjectId: N }) => {\n const g = mapping.grant;\n const grant = sql`exists(select 1 from ${g.table} where ${g.table.columns[g.identityKey]} = ${input.identityKey} and ${g.table.columns[g.subjectId]} = ${input.subjectId})`;\n\n if (mapping.revocation.mode === \"unsupported\") return grant;\n const j = mapping.revocation.job;\n\n return sql`(${grant}) or exists(select 1 from ${j.table} where ${j.table.columns[j.identityKey]} = ${input.identityKey} and ${j.table.columns[j.subjectId]} = ${input.subjectId})`;\n },\n});\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PersistenceMappingError } from "./internal/mapping-error.mjs";
|
|
2
2
|
import { OAuthProxyPersistence } from "./internal/oauth-proxy.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { StorageTable } from "./internal/storage-tables.mjs";
|
|
4
4
|
import { PersistenceConfigurationError } from "./internal/configuration.mjs";
|
|
5
5
|
import { OAuthPersistence_d_exports } from "./OAuthPersistence.mjs";
|
|
6
6
|
import { AuthPersistence } from "./internal/sql-persistence.mjs";
|
|
7
7
|
import { OAuthServerPersistence } from "./internal/oauth-server.mjs";
|
|
8
8
|
import { BrowserLoginPersistence } from "./internal/browser-login.mjs";
|
|
9
|
-
export { AuthPersistence, BrowserLoginPersistence, OAuthPersistence_d_exports as OAuthPersistence, OAuthProxyPersistence, OAuthServerPersistence, PersistenceConfigurationError, PersistenceMappingError,
|
|
9
|
+
export { AuthPersistence, BrowserLoginPersistence, OAuthPersistence_d_exports as OAuthPersistence, OAuthProxyPersistence, OAuthServerPersistence, PersistenceConfigurationError, PersistenceMappingError, StorageTable };
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PersistenceConfigurationError } from "./internal/configuration.mjs";
|
|
2
2
|
import { PersistenceMappingError } from "./internal/mapping-error.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { StorageTable } from "./internal/storage-tables.mjs";
|
|
4
4
|
import { AuthPersistence } from "./internal/sql-persistence.mjs";
|
|
5
5
|
import { OAuthServerPersistence } from "./internal/oauth-server.mjs";
|
|
6
6
|
import { OAuthProxyPersistence } from "./internal/oauth-proxy.mjs";
|
|
7
7
|
import { BrowserLoginPersistence } from "./internal/browser-login.mjs";
|
|
8
8
|
import { OAuthPersistence_exports } from "./OAuthPersistence.mjs";
|
|
9
|
-
export { AuthPersistence, BrowserLoginPersistence, OAuthPersistence_exports as OAuthPersistence, OAuthProxyPersistence, OAuthServerPersistence, PersistenceConfigurationError, PersistenceMappingError,
|
|
9
|
+
export { AuthPersistence, BrowserLoginPersistence, OAuthPersistence_exports as OAuthPersistence, OAuthProxyPersistence, OAuthServerPersistence, PersistenceConfigurationError, PersistenceMappingError, StorageTable };
|
|
@@ -4,7 +4,7 @@ import { Persistence, Unavailable } from "@yielded/auth/BrowserLogin";
|
|
|
4
4
|
//#region src/internal/browser-login.d.ts
|
|
5
5
|
export declare const BrowserLoginPersistence: {
|
|
6
6
|
migration: string;
|
|
7
|
-
layer: Layer.Layer<Persistence, Unavailable, SqlClient.SqlClient>;
|
|
7
|
+
layer: Layer.Layer<Persistence, Unavailable, import("@yielded/auth/Hooks").LifecycleHooks | SqlClient.SqlClient>;
|
|
8
8
|
};
|
|
9
9
|
//#endregion
|
|
10
10
|
//# sourceMappingURL=browser-login.d.mts.map
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Table } from "./sql-table.mjs";
|
|
2
|
+
import { makeNativeSqlTables } from "./native-sql-table.mjs";
|
|
3
|
+
import { exactSqlText } from "./sql-change.mjs";
|
|
4
|
+
import { makeSqlCommitExecutor } from "./sql-commit.mjs";
|
|
5
|
+
import { cleanupSqlRows } from "./sql-cleanup.mjs";
|
|
2
6
|
import { Effect, Layer, Schema } from "effect";
|
|
3
7
|
import { SqlClient } from "effect/sql";
|
|
4
8
|
import { Persistence, Record, Unavailable } from "@yielded/auth/BrowserLogin";
|
|
@@ -24,15 +28,33 @@ const BrowserLoginPersistence = {
|
|
|
24
28
|
pg: () => true,
|
|
25
29
|
orElse: () => false
|
|
26
30
|
})) return yield* Unavailable.make({});
|
|
27
|
-
const
|
|
28
|
-
const
|
|
31
|
+
const executor = yield* makeSqlCommitExecutor(() => Unavailable.make({}));
|
|
32
|
+
const table = makeNativeSqlTables(sql)(new Table("yielded_browser_login", {
|
|
33
|
+
namespace: {
|
|
34
|
+
name: "namespace",
|
|
35
|
+
type: "text"
|
|
36
|
+
},
|
|
37
|
+
attemptId: {
|
|
38
|
+
name: "attempt_id",
|
|
39
|
+
type: "text"
|
|
40
|
+
},
|
|
41
|
+
expiresAt: {
|
|
42
|
+
name: "expires_at_millis",
|
|
43
|
+
type: "integer"
|
|
44
|
+
}
|
|
45
|
+
}, [["namespace", "attemptId"]]));
|
|
29
46
|
const clock = sql.onDialectOrElse({
|
|
30
47
|
sqlite: () => sql.literal("CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)"),
|
|
31
48
|
orElse: () => sql.literal("CAST(EXTRACT(EPOCH FROM clock_timestamp()) * 1000 AS BIGINT)")
|
|
32
49
|
});
|
|
33
50
|
return Persistence.of({
|
|
51
|
+
cleanup: ({ namespace, limit }) => executor.run(cleanupSqlRows([{
|
|
52
|
+
table,
|
|
53
|
+
keys: ["namespace", "attemptId"],
|
|
54
|
+
due: sql`${exactSqlText(sql, table.column("namespace"), table.value("namespace", namespace))} and ${table.column("expiresAt")} <= ${clock}`,
|
|
55
|
+
order: [table.column("expiresAt"), table.column("attemptId")]
|
|
56
|
+
}], limit), "statement"),
|
|
34
57
|
get: Effect.fnUntraced(function* (namespace, id) {
|
|
35
|
-
yield* standalone;
|
|
36
58
|
const rows = yield* sql`SELECT payload, version FROM yielded_browser_login WHERE namespace = ${namespace} AND attempt_id = ${id}`;
|
|
37
59
|
if (rows.length === 0) return void 0;
|
|
38
60
|
if (rows.length !== 1) return yield* Unavailable.make({});
|
|
@@ -40,24 +62,22 @@ const BrowserLoginPersistence = {
|
|
|
40
62
|
const record = yield* Schema.decodeEffect(codec)(row.payload);
|
|
41
63
|
if (record.version !== row.version) return yield* Unavailable.make({});
|
|
42
64
|
return record;
|
|
43
|
-
},
|
|
65
|
+
}, executor.read),
|
|
44
66
|
insert: Effect.fnUntraced(function* (namespace, id, record) {
|
|
45
|
-
yield* standalone;
|
|
46
67
|
const payload = yield* Schema.encodeEffect(codec)(record);
|
|
47
68
|
return (yield* sql`INSERT INTO yielded_browser_login (namespace, attempt_id, version, expires_at_millis, payload)
|
|
48
69
|
SELECT ${namespace}, ${id}, ${record.version}, ${record.expiresAtMillis}, ${payload}
|
|
49
70
|
WHERE ${record.expiresAtMillis} > ${clock}
|
|
50
71
|
ON CONFLICT (namespace, attempt_id) DO NOTHING RETURNING version`).length === 1;
|
|
51
|
-
},
|
|
72
|
+
}, (effect) => executor.run(effect, "statement")),
|
|
52
73
|
compareAndSet: Effect.fnUntraced(function* (namespace, id, version, record) {
|
|
53
|
-
yield* standalone;
|
|
54
74
|
if (version === record.version) return yield* Unavailable.make({});
|
|
55
75
|
const payload = yield* Schema.encodeEffect(codec)(record);
|
|
56
76
|
return (yield* sql`UPDATE yielded_browser_login SET version = ${record.version}, payload = ${payload}
|
|
57
77
|
WHERE namespace = ${namespace} AND attempt_id = ${id} AND version = ${version}
|
|
58
78
|
AND expires_at_millis = ${record.expiresAtMillis} AND expires_at_millis > ${clock}
|
|
59
79
|
RETURNING version`).length === 1;
|
|
60
|
-
},
|
|
80
|
+
}, (effect) => executor.run(effect, "statement"))
|
|
61
81
|
});
|
|
62
82
|
}))
|
|
63
83
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-login.mjs","names":[],"sources":["../../src/internal/browser-login.ts"],"sourcesContent":["import { Persistence, Record, Unavailable } from \"@yielded/auth/BrowserLogin\";\nimport { Effect, Layer, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport {
|
|
1
|
+
{"version":3,"file":"browser-login.mjs","names":[],"sources":["../../src/internal/browser-login.ts"],"sourcesContent":["import { Persistence, Record, Unavailable } from \"@yielded/auth/BrowserLogin\";\nimport { Effect, Layer, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport { makeNativeSqlTables } from \"./native-sql-table\";\nimport { exactSqlText } from \"./sql-change\";\nimport { cleanupSqlRows } from \"./sql-cleanup\";\nimport { makeSqlCommitExecutor } from \"./sql-commit\";\nimport { Table } from \"./sql-table\";\n\nconst codec = Schema.fromJsonString(Record);\nconst Row = Schema.Struct({ payload: Schema.String, version: Schema.String });\n\n/** SQLite/D1 and PostgreSQL; apply through application migrations. Terminal\n * attempts are retained until expiry. Contains private provenance, never bearers.\n */\nconst migration = `CREATE TABLE yielded_browser_login (\n namespace TEXT NOT NULL,\n attempt_id TEXT NOT NULL,\n version TEXT NOT NULL,\n expires_at_millis BIGINT NOT NULL,\n payload TEXT NOT NULL,\n PRIMARY KEY (namespace, attempt_id)\n)`;\n\nconst layer = Layer.effect(\n Persistence,\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n if (!sql.onDialectOrElse({ sqlite: () => true, pg: () => true, orElse: () => false }))\n return yield* Unavailable.make({});\n const executor = yield* makeSqlCommitExecutor(() => Unavailable.make({}));\n\n const table = makeNativeSqlTables(sql)(\n new Table(\n \"yielded_browser_login\",\n {\n namespace: { name: \"namespace\", type: \"text\" },\n attemptId: { name: \"attempt_id\", type: \"text\" },\n expiresAt: { name: \"expires_at_millis\", type: \"integer\" },\n },\n [[\"namespace\", \"attemptId\"]],\n ),\n );\n\n const clock = sql.onDialectOrElse({\n sqlite: () => sql.literal(\"CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)\"),\n orElse: () => sql.literal(\"CAST(EXTRACT(EPOCH FROM clock_timestamp()) * 1000 AS BIGINT)\"),\n });\n\n return Persistence.of({\n cleanup: ({ namespace, limit }) =>\n executor.run(\n cleanupSqlRows(\n [\n {\n table,\n keys: [\"namespace\", \"attemptId\"],\n due: sql`${exactSqlText(sql, table.column(\"namespace\"), table.value(\"namespace\", namespace))} and ${table.column(\"expiresAt\")} <= ${clock}`,\n order: [table.column(\"expiresAt\"), table.column(\"attemptId\")],\n },\n ],\n limit,\n ),\n \"statement\",\n ),\n get: Effect.fnUntraced(function* (namespace, id) {\n const rows =\n yield* sql`SELECT payload, version FROM yielded_browser_login WHERE namespace = ${namespace} AND attempt_id = ${id}`;\n\n if (rows.length === 0) return undefined;\n if (rows.length !== 1) return yield* Unavailable.make({});\n const row = yield* Schema.decodeUnknownEffect(Row)(rows[0]);\n const record = yield* Schema.decodeEffect(codec)(row.payload);\n\n if (record.version !== row.version) return yield* Unavailable.make({});\n\n return record;\n }, executor.read),\n insert: Effect.fnUntraced(\n function* (namespace, id, record) {\n const payload = yield* Schema.encodeEffect(codec)(record);\n\n const rows =\n yield* sql`INSERT INTO yielded_browser_login (namespace, attempt_id, version, expires_at_millis, payload)\n SELECT ${namespace}, ${id}, ${record.version}, ${record.expiresAtMillis}, ${payload}\n WHERE ${record.expiresAtMillis} > ${clock}\n ON CONFLICT (namespace, attempt_id) DO NOTHING RETURNING version`;\n\n return rows.length === 1;\n },\n (effect) => executor.run(effect, \"statement\"),\n ),\n compareAndSet: Effect.fnUntraced(\n function* (namespace, id, version, record) {\n if (version === record.version) return yield* Unavailable.make({});\n const payload = yield* Schema.encodeEffect(codec)(record);\n\n const rows =\n yield* sql`UPDATE yielded_browser_login SET version = ${record.version}, payload = ${payload}\n WHERE namespace = ${namespace} AND attempt_id = ${id} AND version = ${version}\n AND expires_at_millis = ${record.expiresAtMillis} AND expires_at_millis > ${clock}\n RETURNING version`;\n\n return rows.length === 1;\n },\n (effect) => executor.run(effect, \"statement\"),\n ),\n });\n }),\n);\n\nexport const BrowserLoginPersistence = { migration, layer };\n"],"mappings":";;;;;;;;;AAUA,MAAM,QAAQ,OAAO,eAAe,MAAM;AAC1C,MAAM,MAAM,OAAO,OAAO;CAAE,SAAS,OAAO;CAAQ,SAAS,OAAO;AAAO,CAAC;AAsG5E,MAAa,0BAA0B;CAAE;;;;;;;;CAAW,OAxFtC,MAAM,OAClB,aACA,OAAO,IAAI,aAAa;EACtB,MAAM,MAAM,OAAO,UAAU;EAE7B,IAAI,CAAC,IAAI,gBAAgB;GAAE,cAAc;GAAM,UAAU;GAAM,cAAc;EAAM,CAAC,GAClF,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;EACnC,MAAM,WAAW,OAAO,4BAA4B,YAAY,KAAK,CAAC,CAAC,CAAC;EAExE,MAAM,QAAQ,oBAAoB,GAAG,CAAC,CACpC,IAAI,MACF,yBACA;GACE,WAAW;IAAE,MAAM;IAAa,MAAM;GAAO;GAC7C,WAAW;IAAE,MAAM;IAAc,MAAM;GAAO;GAC9C,WAAW;IAAE,MAAM;IAAqB,MAAM;GAAU;EAC1D,GACA,CAAC,CAAC,aAAa,WAAW,CAAC,CAC7B,CACF;EAEA,MAAM,QAAQ,IAAI,gBAAgB;GAChC,cAAc,IAAI,QAAQ,4DAA4D;GACtF,cAAc,IAAI,QAAQ,8DAA8D;EAC1F,CAAC;EAED,OAAO,YAAY,GAAG;GACpB,UAAU,EAAE,WAAW,YACrB,SAAS,IACP,eACE,CACE;IACE;IACA,MAAM,CAAC,aAAa,WAAW;IAC/B,KAAK,GAAG,GAAG,aAAa,KAAK,MAAM,OAAO,WAAW,GAAG,MAAM,MAAM,aAAa,SAAS,CAAC,EAAE,OAAO,MAAM,OAAO,WAAW,EAAE,MAAM;IACpI,OAAO,CAAC,MAAM,OAAO,WAAW,GAAG,MAAM,OAAO,WAAW,CAAC;GAC9D,CACF,GACA,KACF,GACA,WACF;GACF,KAAK,OAAO,WAAW,WAAW,WAAW,IAAI;IAC/C,MAAM,OACJ,OAAO,GAAG,wEAAwE,UAAU,oBAAoB;IAElH,IAAI,KAAK,WAAW,GAAG,OAAO,KAAA;IAC9B,IAAI,KAAK,WAAW,GAAG,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;IACxD,MAAM,MAAM,OAAO,OAAO,oBAAoB,GAAG,CAAC,CAAC,KAAK,EAAE;IAC1D,MAAM,SAAS,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC,IAAI,OAAO;IAE5D,IAAI,OAAO,YAAY,IAAI,SAAS,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;IAErE,OAAO;GACT,GAAG,SAAS,IAAI;GAChB,QAAQ,OAAO,WACb,WAAW,WAAW,IAAI,QAAQ;IAChC,MAAM,UAAU,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC,MAAM;IAQxD,QAAO,OALE,GAAG;iBACL,UAAU,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAI,OAAO,gBAAgB,IAAI,QAAQ;gBAC5E,OAAO,gBAAgB,KAAK,MAAM;0EAG7B,CAAC,WAAW;GACzB,IACC,WAAW,SAAS,IAAI,QAAQ,WAAW,CAC9C;GACA,eAAe,OAAO,WACpB,WAAW,WAAW,IAAI,SAAS,QAAQ;IACzC,IAAI,YAAY,OAAO,SAAS,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;IACjE,MAAM,UAAU,OAAO,OAAO,aAAa,KAAK,CAAC,CAAC,MAAM;IAQxD,QAAO,OALE,GAAG,8CAA8C,OAAO,QAAQ,cAAc,QAAQ;4BAC7E,UAAU,oBAAoB,GAAG,iBAAiB,QAAQ;kCACpD,OAAO,gBAAgB,2BAA2B,MAAM;2BAGrE,CAAC,WAAW;GACzB,IACC,WAAW,SAAS,IAAI,QAAQ,WAAW,CAC9C;EACF,CAAC;CACH,CAAC,CAGiD;AAAM"}
|
|
@@ -2,14 +2,14 @@ import { PersistenceMappingError } from "./mapping-error.mjs";
|
|
|
2
2
|
import { StorageRole } from "./storage-tables.mjs";
|
|
3
3
|
import { Context, Crypto, Effect, Layer, Schema } from "effect";
|
|
4
4
|
import { SqlClient } from "effect/sql";
|
|
5
|
-
import { PasskeyActionChallenge, PasskeyConfig, PasskeyConfigurationError, PasskeyCredentials, PasskeyEnrollmentContext, PasskeyManagementPersistence, PasskeyManagementPolicy, PasskeyMethodPolicy, PasskeyPersistence } from "@yielded/auth/Passkey";
|
|
6
|
-
import { SubjectId } from "@yielded/auth/Schema";
|
|
7
|
-
import { AuthenticationAuthority, AuthenticationRequirement, make } from "@yielded/auth/Sessions";
|
|
8
|
-
import { ProofPersistence } from "@yielded/auth/Proofs";
|
|
9
5
|
import { EmailAction, EmailAddressPersistence } from "@yielded/auth/Email";
|
|
6
|
+
import { PasskeyActionChallenge, PasskeyConfig, PasskeyConfigurationError, PasskeyCredentials, PasskeyManagementPersistence, PasskeyManagementPolicy, PasskeyMethodPolicy, PasskeyPersistence } from "@yielded/auth/Passkey";
|
|
10
7
|
import { PasswordAction, PasswordPersistence, PasswordUnavailable } from "@yielded/auth/Password";
|
|
11
|
-
import {
|
|
8
|
+
import { PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
|
|
9
|
+
import { ProofPersistence } from "@yielded/auth/Proofs";
|
|
10
|
+
import { AuthenticationAuthority, AuthenticationRequirement, make } from "@yielded/auth/Sessions";
|
|
12
11
|
import { LoginIdentifier } from "@yielded/auth/Identity";
|
|
12
|
+
import { SubjectId } from "@yielded/auth/Schema";
|
|
13
13
|
//#region src/internal/configuration.d.ts
|
|
14
14
|
declare const PersistenceConfigurationError_base: Schema.Class<PersistenceConfigurationError, Schema.TaggedStruct<"PersistenceConfigurationError", {
|
|
15
15
|
readonly reason: Schema.String;
|
|
@@ -86,6 +86,7 @@ export type Provisioning<A extends {
|
|
|
86
86
|
management: true;
|
|
87
87
|
};
|
|
88
88
|
} ? K : never]: (input: {
|
|
89
|
+
readonly requestId: string;
|
|
89
90
|
readonly identifier: LoginIdentifier;
|
|
90
91
|
readonly registration: Registration<A["strategies"][K]>;
|
|
91
92
|
}) => Effect.Effect<SubjectId, PasswordUnavailable>; };
|
|
@@ -93,12 +94,12 @@ export type ProvisioningRequirement<A extends {
|
|
|
93
94
|
readonly namespace: string;
|
|
94
95
|
readonly strategies: Readonly<Record<string, Strategy>>;
|
|
95
96
|
}> = ManagedPassword<A> extends never ? never : ProvisioningId<A["namespace"]>;
|
|
96
|
-
type ProofRoles = "
|
|
97
|
+
type ProofRoles = "proofs";
|
|
97
98
|
type UsesProofs<A extends {
|
|
98
99
|
readonly strategies: Readonly<Record<string, Strategy>>;
|
|
99
100
|
}> = Enabled<A, "phone"> | Enabled<A, "email"> | ManagedPassword<A>;
|
|
100
|
-
export type Ports<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> = AuthenticationAuthority | KeyId<A["sessions"]["StatefulSessionPersistence"]> | KeyId<A["sessions"]["SessionRepository"]> | (Enabled<A, "password"> extends never ? never : PasswordPersistence) | KeyId<RegistrationKey<ManagedPassword<A>>> | (Enabled<A, "passkey"> extends never ? never : PasskeyPersistence | PasskeyCredentials) | (ManagedPasskey<A> extends never ? never : PasskeyManagementPersistence
|
|
101
|
-
export type Roles<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> = "identifiers" | "credentials" | "sessions" | "
|
|
101
|
+
export type Ports<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> = AuthenticationAuthority | KeyId<A["sessions"]["StatefulSessionPersistence"]> | KeyId<A["sessions"]["SessionRepository"]> | KeyId<A["sessions"]["PendingAuthentication"]> | KeyId<A["sessions"]["SessionStepUpPersistence"]> | KeyId<A["sessions"]["SessionCleanup"]> | (Enabled<A, "password"> extends never ? never : PasswordPersistence) | KeyId<RegistrationKey<ManagedPassword<A>>> | (Enabled<A, "passkey"> extends never ? never : PasskeyPersistence | PasskeyCredentials) | (ManagedPasskey<A> extends never ? never : PasskeyManagementPersistence) | (Enabled<A, "email"> extends never ? never : EmailAddressPersistence) | (UsesProofs<A> extends never ? never : ProofPersistence) | (Enabled<A, "phone"> extends never ? never : PhoneSignInTargets);
|
|
102
|
+
export type Roles<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> = "identifiers" | "credentials" | "sessions" | "pending" | (Enabled<A, "password"> extends never ? never : "passwords") | (Enabled<A, "email"> extends never ? never : "emailCredentials") | (Enabled<A, "passkey"> extends never ? never : "passkeyCredentials" | "passkeyFlows") | (UsesProofs<A> extends never ? never : ProofRoles);
|
|
102
103
|
export interface SubjectOptions<T extends object, NativeId> {
|
|
103
104
|
readonly table: T;
|
|
104
105
|
readonly id: string;
|
|
@@ -152,6 +153,10 @@ export interface BoundPersistence<T extends object, R, C extends ClaimsCodec, Id
|
|
|
152
153
|
* Do not perform external side effects or open an independent transaction here.
|
|
153
154
|
*/
|
|
154
155
|
readonly Provisioning: Context.Service<ProvisioningRequirement<A>, Provisioning<A>>;
|
|
156
|
+
/** Capture dependencies at acquisition; validate SQL metadata and configure storage
|
|
157
|
+
* once on the first service operation. Initialization failures become that port's
|
|
158
|
+
* unavailable error. Failure or interruption remains cached until layer reacquisition.
|
|
159
|
+
*/
|
|
155
160
|
readonly layer: Layer.Layer<Ports<C, Id, A>, PersistenceConfigurationError, Crypto.Crypto | ConfigId<A["namespace"]> | ProvisioningRequirement<A> | PasskeyRequirement$1<A> | SqlClient.SqlClient | R>;
|
|
156
161
|
readonly managed: <N, Instant = number>(options: {
|
|
157
162
|
readonly subjects: SubjectOptions<T, N>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.mjs","names":[],"sources":["../../src/internal/configuration.ts"],"sourcesContent":["import type { EmailAction, EmailAddressPersistence } from \"@yielded/auth/Email\";\nimport type { LoginIdentifier } from \"@yielded/auth/Identity\";\nimport type {\n PasskeyActionChallenge,\n PasskeyConfig,\n PasskeyCredentials,\n PasskeyEnrollmentContext,\n PasskeyManagementPersistence,\n PasskeyManagementPolicy,\n PasskeyMethodPolicy,\n PasskeyPersistence,\n PasskeyConfigurationError,\n} from \"@yielded/auth/Passkey\";\nimport type {\n PasswordAction,\n PasswordPersistence,\n PasswordUnavailable,\n} from \"@yielded/auth/Password\";\nimport type { PhoneAdmission, PhoneSignInTargets } from \"@yielded/auth/PhoneOtp\";\nimport type { ProofPersistence } from \"@yielded/auth/Proofs\";\nimport type { SubjectId } from \"@yielded/auth/Schema\";\nimport type {\n AuthenticationAuthority,\n AuthenticationRequirement,\n make as makeSessions,\n} from \"@yielded/auth/Sessions\";\nimport { type Context, type Crypto, type Effect, type Layer, Schema } from \"effect\";\nimport type { SqlClient } from \"effect/sql\";\n\nimport type { PersistenceMappingError } from \"./mapping-error\";\nimport type { StorageRole } from \"./storage-tables\";\n\nexport class PersistenceConfigurationError extends Schema.TaggedError<PersistenceConfigurationError>()(\n \"PersistenceConfigurationError\",\n { reason: Schema.String },\n) {}\n\nexport type ClaimsCodec = Schema.Codec<unknown, unknown, never, never>;\n\nexport interface PasskeyFeature {\n readonly kind: \"passkey\";\n readonly moduleId: string;\n readonly policy: Effect.Effect<PasskeyMethodPolicy, PasskeyConfigurationError, PasskeyConfig>;\n readonly management?: boolean;\n readonly managementPolicy?: PasskeyManagementPolicy;\n}\n\nexport interface Strategy {\n readonly strategy: object;\n readonly persistence?:\n | PasskeyFeature\n | {\n readonly kind: \"password\" | \"phone\" | \"email\";\n readonly moduleId: string;\n readonly lifecycle?: boolean;\n readonly management?: boolean;\n readonly addresses?: boolean;\n };\n readonly RegistrationAuthority?: Context.Key<unknown, unknown>;\n}\n\nexport interface Definition<C extends ClaimsCodec, Id extends string> {\n readonly namespace: string;\n readonly claims: C;\n readonly sessionMode?: string | undefined;\n readonly sessions: ReturnType<typeof makeSessions<C, Id>>;\n readonly strategies: Readonly<Record<string, Strategy>>;\n}\n\ntype KeyId<T> = T extends Context.Key<infer Id, infer _Service> ? Id : never;\ntype Enabled<\n A extends { readonly strategies: Readonly<Record<string, Strategy>> },\n Kind extends \"password\" | \"phone\" | \"email\" | \"passkey\",\n> = Extract<A[\"strategies\"][keyof A[\"strategies\"]], { persistence: { kind: Kind } }>;\n\ntype ManagedPassword<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =\n Extract<Enabled<A, \"password\">, { persistence: { management: true } }>;\n\ntype ManagedPasskey<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =\n Extract<Enabled<A, \"passkey\">, { persistence: { management: true } }>;\n\nexport type PasskeyRequirement<\n A extends { readonly strategies: Readonly<Record<string, Strategy>> },\n> = Enabled<A, \"passkey\"> extends never ? never : PasskeyConfig;\n\ntype RegistrationKey<S> = S extends { readonly RegistrationAuthority: infer K } ? K : never;\ntype Registration<S> =\n RegistrationKey<S> extends Context.Key<infer _Id, infer Service>\n ? Service extends { readonly register: (input: infer Input, ...args: never[]) => unknown }\n ? Input extends { readonly registration: infer Value }\n ? Value\n : never\n : never\n : never;\n\nexport interface ProvisioningId<Id extends string> {\n readonly authNamespace: Id;\n readonly service: \"PersistenceProvisioning\";\n}\n\nexport type Provisioning<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> = {\n readonly [\n K in keyof A[\"strategies\"] as A[\"strategies\"][K] extends {\n persistence: { kind: \"password\"; management: true };\n }\n ? K\n : never\n ]: (input: {\n readonly identifier: LoginIdentifier;\n readonly registration: Registration<A[\"strategies\"][K]>;\n }) => Effect.Effect<SubjectId, PasswordUnavailable>;\n};\n\nexport type ProvisioningRequirement<\n A extends { readonly namespace: string; readonly strategies: Readonly<Record<string, Strategy>> },\n> = ManagedPassword<A> extends never ? never : ProvisioningId<A[\"namespace\"]>;\n\ntype ProofRoles =\n | \"proofRequests\"\n | \"proofSeries\"\n | \"proofGenerations\"\n | \"proofContinuations\"\n | \"proofScopes\"\n | \"proofAbuse\"\n | \"proofFailures\"\n | \"proofCommands\";\n\ntype UsesProofs<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =\n | Enabled<A, \"phone\">\n | Enabled<A, \"email\">\n | ManagedPassword<A>;\n\nexport type Ports<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> =\n | AuthenticationAuthority\n | KeyId<A[\"sessions\"][\"StatefulSessionPersistence\"]>\n | KeyId<A[\"sessions\"][\"SessionRepository\"]>\n | (Enabled<A, \"password\"> extends never ? never : PasswordPersistence)\n | KeyId<RegistrationKey<ManagedPassword<A>>>\n | (Enabled<A, \"passkey\"> extends never ? never : PasskeyPersistence | PasskeyCredentials)\n | (ManagedPasskey<A> extends never\n ? never\n : PasskeyManagementPersistence | PasskeyEnrollmentContext)\n | (Enabled<A, \"email\"> extends never ? never : EmailAddressPersistence)\n | (UsesProofs<A> extends never ? never : ProofPersistence)\n | (Enabled<A, \"phone\"> extends never ? never : PhoneAdmission | PhoneSignInTargets);\n\nexport type Roles<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> =\n | \"identifiers\"\n | \"credentials\"\n | \"sessions\"\n | \"sessionFlows\"\n | (Enabled<A, \"password\"> extends never ? never : \"passwords\" | \"passwordCommands\")\n | (ManagedPassword<A> extends never ? never : \"passwordRegistrations\")\n | (Enabled<A, \"phone\"> extends never ? never : \"phoneState\")\n | (Enabled<A, \"email\"> extends never ? never : \"emailCredentials\" | \"emailCommands\")\n | (Enabled<A, \"passkey\"> extends never\n ? never\n :\n | \"passkeyCredentials\"\n | \"passkeyOwnership\"\n | \"passkeyHandles\"\n | \"passkeyModules\"\n | \"passkeyFlows\"\n | \"passkeyAdmissions\"\n | \"passkeyCharges\")\n | (ManagedPasskey<A> extends never ? never : \"passkeyCommands\")\n | (UsesProofs<A> extends never ? never : ProofRoles);\n\nexport interface SubjectOptions<T extends object, NativeId> {\n readonly table: T;\n readonly id: string;\n readonly status: string;\n readonly activeValue: unknown;\n readonly securityRevision: string;\n readonly idCodec: Schema.Codec<SubjectId, NativeId>;\n readonly requirements: (\n row: Readonly<Record<string, unknown>>,\n ) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;\n /** Defaults to sign-in requirements. Recovery can have a distinct application policy. */\n readonly actionRequirements?: (\n row: Readonly<Record<string, unknown>>,\n action: PasswordAction | EmailAction | PasskeyActionChallenge[\"action\"],\n ) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;\n}\n\n/** Codecs at the application-owned subject and timestamp boundary. */\nexport interface SubjectMapping {\n readonly table: object;\n readonly id: string;\n readonly status: string;\n readonly securityRevision: string;\n readonly activeValue: unknown;\n readonly requirements: SubjectOptions<object, unknown>[\"requirements\"];\n readonly actionRequirements: NonNullable<SubjectOptions<object, unknown>[\"actionRequirements\"]>;\n readonly toSubject: (value: unknown) => Effect.Effect<SubjectId, PersistenceMappingError>;\n readonly toNative: (value: SubjectId) => Effect.Effect<unknown, PersistenceMappingError>;\n readonly toSubjectSync: (value: unknown) => SubjectId;\n readonly toNativeSync: (value: SubjectId) => unknown;\n}\n\nexport interface MappingInput {\n readonly tables: Partial<Record<StorageRole, object>>;\n readonly subjects: SubjectMapping;\n readonly encodeInstant: (millis: number) => unknown;\n readonly decodeInstant: (value: unknown) => Effect.Effect<number, PersistenceMappingError>;\n readonly decodeInstantSync: (value: unknown) => number;\n}\n\nexport interface StorageLayout<\n T extends object,\n Role extends StorageRole = StorageRole,\n> extends MappingInput {\n readonly namespace: string;\n readonly schema: Readonly<Record<Role, T>>;\n}\n\nexport interface ConfigId<Id extends string> {\n readonly authNamespace: Id;\n readonly service: \"PersistenceConfig\";\n}\n\nexport interface TimestampOptions<Instant> {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n}\n\nexport interface BoundPersistence<\n T extends object,\n R,\n C extends ClaimsCodec,\n Id extends string,\n A extends Definition<C, Id>,\n> {\n readonly Config: Context.Service<ConfigId<A[\"namespace\"]>, StorageLayout<T, Roles<C, Id, A>>> & {\n readonly layer: (\n value: StorageLayout<T, Roles<C, Id, A>>,\n ) => Layer.Layer<ConfigId<A[\"namespace\"]>>;\n };\n /** Create only the application subject. Runs inside the owning auth SQL transaction;\n * use that SqlClient (including Drizzle over it), and return the new subject ID.\n * Do not perform external side effects or open an independent transaction here.\n */\n readonly Provisioning: Context.Service<ProvisioningRequirement<A>, Provisioning<A>>;\n readonly layer: Layer.Layer<\n Ports<C, Id, A>,\n PersistenceConfigurationError,\n | Crypto.Crypto\n | ConfigId<A[\"namespace\"]>\n | ProvisioningRequirement<A>\n | PasskeyRequirement<A>\n | SqlClient.SqlClient\n | R\n >;\n readonly managed: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables?: Partial<Record<Roles<C, Id, A>, T>>;\n /** Stable SQL identifier prefix; reuse the deployed prefix for existing tables. */\n readonly prefix: string;\n readonly timestamps?: TimestampOptions<Instant>;\n }) => StorageLayout<T, Roles<C, Id, A>>;\n readonly map: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables: Readonly<Record<Roles<C, Id, A>, T>>;\n readonly timestamps?: TimestampOptions<Instant>;\n }) => StorageLayout<T, Roles<C, Id, A>>;\n}\n\n/** Shared configuration shape. The backend chooses table types and service requirements. */\nexport interface PersistenceApi<T extends object, R = never> {\n readonly make: <\n C extends ClaimsCodec,\n const Id extends string,\n const A extends Definition<C, Id>,\n >(\n auth: A & Definition<C, Id>,\n ) => BoundPersistence<T, R, C, Id, A>;\n}\n"],"mappings":";;AAgCA,IAAa,gCAAb,cAAmD,OAAO,YAA2C,CAAC,CACpG,iCACA,EAAE,QAAQ,OAAO,OAAO,CAC1B,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"configuration.mjs","names":[],"sources":["../../src/internal/configuration.ts"],"sourcesContent":["import type { EmailAction, EmailAddressPersistence } from \"@yielded/auth/Email\";\nimport type { LoginIdentifier } from \"@yielded/auth/Identity\";\nimport type {\n PasskeyActionChallenge,\n PasskeyConfig,\n PasskeyCredentials,\n PasskeyManagementPersistence,\n PasskeyManagementPolicy,\n PasskeyMethodPolicy,\n PasskeyPersistence,\n PasskeyConfigurationError,\n} from \"@yielded/auth/Passkey\";\nimport type {\n PasswordAction,\n PasswordPersistence,\n PasswordUnavailable,\n} from \"@yielded/auth/Password\";\nimport type { PhoneSignInTargets } from \"@yielded/auth/PhoneOtp\";\nimport type { ProofPersistence } from \"@yielded/auth/Proofs\";\nimport type { SubjectId } from \"@yielded/auth/Schema\";\nimport type {\n AuthenticationAuthority,\n AuthenticationRequirement,\n make as makeSessions,\n} from \"@yielded/auth/Sessions\";\nimport { type Context, type Crypto, type Effect, type Layer, Schema } from \"effect\";\nimport type { SqlClient } from \"effect/sql\";\n\nimport type { PersistenceMappingError } from \"./mapping-error\";\nimport type { StorageRole } from \"./storage-tables\";\n\nexport class PersistenceConfigurationError extends Schema.TaggedError<PersistenceConfigurationError>()(\n \"PersistenceConfigurationError\",\n { reason: Schema.String },\n) {}\n\nexport type ClaimsCodec = Schema.Codec<unknown, unknown, never, never>;\n\nexport interface PasskeyFeature {\n readonly kind: \"passkey\";\n readonly moduleId: string;\n readonly policy: Effect.Effect<PasskeyMethodPolicy, PasskeyConfigurationError, PasskeyConfig>;\n readonly management?: boolean;\n readonly managementPolicy?: PasskeyManagementPolicy;\n}\n\nexport interface Strategy {\n readonly strategy: object;\n readonly persistence?:\n | PasskeyFeature\n | {\n readonly kind: \"password\" | \"phone\" | \"email\";\n readonly moduleId: string;\n readonly lifecycle?: boolean;\n readonly management?: boolean;\n readonly addresses?: boolean;\n };\n readonly RegistrationAuthority?: Context.Key<unknown, unknown>;\n}\n\nexport interface Definition<C extends ClaimsCodec, Id extends string> {\n readonly namespace: string;\n readonly claims: C;\n readonly sessionMode?: string | undefined;\n readonly sessions: ReturnType<typeof makeSessions<C, Id>>;\n readonly strategies: Readonly<Record<string, Strategy>>;\n}\n\ntype KeyId<T> = T extends Context.Key<infer Id, infer _Service> ? Id : never;\ntype Enabled<\n A extends { readonly strategies: Readonly<Record<string, Strategy>> },\n Kind extends \"password\" | \"phone\" | \"email\" | \"passkey\",\n> = Extract<A[\"strategies\"][keyof A[\"strategies\"]], { persistence: { kind: Kind } }>;\n\ntype ManagedPassword<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =\n Extract<Enabled<A, \"password\">, { persistence: { management: true } }>;\n\ntype ManagedPasskey<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =\n Extract<Enabled<A, \"passkey\">, { persistence: { management: true } }>;\n\nexport type PasskeyRequirement<\n A extends { readonly strategies: Readonly<Record<string, Strategy>> },\n> = Enabled<A, \"passkey\"> extends never ? never : PasskeyConfig;\n\ntype RegistrationKey<S> = S extends { readonly RegistrationAuthority: infer K } ? K : never;\ntype Registration<S> =\n RegistrationKey<S> extends Context.Key<infer _Id, infer Service>\n ? Service extends { readonly register: (input: infer Input, ...args: never[]) => unknown }\n ? Input extends { readonly registration: infer Value }\n ? Value\n : never\n : never\n : never;\n\nexport interface ProvisioningId<Id extends string> {\n readonly authNamespace: Id;\n readonly service: \"PersistenceProvisioning\";\n}\n\nexport type Provisioning<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> = {\n readonly [\n K in keyof A[\"strategies\"] as A[\"strategies\"][K] extends {\n persistence: { kind: \"password\"; management: true };\n }\n ? K\n : never\n ]: (input: {\n readonly requestId: string;\n readonly identifier: LoginIdentifier;\n readonly registration: Registration<A[\"strategies\"][K]>;\n }) => Effect.Effect<SubjectId, PasswordUnavailable>;\n};\n\nexport type ProvisioningRequirement<\n A extends { readonly namespace: string; readonly strategies: Readonly<Record<string, Strategy>> },\n> = ManagedPassword<A> extends never ? never : ProvisioningId<A[\"namespace\"]>;\n\ntype ProofRoles = \"proofs\";\n\ntype UsesProofs<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =\n | Enabled<A, \"phone\">\n | Enabled<A, \"email\">\n | ManagedPassword<A>;\n\nexport type Ports<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> =\n | AuthenticationAuthority\n | KeyId<A[\"sessions\"][\"StatefulSessionPersistence\"]>\n | KeyId<A[\"sessions\"][\"SessionRepository\"]>\n | KeyId<A[\"sessions\"][\"PendingAuthentication\"]>\n | KeyId<A[\"sessions\"][\"SessionStepUpPersistence\"]>\n | KeyId<A[\"sessions\"][\"SessionCleanup\"]>\n | (Enabled<A, \"password\"> extends never ? never : PasswordPersistence)\n | KeyId<RegistrationKey<ManagedPassword<A>>>\n | (Enabled<A, \"passkey\"> extends never ? never : PasskeyPersistence | PasskeyCredentials)\n | (ManagedPasskey<A> extends never ? never : PasskeyManagementPersistence)\n | (Enabled<A, \"email\"> extends never ? never : EmailAddressPersistence)\n | (UsesProofs<A> extends never ? never : ProofPersistence)\n | (Enabled<A, \"phone\"> extends never ? never : PhoneSignInTargets);\n\nexport type Roles<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> =\n | \"identifiers\"\n | \"credentials\"\n | \"sessions\"\n | \"pending\"\n | (Enabled<A, \"password\"> extends never ? never : \"passwords\")\n | (Enabled<A, \"email\"> extends never ? never : \"emailCredentials\")\n | (Enabled<A, \"passkey\"> extends never ? never : \"passkeyCredentials\" | \"passkeyFlows\")\n | (UsesProofs<A> extends never ? never : ProofRoles);\n\nexport interface SubjectOptions<T extends object, NativeId> {\n readonly table: T;\n readonly id: string;\n readonly status: string;\n readonly activeValue: unknown;\n readonly securityRevision: string;\n readonly idCodec: Schema.Codec<SubjectId, NativeId>;\n readonly requirements: (\n row: Readonly<Record<string, unknown>>,\n ) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;\n /** Defaults to sign-in requirements. Recovery can have a distinct application policy. */\n readonly actionRequirements?: (\n row: Readonly<Record<string, unknown>>,\n action: PasswordAction | EmailAction | PasskeyActionChallenge[\"action\"],\n ) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;\n}\n\n/** Codecs at the application-owned subject and timestamp boundary. */\nexport interface SubjectMapping {\n readonly table: object;\n readonly id: string;\n readonly status: string;\n readonly securityRevision: string;\n readonly activeValue: unknown;\n readonly requirements: SubjectOptions<object, unknown>[\"requirements\"];\n readonly actionRequirements: NonNullable<SubjectOptions<object, unknown>[\"actionRequirements\"]>;\n readonly toSubject: (value: unknown) => Effect.Effect<SubjectId, PersistenceMappingError>;\n readonly toNative: (value: SubjectId) => Effect.Effect<unknown, PersistenceMappingError>;\n readonly toSubjectSync: (value: unknown) => SubjectId;\n readonly toNativeSync: (value: SubjectId) => unknown;\n}\n\nexport interface MappingInput {\n readonly tables: Partial<Record<StorageRole, object>>;\n readonly subjects: SubjectMapping;\n readonly encodeInstant: (millis: number) => unknown;\n readonly decodeInstant: (value: unknown) => Effect.Effect<number, PersistenceMappingError>;\n readonly decodeInstantSync: (value: unknown) => number;\n}\n\nexport interface StorageLayout<\n T extends object,\n Role extends StorageRole = StorageRole,\n> extends MappingInput {\n readonly namespace: string;\n readonly schema: Readonly<Record<Role, T>>;\n}\n\nexport interface ConfigId<Id extends string> {\n readonly authNamespace: Id;\n readonly service: \"PersistenceConfig\";\n}\n\nexport interface TimestampOptions<Instant> {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n}\n\nexport interface BoundPersistence<\n T extends object,\n R,\n C extends ClaimsCodec,\n Id extends string,\n A extends Definition<C, Id>,\n> {\n readonly Config: Context.Service<ConfigId<A[\"namespace\"]>, StorageLayout<T, Roles<C, Id, A>>> & {\n readonly layer: (\n value: StorageLayout<T, Roles<C, Id, A>>,\n ) => Layer.Layer<ConfigId<A[\"namespace\"]>>;\n };\n /** Create only the application subject. Runs inside the owning auth SQL transaction;\n * use that SqlClient (including Drizzle over it), and return the new subject ID.\n * Do not perform external side effects or open an independent transaction here.\n */\n readonly Provisioning: Context.Service<ProvisioningRequirement<A>, Provisioning<A>>;\n /** Capture dependencies at acquisition; validate SQL metadata and configure storage\n * once on the first service operation. Initialization failures become that port's\n * unavailable error. Failure or interruption remains cached until layer reacquisition.\n */\n readonly layer: Layer.Layer<\n Ports<C, Id, A>,\n PersistenceConfigurationError,\n | Crypto.Crypto\n | ConfigId<A[\"namespace\"]>\n | ProvisioningRequirement<A>\n | PasskeyRequirement<A>\n | SqlClient.SqlClient\n | R\n >;\n readonly managed: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables?: Partial<Record<Roles<C, Id, A>, T>>;\n /** Stable SQL identifier prefix; reuse the deployed prefix for existing tables. */\n readonly prefix: string;\n readonly timestamps?: TimestampOptions<Instant>;\n }) => StorageLayout<T, Roles<C, Id, A>>;\n readonly map: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables: Readonly<Record<Roles<C, Id, A>, T>>;\n readonly timestamps?: TimestampOptions<Instant>;\n }) => StorageLayout<T, Roles<C, Id, A>>;\n}\n\n/** Shared configuration shape. The backend chooses table types and service requirements. */\nexport interface PersistenceApi<T extends object, R = never> {\n readonly make: <\n C extends ClaimsCodec,\n const Id extends string,\n const A extends Definition<C, Id>,\n >(\n auth: A & Definition<C, Id>,\n ) => BoundPersistence<T, R, C, Id, A>;\n}\n"],"mappings":";;AA+BA,IAAa,gCAAb,cAAmD,OAAO,YAA2C,CAAC,CACpG,iCACA,EAAE,QAAQ,OAAO,OAAO,CAC1B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Crypto, Effect } from "effect";
|
package/dist/internal/crypto.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Crypto, Effect } from "effect";
|
|
2
|
-
import { TokenDigest } from "@yielded/auth/Schema";
|
|
3
2
|
import { Base64Url } from "effect/encoding";
|
|
3
|
+
import { TokenDigest } from "@yielded/auth/Schema";
|
|
4
4
|
//#region src/internal/crypto.ts
|
|
5
5
|
const encoder = new TextEncoder();
|
|
6
6
|
const randomId = Effect.flatMap(Crypto.Crypto, (crypto) => crypto.randomBytes(32).pipe(Effect.map(Base64Url.encode)));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/internal/d1-planning.ts
|
|
2
|
+
/** A false predicate aborts the current D1 batch; checking its result after
|
|
3
|
+
* batch completion would be too late to roll the protected mutation back. */
|
|
4
|
+
const sqlBatchAssertion = (sql, condition) => sql`select case when ${condition} then 1 else json_extract('[]', '$[auth-batch-precondition]') end as valid`;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { sqlBatchAssertion };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=d1-planning.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d1-planning.mjs","names":[],"sources":["../../src/internal/d1-planning.ts"],"sourcesContent":["import type { SqlClient } from \"effect/sql/SqlClient\";\nimport type { Fragment } from \"effect/sql/Statement\";\n\n/** A false predicate aborts the current D1 batch; checking its result after\n * batch completion would be too late to roll the protected mutation back. */\nexport const sqlBatchAssertion = (sql: SqlClient, condition: Fragment) =>\n sql`select case when ${condition} then 1 else json_extract('[]', '$[auth-batch-precondition]') end as valid`;\n"],"mappings":";;;AAKA,MAAa,qBAAqB,KAAgB,cAChD,GAAG,oBAAoB,UAAU"}
|