@yielded/auth-persistence-drizzle 0.1.0-beta.0 → 0.1.0-beta.12
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 -1
- package/dist/D1.d.mts +155 -40
- package/dist/D1.mjs +10 -6
- package/dist/D1.mjs.map +1 -1
- package/dist/Libsql.d.mts +251 -129
- package/dist/Libsql.mjs +20 -21
- package/dist/Libsql.mjs.map +1 -1
- package/dist/Mysql2.d.mts +208 -56
- package/dist/Mysql2.mjs +13 -8
- package/dist/Mysql2.mjs.map +1 -1
- package/dist/Pglite.d.mts +209 -57
- package/dist/Pglite.mjs +13 -9
- package/dist/Pglite.mjs.map +1 -1
- package/dist/Postgres.d.mts +207 -55
- package/dist/Postgres.mjs +13 -9
- package/dist/Postgres.mjs.map +1 -1
- package/dist/SqliteBun.d.mts +249 -126
- package/dist/SqliteBun.mjs +20 -18
- package/dist/SqliteBun.mjs.map +1 -1
- package/dist/SqliteDo.d.mts +248 -158
- package/dist/SqliteDo.mjs +26 -44
- package/dist/SqliteDo.mjs.map +1 -1
- package/dist/SqliteNode.d.mts +247 -124
- package/dist/SqliteNode.mjs +20 -18
- package/dist/SqliteNode.mjs.map +1 -1
- package/dist/SqliteWasm.d.mts +251 -128
- package/dist/SqliteWasm.mjs +20 -18
- package/dist/SqliteWasm.mjs.map +1 -1
- package/dist/drizzle/D1BatchStatements.d.mts +1 -1
- package/dist/drizzle/D1BatchStatements.mjs.map +1 -1
- package/dist/drizzle/d1-database.d.mts +11 -0
- package/dist/drizzle/d1-database.mjs +8 -0
- package/dist/drizzle/d1-database.mjs.map +1 -0
- package/dist/drizzle/d1-emails.d.mts +8 -7
- package/dist/drizzle/d1-emails.mjs +7 -4
- package/dist/drizzle/d1-emails.mjs.map +1 -1
- package/dist/drizzle/d1-generated-statement.mjs.map +1 -1
- package/dist/drizzle/d1-identity.mjs +12 -9
- package/dist/drizzle/d1-identity.mjs.map +1 -1
- package/dist/drizzle/d1-oauth.d.mts +41 -10
- package/dist/drizzle/d1-oauth.mjs +8 -5
- package/dist/drizzle/d1-oauth.mjs.map +1 -1
- package/dist/drizzle/d1-passkey.d.mts +3 -14
- package/dist/drizzle/d1-passkey.mjs +2 -1
- package/dist/drizzle/d1-passkey.mjs.map +1 -1
- package/dist/drizzle/d1-password-prepared.d.mts +4 -3
- package/dist/drizzle/d1-password-prepared.mjs +3 -1
- package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
- package/dist/drizzle/d1-passwords.d.mts +7 -6
- package/dist/drizzle/d1-passwords.mjs +5 -2
- package/dist/drizzle/d1-passwords.mjs.map +1 -1
- package/dist/drizzle/d1-phone.d.mts +3 -4
- package/dist/drizzle/d1-phone.mjs +2 -1
- package/dist/drizzle/d1-phone.mjs.map +1 -1
- package/dist/drizzle/d1-planning.d.mts +1 -1
- package/dist/drizzle/d1-proofs.d.mts +5 -4
- package/dist/drizzle/d1-proofs.mjs +3 -1
- package/dist/drizzle/d1-proofs.mjs.map +1 -1
- package/dist/drizzle/d1-sessions.d.mts +14 -13
- package/dist/drizzle/d1-sessions.mjs +15 -9
- package/dist/drizzle/d1-sessions.mjs.map +1 -1
- package/dist/drizzle/d1-totp.d.mts +3 -4
- package/dist/drizzle/d1-totp.mjs +2 -1
- package/dist/drizzle/d1-totp.mjs.map +1 -1
- package/dist/drizzle/email-registration.d.mts +1 -1
- package/dist/drizzle/email-registration.mjs +2 -1
- package/dist/drizzle/email-registration.mjs.map +1 -1
- package/dist/drizzle/email-target.d.mts +8 -7
- package/dist/drizzle/email-target.mjs +10 -10
- package/dist/drizzle/email-target.mjs.map +1 -1
- package/dist/drizzle/model.d.mts +2 -126
- package/dist/drizzle/model.mjs +2 -21
- package/dist/drizzle/model.mjs.map +1 -1
- package/dist/drizzle/mysql-database.d.mts +8 -0
- package/dist/drizzle/mysql-database.mjs +8 -0
- package/dist/drizzle/mysql-database.mjs.map +1 -0
- package/dist/drizzle/mysql-emails.d.mts +8 -7
- package/dist/drizzle/mysql-emails.mjs +12 -8
- package/dist/drizzle/mysql-emails.mjs.map +1 -1
- package/dist/drizzle/mysql-identity.mjs +12 -9
- package/dist/drizzle/mysql-identity.mjs.map +1 -1
- package/dist/drizzle/mysql-password-prepared.d.mts +4 -3
- package/dist/drizzle/mysql-password-prepared.mjs +6 -2
- package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
- package/dist/drizzle/mysql-passwords.d.mts +7 -5
- package/dist/drizzle/mysql-passwords.mjs +11 -7
- package/dist/drizzle/mysql-passwords.mjs.map +1 -1
- package/dist/drizzle/mysql-proofs.d.mts +4 -3
- package/dist/drizzle/mysql-proofs.mjs +8 -4
- package/dist/drizzle/mysql-proofs.mjs.map +1 -1
- package/dist/drizzle/mysql-sessions.d.mts +12 -11
- package/dist/drizzle/mysql-sessions.mjs +16 -12
- package/dist/drizzle/mysql-sessions.mjs.map +1 -1
- package/dist/drizzle/native-database.mjs +10 -0
- package/dist/drizzle/native-database.mjs.map +1 -0
- package/dist/drizzle/oauth-accounts.mjs +1 -1
- package/dist/drizzle/oauth-connected-access.mjs +14 -12
- package/dist/drizzle/oauth-connected-access.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-custody.mjs +2 -2
- package/dist/drizzle/oauth-connected-drivers.mjs +11 -6
- package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-flow.mjs +2 -2
- package/dist/drizzle/oauth-connected-input.mjs +14 -1
- package/dist/drizzle/oauth-connected-input.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-maintenance.mjs +1 -1
- package/dist/drizzle/oauth-connected-management.mjs +2 -2
- package/dist/drizzle/oauth-connected-model.d.mts +17 -3
- package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-settlement.mjs +51 -41
- package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-sign-in.mjs +263 -0
- package/dist/drizzle/oauth-connected-sign-in.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-state.d.mts +110 -2
- package/dist/drizzle/oauth-connected-state.mjs +9 -4
- package/dist/drizzle/oauth-connected-state.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-target.d.mts +142 -15
- package/dist/drizzle/oauth-connected-target.mjs +9 -6
- package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
- package/dist/drizzle/oauth-drivers.mjs +9 -7
- package/dist/drizzle/oauth-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-flow.d.mts +1 -1
- package/dist/drizzle/oauth-flow.mjs +1 -1
- package/dist/drizzle/oauth-input.mjs +1 -1
- package/dist/drizzle/oauth-model.d.mts +1 -1
- package/dist/drizzle/oauth-owner.d.mts +1 -1
- package/dist/drizzle/oauth-registration.d.mts +2 -2
- package/dist/drizzle/oauth-registration.mjs +1 -1
- package/dist/drizzle/oauth-state.mjs +5 -4
- package/dist/drizzle/oauth-state.mjs.map +1 -1
- package/dist/drizzle/oauth-target.d.mts +14 -13
- package/dist/drizzle/oauth-target.mjs +14 -13
- package/dist/drizzle/oauth-target.mjs.map +1 -1
- package/dist/drizzle/passkey-drivers.mjs +8 -6
- package/dist/drizzle/passkey-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-drivers.mjs +5 -3
- package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-target.d.mts +1 -1
- package/dist/drizzle/password-prepared-sql.mjs +2 -1
- package/dist/drizzle/password-prepared-sql.mjs.map +1 -1
- package/dist/drizzle/password-prepared-state.mjs +1 -1
- package/dist/drizzle/password-prepared-target.d.mts +4 -3
- package/dist/drizzle/password-prepared-target.mjs +4 -3
- package/dist/drizzle/password-prepared-target.mjs.map +1 -1
- package/dist/drizzle/password-registration.mjs +2 -1
- package/dist/drizzle/password-registration.mjs.map +1 -1
- package/dist/drizzle/password-target.d.mts +6 -5
- package/dist/drizzle/password-target.mjs +8 -8
- package/dist/drizzle/password-target.mjs.map +1 -1
- package/dist/drizzle/pg-database.d.mts +9 -0
- package/dist/drizzle/pg-database.mjs +8 -0
- package/dist/drizzle/pg-database.mjs.map +1 -0
- package/dist/drizzle/pg-emails.d.mts +8 -7
- package/dist/drizzle/pg-emails.mjs +12 -8
- package/dist/drizzle/pg-emails.mjs.map +1 -1
- package/dist/drizzle/pg-identity.mjs +92 -0
- package/dist/drizzle/pg-identity.mjs.map +1 -0
- package/dist/drizzle/pg-password-prepared.d.mts +4 -3
- package/dist/drizzle/pg-password-prepared.mjs +6 -2
- package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
- package/dist/drizzle/pg-passwords.d.mts +7 -5
- package/dist/drizzle/pg-passwords.mjs +11 -7
- package/dist/drizzle/pg-passwords.mjs.map +1 -1
- package/dist/drizzle/pg-proofs.d.mts +4 -3
- package/dist/drizzle/pg-proofs.mjs +8 -4
- package/dist/drizzle/pg-proofs.mjs.map +1 -1
- package/dist/drizzle/pg-sessions.d.mts +12 -11
- package/dist/drizzle/pg-sessions.mjs +16 -12
- package/dist/drizzle/pg-sessions.mjs.map +1 -1
- package/dist/drizzle/phone-model.d.mts +1 -1
- package/dist/drizzle/phone-target.d.mts +5 -4
- package/dist/drizzle/phone-target.mjs +12 -11
- package/dist/drizzle/phone-target.mjs.map +1 -1
- package/dist/drizzle/proof-target.d.mts +4 -3
- package/dist/drizzle/proof-target.mjs +5 -5
- package/dist/drizzle/proof-target.mjs.map +1 -1
- package/dist/drizzle/session-sql.d.mts +1 -0
- package/dist/drizzle/session-target.d.mts +11 -9
- package/dist/drizzle/session-target.mjs +11 -11
- package/dist/drizzle/session-target.mjs.map +1 -1
- package/dist/drizzle/sqlite-emails.mjs +9 -5
- package/dist/drizzle/sqlite-emails.mjs.map +1 -1
- package/dist/drizzle/sqlite-identity.mjs +14 -11
- package/dist/drizzle/sqlite-identity.mjs.map +1 -1
- package/dist/drizzle/sqlite-password-prepared.mjs +7 -3
- package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
- package/dist/drizzle/sqlite-passwords.mjs +10 -6
- package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
- package/dist/drizzle/sqlite-proofs.mjs +7 -3
- package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
- package/dist/drizzle/sqlite-sessions.mjs +16 -12
- package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
- package/dist/drizzle/standalone-guard.d.mts +2 -0
- package/dist/drizzle/standalone-guard.mjs +8 -4
- package/dist/drizzle/standalone-guard.mjs.map +1 -1
- package/dist/drizzle/totp-model.d.mts +1 -1
- package/dist/drizzle/totp-target.d.mts +5 -4
- package/dist/drizzle/totp-target.mjs +31 -28
- package/dist/drizzle/totp-target.mjs.map +1 -1
- package/dist/drizzle/transaction-mysql.mjs +1 -1
- package/dist/drizzle/transaction-mysql.mjs.map +1 -1
- package/dist/index.d.mts +2 -4
- package/dist/index.mjs +2 -4
- package/dist/internal/drizzle-postgres.mjs.map +1 -1
- package/dist/internal/drizzle-sqlite.mjs.map +1 -1
- package/package.json +1 -1
- package/src/D1.ts +37 -26
- package/src/Libsql.ts +45 -61
- package/src/Mysql2.ts +39 -35
- package/src/Pglite.ts +48 -30
- package/src/Postgres.ts +48 -30
- package/src/SqliteBun.ts +59 -68
- package/src/SqliteDo.ts +61 -274
- package/src/SqliteNode.ts +56 -66
- package/src/SqliteWasm.ts +56 -66
- package/src/drizzle/D1BatchStatements.ts +1 -1
- package/src/drizzle/d1-database.ts +10 -0
- package/src/drizzle/d1-emails.ts +86 -88
- package/src/drizzle/d1-generated-statement.ts +1 -1
- package/src/drizzle/d1-identity.ts +17 -20
- package/src/drizzle/d1-oauth.ts +19 -8
- package/src/drizzle/d1-passkey.ts +5 -1
- package/src/drizzle/d1-password-prepared.ts +40 -42
- package/src/drizzle/d1-passwords.ts +76 -80
- package/src/drizzle/d1-phone.ts +5 -1
- package/src/drizzle/d1-proofs.ts +31 -34
- package/src/drizzle/d1-sessions.ts +53 -40
- package/src/drizzle/d1-totp.ts +5 -1
- package/src/drizzle/email-registration.ts +6 -2
- package/src/drizzle/email-target.ts +18 -20
- package/src/drizzle/model.ts +1 -208
- package/src/drizzle/mysql-database.ts +8 -0
- package/src/drizzle/mysql-emails.ts +29 -17
- package/src/drizzle/mysql-identity.ts +18 -21
- package/src/drizzle/mysql-password-prepared.ts +11 -9
- package/src/drizzle/mysql-passwords.ts +22 -10
- package/src/drizzle/mysql-proofs.ts +17 -6
- package/src/drizzle/mysql-sessions.ts +41 -18
- package/src/drizzle/native-database.ts +22 -0
- package/src/drizzle/oauth-connected-access.ts +8 -1
- package/src/drizzle/oauth-connected-drivers.ts +21 -6
- package/src/drizzle/oauth-connected-input.ts +13 -0
- package/src/drizzle/oauth-connected-model.ts +17 -0
- package/src/drizzle/oauth-connected-settlement.ts +65 -42
- package/src/drizzle/oauth-connected-sign-in.ts +438 -0
- package/src/drizzle/oauth-connected-state.ts +19 -7
- package/src/drizzle/oauth-connected-target.ts +26 -18
- package/src/drizzle/oauth-drivers.ts +26 -10
- package/src/drizzle/oauth-state.ts +5 -4
- package/src/drizzle/oauth-target.ts +31 -43
- package/src/drizzle/passkey-drivers.ts +21 -13
- package/src/drizzle/passkey-write-drivers.ts +11 -6
- package/src/drizzle/password-prepared-sql.ts +2 -4
- package/src/drizzle/password-prepared-target.ts +10 -7
- package/src/drizzle/password-registration.ts +7 -8
- package/src/drizzle/password-target.ts +20 -19
- package/src/drizzle/pg-database.ts +10 -0
- package/src/drizzle/pg-emails.ts +29 -17
- package/src/drizzle/pg-identity.ts +297 -0
- package/src/drizzle/pg-password-prepared.ts +11 -9
- package/src/drizzle/pg-passwords.ts +22 -10
- package/src/drizzle/pg-proofs.ts +17 -6
- package/src/drizzle/pg-sessions.ts +41 -18
- package/src/drizzle/phone-target.ts +23 -18
- package/src/drizzle/proof-target.ts +10 -13
- package/src/drizzle/session-target.ts +33 -51
- package/src/drizzle/sqlite-emails.ts +31 -14
- package/src/drizzle/sqlite-identity.ts +22 -42
- package/src/drizzle/sqlite-password-prepared.ts +24 -10
- package/src/drizzle/sqlite-passwords.ts +30 -16
- package/src/drizzle/sqlite-proofs.ts +29 -6
- package/src/drizzle/sqlite-sessions.ts +50 -24
- package/src/drizzle/standalone-guard.ts +19 -7
- package/src/drizzle/totp-target.ts +62 -61
- package/src/drizzle/transaction-mysql.ts +1 -1
- package/src/index.ts +0 -24
- package/src/internal/drizzle-postgres.ts +1 -1
- package/src/internal/drizzle-sqlite.ts +1 -1
- package/dist/drizzle/d1-identity.d.mts +0 -30
- package/dist/drizzle/mysql-identity.d.mts +0 -21
- package/dist/drizzle/mysql.d.mts +0 -69
- package/dist/drizzle/mysql.mjs +0 -218
- package/dist/drizzle/mysql.mjs.map +0 -1
- package/dist/drizzle/pg.d.mts +0 -80
- package/dist/drizzle/pg.mjs +0 -289
- package/dist/drizzle/pg.mjs.map +0 -1
- package/dist/drizzle/sqlite.d.mts +0 -77
- package/dist/drizzle/sqlite.mjs +0 -217
- package/dist/drizzle/sqlite.mjs.map +0 -1
- package/src/drizzle/mysql.ts +0 -687
- package/src/drizzle/pg.ts +0 -984
- package/src/drizzle/sqlite.ts +0 -705
|
@@ -540,10 +540,14 @@ const prepareConflict = Effect.fn("Drizzle.prepareConflict")(function* <Registra
|
|
|
540
540
|
|
|
541
541
|
export const makeSqlEmailRegistrationAuthority = Effect.fn("makeSqlEmailRegistrationAuthority")(
|
|
542
542
|
function* <Registration>(
|
|
543
|
-
database: EmailSqlDatabase,
|
|
544
543
|
mapping: Mapping<Registration>,
|
|
545
544
|
configuration: EmailRegistrationConfiguration,
|
|
546
|
-
): Effect.fn.Return<
|
|
545
|
+
): Effect.fn.Return<
|
|
546
|
+
EmailRegistrationAuthority<Registration>,
|
|
547
|
+
never,
|
|
548
|
+
LifecycleHooks | CurrentEmailSql
|
|
549
|
+
> {
|
|
550
|
+
const database = yield* CurrentEmailSql;
|
|
547
551
|
const hooks = yield* LifecycleHooks;
|
|
548
552
|
|
|
549
553
|
return {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "@yielded/auth/Hooks";
|
|
8
8
|
/* oxlint-disable no-explicit-any -- public driver wrappers restore concrete Drizzle generics. */
|
|
9
9
|
import { type Context, Effect, Layer } from "effect";
|
|
10
|
-
import type * as SqlError from "effect/
|
|
10
|
+
import type * as SqlError from "effect/sql/SqlError";
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
makeSqlEmailRegistrationAuthority,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type EmailRegistrationConfiguration,
|
|
16
16
|
} from "./email-registration";
|
|
17
17
|
import {
|
|
18
|
+
CurrentEmailSql,
|
|
18
19
|
makeSqlEmailAddressPersistence,
|
|
19
20
|
makeSqlEmailSignInTargets,
|
|
20
21
|
type EmailSqlConfiguration,
|
|
@@ -22,7 +23,7 @@ import {
|
|
|
22
23
|
type EmailSqlQuery,
|
|
23
24
|
} from "./email-sql";
|
|
24
25
|
import type { ProofTargetConfiguration } from "./proof-target";
|
|
25
|
-
import { sqlClientStandaloneGuard } from "./standalone-guard";
|
|
26
|
+
import { sqlClientStandaloneGuard, type TransactionService } from "./standalone-guard";
|
|
26
27
|
|
|
27
28
|
export interface EmailTargetConfiguration {
|
|
28
29
|
readonly mode: "interactive" | "synchronous";
|
|
@@ -46,9 +47,9 @@ export type EmailCoordinatorError<E> =
|
|
|
46
47
|
| SqlError.SqlError;
|
|
47
48
|
|
|
48
49
|
export const sqlClientEmailStandaloneGuard = (
|
|
49
|
-
|
|
50
|
+
service: TransactionService | undefined,
|
|
50
51
|
): Effect.Effect<void, EmailUnavailable> =>
|
|
51
|
-
sqlClientStandaloneGuard(
|
|
52
|
+
sqlClientStandaloneGuard(service, () => EmailUnavailable.make({}));
|
|
52
53
|
|
|
53
54
|
const proofConfiguration = (configuration: EmailTargetConfiguration, coordinated = false) => ({
|
|
54
55
|
mode: configuration.proof.mode,
|
|
@@ -93,13 +94,12 @@ const registrationOptions = (
|
|
|
93
94
|
});
|
|
94
95
|
|
|
95
96
|
export const makeTargetEmailSignInServices = (
|
|
96
|
-
database: any,
|
|
97
97
|
mapping: any,
|
|
98
98
|
configuration: EmailTargetConfiguration,
|
|
99
99
|
) =>
|
|
100
100
|
Effect.gen(function* () {
|
|
101
101
|
return {
|
|
102
|
-
emailSignInTargets: yield* makeSqlEmailSignInTargets(
|
|
102
|
+
emailSignInTargets: yield* makeSqlEmailSignInTargets(mapping, {
|
|
103
103
|
mode: configuration.mode,
|
|
104
104
|
locking: false,
|
|
105
105
|
standaloneGuard: configuration.standaloneGuard,
|
|
@@ -108,7 +108,6 @@ export const makeTargetEmailSignInServices = (
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
export const makeTargetEmailAddressServices = (
|
|
111
|
-
database: any,
|
|
112
111
|
mapping: any,
|
|
113
112
|
proofMapping: any,
|
|
114
113
|
configuration: EmailTargetConfiguration,
|
|
@@ -116,7 +115,6 @@ export const makeTargetEmailAddressServices = (
|
|
|
116
115
|
Effect.gen(function* () {
|
|
117
116
|
return {
|
|
118
117
|
emailAddressPersistence: yield* makeSqlEmailAddressPersistence(
|
|
119
|
-
database,
|
|
120
118
|
mapping,
|
|
121
119
|
addressOptions(configuration, proofMapping),
|
|
122
120
|
),
|
|
@@ -124,7 +122,6 @@ export const makeTargetEmailAddressServices = (
|
|
|
124
122
|
});
|
|
125
123
|
|
|
126
124
|
export const makeTargetEmailRegistrationServices = <Registration>(
|
|
127
|
-
database: any,
|
|
128
125
|
mapping: any,
|
|
129
126
|
proofMapping: any,
|
|
130
127
|
configuration: EmailTargetConfiguration,
|
|
@@ -132,7 +129,6 @@ export const makeTargetEmailRegistrationServices = <Registration>(
|
|
|
132
129
|
Effect.gen(function* () {
|
|
133
130
|
return {
|
|
134
131
|
registrationAuthority: yield* makeSqlEmailRegistrationAuthority<Registration>(
|
|
135
|
-
database,
|
|
136
132
|
mapping,
|
|
137
133
|
registrationOptions(configuration, proofMapping),
|
|
138
134
|
),
|
|
@@ -161,9 +157,10 @@ export const coordinateTargetEmailAddress = <Transaction, A, E, R>(
|
|
|
161
157
|
Effect.gen(function* () {
|
|
162
158
|
return yield* owner(transaction, {
|
|
163
159
|
emailAddressPersistence: yield* makeSqlEmailAddressPersistence(
|
|
164
|
-
transaction as unknown as EmailSqlDatabase,
|
|
165
160
|
mapping,
|
|
166
161
|
addressOptions(configuration, proofMapping, true),
|
|
162
|
+
).pipe(
|
|
163
|
+
Effect.provideService(CurrentEmailSql, transaction as unknown as EmailSqlDatabase),
|
|
167
164
|
),
|
|
168
165
|
});
|
|
169
166
|
}),
|
|
@@ -196,9 +193,10 @@ export const coordinateTargetEmailRegistration = <Registration, Transaction, A,
|
|
|
196
193
|
Effect.gen(function* () {
|
|
197
194
|
return yield* owner(transaction, {
|
|
198
195
|
registrationAuthority: yield* makeSqlEmailRegistrationAuthority<Registration>(
|
|
199
|
-
transaction as unknown as EmailSqlDatabase,
|
|
200
196
|
mapping,
|
|
201
197
|
registrationOptions(configuration, proofMapping, true),
|
|
198
|
+
).pipe(
|
|
199
|
+
Effect.provideService(CurrentEmailSql, transaction as unknown as EmailSqlDatabase),
|
|
202
200
|
),
|
|
203
201
|
});
|
|
204
202
|
}),
|
|
@@ -209,19 +207,19 @@ export const coordinateTargetEmailRegistration = <Registration, Transaction, A,
|
|
|
209
207
|
return result.value;
|
|
210
208
|
});
|
|
211
209
|
|
|
212
|
-
export const emailSignInTargetsLayer = (
|
|
213
|
-
services: Effect.Effect<{ readonly emailSignInTargets: EmailSignInTargets["Service"] }>,
|
|
210
|
+
export const emailSignInTargetsLayer = <E, R>(
|
|
211
|
+
services: Effect.Effect<{ readonly emailSignInTargets: EmailSignInTargets["Service"] }, E, R>,
|
|
214
212
|
) =>
|
|
215
213
|
Layer.effect(
|
|
216
214
|
EmailSignInTargets,
|
|
217
215
|
Effect.map(services, (value) => value.emailSignInTargets),
|
|
218
216
|
);
|
|
219
217
|
|
|
220
|
-
export const emailAddressPersistenceLayer = (
|
|
218
|
+
export const emailAddressPersistenceLayer = <E, R>(
|
|
221
219
|
services: Effect.Effect<
|
|
222
220
|
{ readonly emailAddressPersistence: EmailAddressPersistence["Service"] },
|
|
223
|
-
|
|
224
|
-
|
|
221
|
+
E,
|
|
222
|
+
R
|
|
225
223
|
>,
|
|
226
224
|
) =>
|
|
227
225
|
Layer.effect(
|
|
@@ -229,12 +227,12 @@ export const emailAddressPersistenceLayer = (
|
|
|
229
227
|
Effect.map(services, (value) => value.emailAddressPersistence),
|
|
230
228
|
);
|
|
231
229
|
|
|
232
|
-
export const emailRegistrationLayer = <Id, Registration>(
|
|
230
|
+
export const emailRegistrationLayer = <Id, Registration, E, R>(
|
|
233
231
|
tag: Context.Key<Id, EmailRegistrationAuthority<Registration>>,
|
|
234
232
|
services: Effect.Effect<
|
|
235
233
|
{ readonly registrationAuthority: EmailRegistrationAuthority<Registration> },
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
E,
|
|
235
|
+
R
|
|
238
236
|
>,
|
|
239
237
|
) =>
|
|
240
238
|
Layer.effect(
|
package/src/drizzle/model.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { requireStandalone } from "@yielded/auth-persistence/Adapter";
|
|
2
|
-
import { AuthStore } from "@yielded/auth/AuthStore";
|
|
3
|
-
import { AuthStoreError } from "@yielded/auth/Errors";
|
|
4
1
|
import {
|
|
5
2
|
ExternalIdentityMutation,
|
|
6
3
|
SubjectProvisioner,
|
|
@@ -8,48 +5,11 @@ import {
|
|
|
8
5
|
type ExternalIdentity,
|
|
9
6
|
type LoginIdentifier,
|
|
10
7
|
} from "@yielded/auth/Identity";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
type ConsumeChallenge,
|
|
14
|
-
type NewChallenge,
|
|
15
|
-
type NewRegistration,
|
|
16
|
-
type PendingRegistration,
|
|
17
|
-
} from "@yielded/auth/Schema";
|
|
18
|
-
import {
|
|
19
|
-
getTableColumns,
|
|
20
|
-
type AnyColumn,
|
|
21
|
-
type InferInsertModel,
|
|
22
|
-
type InferSelectModel,
|
|
23
|
-
type Table,
|
|
24
|
-
} from "drizzle-orm";
|
|
8
|
+
import { getTableColumns, type AnyColumn, type InferInsertModel, type Table } from "drizzle-orm";
|
|
25
9
|
import { Context, DateTime, Effect, Layer } from "effect";
|
|
26
|
-
import type * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
27
10
|
|
|
28
11
|
export type CommitMode = "interactive" | "synchronous" | "batch";
|
|
29
12
|
|
|
30
|
-
/**
|
|
31
|
-
* Ordinary error-channel consumes must own their commit. Coordinated callers
|
|
32
|
-
* use the decision methods inside their outer transaction and translate only
|
|
33
|
-
* after that owner commits.
|
|
34
|
-
*/
|
|
35
|
-
export interface SqlClientTransactionDatabase {
|
|
36
|
-
readonly $client: Pick<SqlClient.SqlClient, "transactionService">;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export const requireStandaloneConsume = (
|
|
40
|
-
database: SqlClientTransactionDatabase,
|
|
41
|
-
): Effect.Effect<void, AuthStoreError> =>
|
|
42
|
-
requireStandalone(
|
|
43
|
-
() =>
|
|
44
|
-
AuthStoreError.make({
|
|
45
|
-
message: "Use the decision consume API inside an outer database transaction",
|
|
46
|
-
}),
|
|
47
|
-
database.$client,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
export type { ChallengeConsumeDecision } from "@yielded/auth/Persistence";
|
|
51
|
-
export type { ConsumeDecision } from "@yielded/auth/AuthStore";
|
|
52
|
-
|
|
53
13
|
export {
|
|
54
14
|
PersistenceMappingError,
|
|
55
15
|
isMappedConstraintConflict,
|
|
@@ -62,156 +22,8 @@ export interface InstantCodec<NativeInstant> {
|
|
|
62
22
|
readonly decode: (native: NativeInstant) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;
|
|
63
23
|
}
|
|
64
24
|
|
|
65
|
-
export interface RequiredAuthStoreConstraints {
|
|
66
|
-
readonly series: "unique(namespace,value,purpose)";
|
|
67
|
-
readonly challengeDigest: "unique(tokenDigest)";
|
|
68
|
-
readonly registrationDigest: "unique(tokenDigest)";
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface RequiredOAuthStateConstraints {
|
|
72
|
-
readonly oauthStateDigest: "unique(stateDigest)";
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export interface RequiredAuthConstraints
|
|
76
|
-
extends RequiredAuthStoreConstraints, RequiredOAuthStateConstraints {}
|
|
77
|
-
|
|
78
|
-
export const requiredAuthConstraints: RequiredAuthConstraints = {
|
|
79
|
-
series: "unique(namespace,value,purpose)",
|
|
80
|
-
challengeDigest: "unique(tokenDigest)",
|
|
81
|
-
registrationDigest: "unique(tokenDigest)",
|
|
82
|
-
oauthStateDigest: "unique(stateDigest)",
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export const requiredAuthStoreConstraints: RequiredAuthStoreConstraints = {
|
|
86
|
-
series: "unique(namespace,value,purpose)",
|
|
87
|
-
challengeDigest: "unique(tokenDigest)",
|
|
88
|
-
registrationDigest: "unique(tokenDigest)",
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export const requiredOAuthStateConstraints: RequiredOAuthStateConstraints = {
|
|
92
|
-
oauthStateDigest: "unique(stateDigest)",
|
|
93
|
-
};
|
|
94
|
-
|
|
95
25
|
type ColumnKey<T extends Table> = Extract<keyof T["_"]["columns"], string>;
|
|
96
26
|
|
|
97
|
-
export interface ChallengeRecord {
|
|
98
|
-
readonly challenge: NewChallenge;
|
|
99
|
-
readonly namespace: string;
|
|
100
|
-
readonly failedAttempts: number;
|
|
101
|
-
readonly consumed: boolean;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface ChallengeColumns<T extends Table> {
|
|
105
|
-
readonly challengeId: ColumnKey<T>;
|
|
106
|
-
readonly tokenDigest: ColumnKey<T>;
|
|
107
|
-
readonly namespace: ColumnKey<T>;
|
|
108
|
-
readonly value: ColumnKey<T>;
|
|
109
|
-
readonly purpose: ColumnKey<T>;
|
|
110
|
-
readonly otpKeyId: ColumnKey<T>;
|
|
111
|
-
readonly otpDigest: ColumnKey<T>;
|
|
112
|
-
readonly issuedAt: ColumnKey<T>;
|
|
113
|
-
readonly expiresAt: ColumnKey<T>;
|
|
114
|
-
readonly attemptLimit: ColumnKey<T>;
|
|
115
|
-
readonly failedAttempts: ColumnKey<T>;
|
|
116
|
-
readonly consumed: ColumnKey<T>;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Inputs are immutable server-created issuances. Replacements must advance
|
|
121
|
-
* issuedAt; equal or older issuances fail even after consumption or expiry.
|
|
122
|
-
* Instant encoding must preserve this ordering. Retain the series row as an
|
|
123
|
-
* issuance watermark until every previously accepted issuance has expired;
|
|
124
|
-
* current-row expiry alone is insufficient if historical lifetimes were longer.
|
|
125
|
-
*/
|
|
126
|
-
export interface ChallengeTableMapping<T extends Table> {
|
|
127
|
-
readonly table: T;
|
|
128
|
-
readonly columns: ChallengeColumns<T>;
|
|
129
|
-
readonly identifierNamespace: string;
|
|
130
|
-
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
131
|
-
readonly encodeInsert: (
|
|
132
|
-
input: NewChallenge,
|
|
133
|
-
state: {
|
|
134
|
-
readonly namespace: string;
|
|
135
|
-
readonly failedAttempts: number;
|
|
136
|
-
readonly consumed: false;
|
|
137
|
-
},
|
|
138
|
-
) => InferInsertModel<T>;
|
|
139
|
-
readonly encodeUpdate: (
|
|
140
|
-
input: NewChallenge,
|
|
141
|
-
state: {
|
|
142
|
-
readonly namespace: string;
|
|
143
|
-
readonly failedAttempts: unknown;
|
|
144
|
-
readonly consumed: false;
|
|
145
|
-
},
|
|
146
|
-
) => Readonly<Record<string, unknown>>;
|
|
147
|
-
readonly decode: (
|
|
148
|
-
row: InferSelectModel<T>,
|
|
149
|
-
) => Effect.Effect<ChallengeRecord, PersistenceMappingError>;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export interface RegistrationRecord {
|
|
153
|
-
readonly registration: PendingRegistration;
|
|
154
|
-
readonly consumed: boolean;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export interface RegistrationColumns<T extends Table> {
|
|
158
|
-
readonly registrationId: ColumnKey<T>;
|
|
159
|
-
readonly tokenDigest: ColumnKey<T>;
|
|
160
|
-
readonly expiresAt: ColumnKey<T>;
|
|
161
|
-
readonly consumed: ColumnKey<T>;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export interface RegistrationTableMapping<T extends Table> {
|
|
165
|
-
readonly table: T;
|
|
166
|
-
readonly columns: RegistrationColumns<T>;
|
|
167
|
-
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
168
|
-
readonly encodeInsert: (input: NewRegistration, consumed: false) => InferInsertModel<T>;
|
|
169
|
-
readonly decode: (
|
|
170
|
-
row: InferSelectModel<T>,
|
|
171
|
-
) => Effect.Effect<RegistrationRecord, PersistenceMappingError>;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export interface OAuthStateColumns<T extends Table> {
|
|
175
|
-
readonly stateDigest: ColumnKey<T>;
|
|
176
|
-
readonly expiresAt: ColumnKey<T>;
|
|
177
|
-
readonly consumed: ColumnKey<T>;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export interface OAuthStateTableMapping<T extends Table> {
|
|
181
|
-
readonly table: T;
|
|
182
|
-
readonly columns: OAuthStateColumns<T>;
|
|
183
|
-
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
184
|
-
readonly encodeInsert: (state: OAuthState, consumed: false) => InferInsertModel<T>;
|
|
185
|
-
readonly decode: (
|
|
186
|
-
row: InferSelectModel<T>,
|
|
187
|
-
) => Effect.Effect<
|
|
188
|
-
{ readonly state: OAuthState; readonly consumed: boolean },
|
|
189
|
-
PersistenceMappingError
|
|
190
|
-
>;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export interface AuthStoreTables<Challenge extends Table, Registration extends Table> {
|
|
194
|
-
readonly constraints: RequiredAuthStoreConstraints;
|
|
195
|
-
readonly challenge: ChallengeTableMapping<Challenge>;
|
|
196
|
-
readonly registration: RegistrationTableMapping<Registration>;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export interface OAuthStateTables<State extends Table> {
|
|
200
|
-
readonly constraints: RequiredOAuthStateConstraints;
|
|
201
|
-
readonly oauthState: OAuthStateTableMapping<State>;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
export interface AuthTables<
|
|
205
|
-
Challenge extends Table,
|
|
206
|
-
Registration extends Table,
|
|
207
|
-
State extends Table,
|
|
208
|
-
> {
|
|
209
|
-
readonly constraints: RequiredAuthConstraints;
|
|
210
|
-
readonly challenge: ChallengeTableMapping<Challenge>;
|
|
211
|
-
readonly registration: RegistrationTableMapping<Registration>;
|
|
212
|
-
readonly oauthState: OAuthStateTableMapping<State>;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
27
|
export interface RequiredIdentityConstraints {
|
|
216
28
|
readonly identifier: "unique(namespace,value)";
|
|
217
29
|
readonly externalIdentity: "unique(provider,issuer,subject)";
|
|
@@ -420,25 +232,6 @@ export const updateValues = <T extends Table>(
|
|
|
420
232
|
entries: ReadonlyArray<readonly [ColumnKey<T>, unknown]>,
|
|
421
233
|
): Partial<InferInsertModel<T>> => Object.fromEntries(entries) as Partial<InferInsertModel<T>>;
|
|
422
234
|
|
|
423
|
-
export type ChallengeInput = ConsumeChallenge;
|
|
424
|
-
|
|
425
|
-
/** Acquire an application database in Effect and expose the auth stores as one layer. */
|
|
426
|
-
export const authServicesLayer = <E, R>(
|
|
427
|
-
acquire: Effect.Effect<
|
|
428
|
-
{
|
|
429
|
-
readonly authStore: AuthStore["Service"];
|
|
430
|
-
readonly oauthStateStore: OAuthStateStore["Service"];
|
|
431
|
-
},
|
|
432
|
-
E,
|
|
433
|
-
R
|
|
434
|
-
>,
|
|
435
|
-
) =>
|
|
436
|
-
Layer.effectContext(
|
|
437
|
-
Effect.map(acquire, ({ authStore, oauthStateStore }) =>
|
|
438
|
-
Context.make(AuthStore, authStore).pipe(Context.add(OAuthStateStore, oauthStateStore)),
|
|
439
|
-
),
|
|
440
|
-
);
|
|
441
|
-
|
|
442
235
|
/** Acquire an application database in Effect and expose the identity services as one layer. */
|
|
443
236
|
export const identityServicesLayer = <E, R>(
|
|
444
237
|
acquire: Effect.Effect<
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnyRelations } from "drizzle-orm";
|
|
2
|
+
import type { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
3
|
+
import { Context } from "effect";
|
|
4
|
+
|
|
5
|
+
/** Application-owned MySQL database used to construct persistence services. */
|
|
6
|
+
export class Database extends Context.Service<Database, EffectMysql2Database<AnyRelations>>()(
|
|
7
|
+
"effect-auth/persistence-drizzle/Mysql2/Database",
|
|
8
|
+
) {}
|
|
@@ -5,7 +5,7 @@ import type { AnyRelations } from "drizzle-orm";
|
|
|
5
5
|
import type { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
6
6
|
import type { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
7
7
|
import { Effect, Context } from "effect";
|
|
8
|
-
import type { SqlError } from "effect/
|
|
8
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
9
9
|
|
|
10
10
|
import type {
|
|
11
11
|
EmailAddressMapping,
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
EmailSignInMapping,
|
|
14
14
|
} from "./email-model";
|
|
15
15
|
import type { EmailRegistrationAuthority } from "./email-registration";
|
|
16
|
+
import { CurrentEmailSql } from "./email-sql";
|
|
16
17
|
import type { EmailSqlQuery } from "./email-sql";
|
|
17
18
|
import {
|
|
18
19
|
coordinateTargetEmailAddress,
|
|
@@ -22,9 +23,16 @@ import {
|
|
|
22
23
|
makeTargetEmailSignInServices,
|
|
23
24
|
sqlClientEmailStandaloneGuard,
|
|
24
25
|
} from "./email-target";
|
|
26
|
+
import { Database as DatabaseService } from "./mysql-database";
|
|
27
|
+
import { nativeDatabase } from "./native-database";
|
|
25
28
|
import type { ProofPersistenceMapping } from "./proof-model";
|
|
26
29
|
import type { ProofSqlQuery } from "./proof-sql";
|
|
27
30
|
import { sqlClientProofStandaloneGuard } from "./proof-target";
|
|
31
|
+
import {
|
|
32
|
+
type TransactionService,
|
|
33
|
+
acquireTransactionService,
|
|
34
|
+
transactionService,
|
|
35
|
+
} from "./standalone-guard";
|
|
28
36
|
import type { SuppliedService } from "./SuppliedService";
|
|
29
37
|
|
|
30
38
|
type Database = EffectMysql2Database<AnyRelations>;
|
|
@@ -44,15 +52,15 @@ type ProofMapping = ProofPersistenceMapping<
|
|
|
44
52
|
any
|
|
45
53
|
>;
|
|
46
54
|
|
|
47
|
-
const configuration = (
|
|
55
|
+
const configuration = (service: TransactionService | undefined) => ({
|
|
48
56
|
mode: "interactive" as const,
|
|
49
57
|
locking: true,
|
|
50
|
-
standaloneGuard: sqlClientEmailStandaloneGuard(
|
|
58
|
+
standaloneGuard: sqlClientEmailStandaloneGuard(service),
|
|
51
59
|
generatedSubjectRows: (query: EmailSqlQuery) => query.$returningId(),
|
|
52
60
|
proof: {
|
|
53
61
|
mode: "interactive" as const,
|
|
54
62
|
locking: true,
|
|
55
|
-
standaloneGuard: sqlClientProofStandaloneGuard(
|
|
63
|
+
standaloneGuard: sqlClientProofStandaloneGuard(service),
|
|
56
64
|
insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>
|
|
57
65
|
query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),
|
|
58
66
|
},
|
|
@@ -64,9 +72,12 @@ export const makeMysqlEmailSignInServices = <
|
|
|
64
72
|
C extends AnyMySqlTable,
|
|
65
73
|
NativeId,
|
|
66
74
|
>(
|
|
67
|
-
database: Database,
|
|
68
75
|
mapping: EmailSignInMapping<S, I, C, NativeId>,
|
|
69
|
-
) =>
|
|
76
|
+
) =>
|
|
77
|
+
Effect.flatMap(
|
|
78
|
+
Effect.map(acquireTransactionService(DatabaseService), configuration),
|
|
79
|
+
(configuration) => makeTargetEmailSignInServices(mapping, configuration),
|
|
80
|
+
).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
|
|
70
81
|
|
|
71
82
|
export const makeMysqlEmailAddressServices = <
|
|
72
83
|
S extends AnyMySqlTable,
|
|
@@ -76,10 +87,13 @@ export const makeMysqlEmailAddressServices = <
|
|
|
76
87
|
M extends AnyMySqlTable,
|
|
77
88
|
NativeId,
|
|
78
89
|
>(
|
|
79
|
-
database: Database,
|
|
80
90
|
mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>,
|
|
81
91
|
proofMapping: ProofMapping,
|
|
82
|
-
) =>
|
|
92
|
+
) =>
|
|
93
|
+
Effect.flatMap(
|
|
94
|
+
Effect.map(acquireTransactionService(DatabaseService), configuration),
|
|
95
|
+
(configuration) => makeTargetEmailAddressServices(mapping, proofMapping, configuration),
|
|
96
|
+
).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
|
|
83
97
|
|
|
84
98
|
export function coordinateMysqlEmailAddress<
|
|
85
99
|
D extends Database,
|
|
@@ -170,7 +184,7 @@ export function coordinateMysqlEmailAddress<
|
|
|
170
184
|
database,
|
|
171
185
|
options.mapping,
|
|
172
186
|
options.proofMapping,
|
|
173
|
-
configuration(database),
|
|
187
|
+
configuration(transactionService(database)),
|
|
174
188
|
(
|
|
175
189
|
transaction: TransactionOf<D>,
|
|
176
190
|
services: { readonly emailAddressPersistence: EmailAddressPersistence["Service"] },
|
|
@@ -195,16 +209,14 @@ export const makeMysqlEmailRegistrationServices = <
|
|
|
195
209
|
Rq extends AnyMySqlTable,
|
|
196
210
|
NativeId,
|
|
197
211
|
>(
|
|
198
|
-
database: Database,
|
|
199
212
|
mapping: EmailRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,
|
|
200
213
|
proofMapping: ProofMapping,
|
|
201
214
|
) =>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
);
|
|
215
|
+
Effect.flatMap(
|
|
216
|
+
Effect.map(acquireTransactionService(DatabaseService), configuration),
|
|
217
|
+
(configuration) =>
|
|
218
|
+
makeTargetEmailRegistrationServices<Registration>(mapping, proofMapping, configuration),
|
|
219
|
+
).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
|
|
208
220
|
|
|
209
221
|
export function coordinateMysqlEmailRegistration<
|
|
210
222
|
TargetId,
|
|
@@ -304,7 +316,7 @@ export function coordinateMysqlEmailRegistration<
|
|
|
304
316
|
database,
|
|
305
317
|
options.mapping,
|
|
306
318
|
options.proofMapping,
|
|
307
|
-
configuration(database),
|
|
319
|
+
configuration(transactionService(database)),
|
|
308
320
|
(
|
|
309
321
|
transaction: TransactionOf<D>,
|
|
310
322
|
services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { reportPersistenceFailure } from "@yielded/auth/Persistence";
|
|
11
11
|
import type { SubjectId } from "@yielded/auth/Schema";
|
|
12
12
|
/* oxlint-disable no-explicit-any -- Drizzle generic query types are narrowed at this technology boundary. */
|
|
13
|
-
import { and, eq
|
|
13
|
+
import { and, eq } from "drizzle-orm";
|
|
14
14
|
import type { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
15
15
|
import type { AnyMySqlTable, MySqlColumn } from "drizzle-orm/mysql-core";
|
|
16
16
|
import { Cause, Effect, Schema } from "effect";
|
|
@@ -24,8 +24,8 @@ import {
|
|
|
24
24
|
type IdentityTables,
|
|
25
25
|
type SubjectProvisioningTables,
|
|
26
26
|
} from "./model";
|
|
27
|
+
import { Database as DatabaseService } from "./mysql-database";
|
|
27
28
|
|
|
28
|
-
type Database = EffectMysql2Database<AnyRelations>;
|
|
29
29
|
type RuntimeDatabase = EffectMysql2Database<any>;
|
|
30
30
|
const unavailable = () => IdentityUnavailable.make();
|
|
31
31
|
const isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));
|
|
@@ -39,15 +39,14 @@ const mapUnavailable = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
|
|
|
39
39
|
),
|
|
40
40
|
);
|
|
41
41
|
|
|
42
|
-
export const makeMysqlSubjectProvisioningServices = <
|
|
42
|
+
export const makeMysqlSubjectProvisioningServices = Effect.fnUntraced(function* <
|
|
43
43
|
Subject extends AnyMySqlTable,
|
|
44
44
|
Identifier extends AnyMySqlTable,
|
|
45
45
|
Request extends AnyMySqlTable,
|
|
46
46
|
NativeId,
|
|
47
|
-
>(
|
|
48
|
-
database
|
|
49
|
-
|
|
50
|
-
) => {
|
|
47
|
+
>(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {
|
|
48
|
+
const database = yield* DatabaseService;
|
|
49
|
+
|
|
51
50
|
const db = database as RuntimeDatabase;
|
|
52
51
|
const requestTable = mapping.provisioningRequest.table;
|
|
53
52
|
|
|
@@ -190,16 +189,15 @@ export const makeMysqlSubjectProvisioningServices = <
|
|
|
190
189
|
}, mapUnavailable);
|
|
191
190
|
|
|
192
191
|
return { subjectProvisioner: SubjectProvisioner.of({ provision }) } as const;
|
|
193
|
-
};
|
|
192
|
+
});
|
|
194
193
|
|
|
195
|
-
export const makeMysqlExternalIdentityServices = <
|
|
194
|
+
export const makeMysqlExternalIdentityServices = Effect.fnUntraced(function* <
|
|
196
195
|
Subject extends AnyMySqlTable,
|
|
197
196
|
External extends AnyMySqlTable,
|
|
198
197
|
NativeId,
|
|
199
|
-
>(
|
|
200
|
-
database
|
|
201
|
-
|
|
202
|
-
) => {
|
|
198
|
+
>(mapping: ExternalIdentityTables<Subject, External, NativeId>) {
|
|
199
|
+
const database = yield* DatabaseService;
|
|
200
|
+
|
|
203
201
|
const db = database as RuntimeDatabase;
|
|
204
202
|
const externalTable = mapping.externalIdentity.table;
|
|
205
203
|
|
|
@@ -307,18 +305,17 @@ export const makeMysqlExternalIdentityServices = <
|
|
|
307
305
|
}, mapUnavailable);
|
|
308
306
|
|
|
309
307
|
return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) } as const;
|
|
310
|
-
};
|
|
308
|
+
});
|
|
311
309
|
|
|
312
|
-
export const makeMysqlIdentityServices = <
|
|
310
|
+
export const makeMysqlIdentityServices = Effect.fnUntraced(function* <
|
|
313
311
|
Subject extends AnyMySqlTable,
|
|
314
312
|
Identifier extends AnyMySqlTable,
|
|
315
313
|
External extends AnyMySqlTable,
|
|
316
314
|
Request extends AnyMySqlTable,
|
|
317
315
|
NativeId,
|
|
318
|
-
>(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
...makeMysqlExternalIdentityServices(database, mapping),
|
|
316
|
+
>(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {
|
|
317
|
+
return {
|
|
318
|
+
...(yield* makeMysqlSubjectProvisioningServices(mapping)),
|
|
319
|
+
...(yield* makeMysqlExternalIdentityServices(mapping)),
|
|
320
|
+
};
|
|
324
321
|
});
|
|
@@ -4,9 +4,11 @@ import type { AnyRelations } from "drizzle-orm";
|
|
|
4
4
|
import type { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
5
5
|
import type { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
6
6
|
import { Effect, Context } from "effect";
|
|
7
|
-
import type { SqlError } from "effect/
|
|
7
|
+
import type { SqlError } from "effect/sql/SqlError";
|
|
8
8
|
|
|
9
|
+
import { Database as DatabaseService } from "./mysql-database";
|
|
9
10
|
import { mysqlPasswordConfiguration as configuration } from "./mysql-passwords";
|
|
11
|
+
import { nativeDatabase } from "./native-database";
|
|
10
12
|
import type {
|
|
11
13
|
PasswordPreparedPersistenceMapping,
|
|
12
14
|
PasswordPreparedProofMapping,
|
|
@@ -15,6 +17,8 @@ import {
|
|
|
15
17
|
makeTargetPasswordPreparedPersistenceServices,
|
|
16
18
|
coordinateTargetPasswordPreparedPersistence,
|
|
17
19
|
} from "./password-prepared-target";
|
|
20
|
+
import { CurrentPasswordSql } from "./password-sql";
|
|
21
|
+
import { acquireTransactionService, transactionService } from "./standalone-guard";
|
|
18
22
|
import type { SuppliedService } from "./SuppliedService";
|
|
19
23
|
type Database = EffectMysql2Database<AnyRelations>;
|
|
20
24
|
type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
|
|
@@ -39,16 +43,14 @@ export const makeMySqlPasswordPreparedPersistenceServices = <
|
|
|
39
43
|
PCr extends AnyMySqlTable = AnyMySqlTable,
|
|
40
44
|
PNativeId = unknown,
|
|
41
45
|
>(
|
|
42
|
-
database: Database,
|
|
43
46
|
mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>,
|
|
44
47
|
proofMapping?: PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>,
|
|
45
48
|
) =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
);
|
|
49
|
+
Effect.flatMap(
|
|
50
|
+
Effect.map(acquireTransactionService(DatabaseService), configuration),
|
|
51
|
+
(configuration) =>
|
|
52
|
+
makeTargetPasswordPreparedPersistenceServices(mapping, configuration, proofMapping),
|
|
53
|
+
).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
|
|
52
54
|
|
|
53
55
|
export function coordinateMySqlPasswordPreparedPersistence<
|
|
54
56
|
TargetId,
|
|
@@ -186,7 +188,7 @@ export function coordinateMySqlPasswordPreparedPersistence<
|
|
|
186
188
|
coordinateTargetPasswordPreparedPersistence<TransactionOf<D>, Out, E, Exclude<R, TargetId>>(
|
|
187
189
|
database,
|
|
188
190
|
options.mapping,
|
|
189
|
-
configuration(database),
|
|
191
|
+
configuration(transactionService(database)),
|
|
190
192
|
options.proofMapping,
|
|
191
193
|
(
|
|
192
194
|
transaction: TransactionOf<D>,
|