@yielded/auth-persistence-drizzle 0.1.0-beta.0 → 0.1.0-beta.1
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 +135 -25
- package/dist/D1.mjs +1 -3
- package/dist/D1.mjs.map +1 -1
- package/dist/Libsql.d.mts +192 -75
- package/dist/Libsql.mjs +1 -7
- package/dist/Libsql.mjs.map +1 -1
- package/dist/Mysql2.d.mts +177 -37
- package/dist/Mysql2.mjs +1 -3
- package/dist/Mysql2.mjs.map +1 -1
- package/dist/Pglite.d.mts +171 -30
- package/dist/Pglite.mjs +2 -3
- package/dist/Pglite.mjs.map +1 -1
- package/dist/Postgres.d.mts +177 -36
- package/dist/Postgres.mjs +2 -3
- package/dist/Postgres.mjs.map +1 -1
- package/dist/SqliteBun.d.mts +192 -74
- package/dist/SqliteBun.mjs +1 -5
- package/dist/SqliteBun.mjs.map +1 -1
- package/dist/SqliteDo.d.mts +194 -110
- package/dist/SqliteDo.mjs +2 -32
- package/dist/SqliteDo.mjs.map +1 -1
- package/dist/SqliteNode.d.mts +190 -72
- package/dist/SqliteNode.mjs +1 -5
- package/dist/SqliteNode.mjs.map +1 -1
- package/dist/SqliteWasm.d.mts +192 -74
- package/dist/SqliteWasm.mjs +1 -5
- 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-emails.mjs.map +1 -1
- package/dist/drizzle/d1-generated-statement.mjs.map +1 -1
- package/dist/drizzle/d1-identity.d.mts +1 -1
- package/dist/drizzle/d1-oauth.d.mts +35 -5
- package/dist/drizzle/d1-oauth.mjs +1 -1
- package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
- package/dist/drizzle/d1-passwords.d.mts +1 -1
- package/dist/drizzle/d1-passwords.mjs.map +1 -1
- package/dist/drizzle/d1-proofs.d.mts +1 -1
- package/dist/drizzle/d1-proofs.mjs.map +1 -1
- package/dist/drizzle/d1-sessions.d.mts +3 -3
- package/dist/drizzle/d1-sessions.mjs.map +1 -1
- package/dist/drizzle/email-registration.d.mts +1 -1
- package/dist/drizzle/email-target.d.mts +1 -1
- 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-emails.d.mts +1 -1
- package/dist/drizzle/mysql-emails.mjs.map +1 -1
- package/dist/drizzle/mysql-identity.d.mts +1 -1
- package/dist/drizzle/mysql-password-prepared.d.mts +1 -1
- package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
- package/dist/drizzle/mysql-passwords.d.mts +1 -1
- package/dist/drizzle/mysql-passwords.mjs.map +1 -1
- package/dist/drizzle/mysql-proofs.d.mts +1 -1
- package/dist/drizzle/mysql-proofs.mjs.map +1 -1
- package/dist/drizzle/mysql-sessions.d.mts +1 -1
- package/dist/drizzle/mysql-sessions.mjs.map +1 -1
- 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 +4 -1
- 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 +137 -9
- package/dist/drizzle/oauth-connected-target.mjs +6 -2
- package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
- package/dist/drizzle/oauth-drivers.mjs +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 +2 -2
- package/dist/drizzle/oauth-target.mjs +1 -1
- package/dist/drizzle/oauth-target.mjs.map +1 -1
- package/dist/drizzle/passkey-write-target.d.mts +1 -1
- package/dist/drizzle/password-prepared-state.mjs +1 -1
- package/dist/drizzle/password-prepared-target.d.mts +1 -1
- package/dist/drizzle/password-prepared-target.mjs.map +1 -1
- package/dist/drizzle/password-target.d.mts +1 -1
- package/dist/drizzle/password-target.mjs.map +1 -1
- package/dist/drizzle/pg-emails.d.mts +1 -1
- package/dist/drizzle/pg-emails.mjs.map +1 -1
- package/dist/drizzle/pg-identity.d.mts +22 -0
- package/dist/drizzle/pg-identity.mjs +89 -0
- package/dist/drizzle/pg-identity.mjs.map +1 -0
- package/dist/drizzle/pg-password-prepared.d.mts +1 -1
- package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
- package/dist/drizzle/pg-passwords.d.mts +1 -1
- package/dist/drizzle/pg-passwords.mjs.map +1 -1
- package/dist/drizzle/pg-proofs.d.mts +1 -1
- package/dist/drizzle/pg-proofs.mjs.map +1 -1
- package/dist/drizzle/pg-sessions.d.mts +1 -1
- 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 +1 -1
- package/dist/drizzle/phone-target.mjs.map +1 -1
- package/dist/drizzle/proof-target.d.mts +1 -1
- package/dist/drizzle/proof-target.mjs.map +1 -1
- package/dist/drizzle/session-target.d.mts +1 -1
- package/dist/drizzle/session-target.mjs.map +1 -1
- package/dist/drizzle/sqlite-emails.mjs.map +1 -1
- package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
- package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
- package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
- package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
- 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 +1 -1
- 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 +1 -17
- package/src/Libsql.ts +0 -44
- package/src/Mysql2.ts +1 -23
- package/src/Pglite.ts +2 -18
- package/src/Postgres.ts +2 -18
- package/src/SqliteBun.ts +1 -38
- package/src/SqliteDo.ts +1 -256
- package/src/SqliteNode.ts +1 -38
- package/src/SqliteWasm.ts +1 -38
- package/src/drizzle/D1BatchStatements.ts +1 -1
- package/src/drizzle/d1-emails.ts +2 -4
- package/src/drizzle/d1-generated-statement.ts +1 -1
- package/src/drizzle/d1-password-prepared.ts +2 -5
- package/src/drizzle/d1-passwords.ts +2 -4
- package/src/drizzle/d1-proofs.ts +2 -4
- package/src/drizzle/d1-sessions.ts +2 -2
- package/src/drizzle/email-target.ts +1 -1
- package/src/drizzle/model.ts +1 -208
- package/src/drizzle/mysql-emails.ts +1 -1
- package/src/drizzle/mysql-password-prepared.ts +1 -1
- package/src/drizzle/mysql-passwords.ts +1 -1
- package/src/drizzle/mysql-proofs.ts +1 -1
- package/src/drizzle/mysql-sessions.ts +1 -1
- package/src/drizzle/oauth-connected-access.ts +8 -1
- package/src/drizzle/oauth-connected-drivers.ts +3 -0
- 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 +10 -1
- package/src/drizzle/oauth-state.ts +5 -4
- package/src/drizzle/oauth-target.ts +1 -1
- package/src/drizzle/password-prepared-target.ts +1 -1
- package/src/drizzle/password-target.ts +1 -1
- package/src/drizzle/pg-emails.ts +1 -1
- package/src/drizzle/pg-identity.ts +301 -0
- package/src/drizzle/pg-password-prepared.ts +1 -1
- package/src/drizzle/pg-passwords.ts +1 -1
- package/src/drizzle/pg-proofs.ts +1 -1
- package/src/drizzle/pg-sessions.ts +1 -1
- package/src/drizzle/phone-target.ts +1 -1
- package/src/drizzle/proof-target.ts +1 -1
- package/src/drizzle/session-target.ts +1 -1
- package/src/drizzle/sqlite-emails.ts +1 -1
- package/src/drizzle/sqlite-password-prepared.ts +1 -1
- package/src/drizzle/sqlite-passwords.ts +1 -1
- package/src/drizzle/sqlite-proofs.ts +1 -1
- package/src/drizzle/sqlite-sessions.ts +1 -1
- package/src/drizzle/standalone-guard.ts +1 -1
- package/src/drizzle/totp-target.ts +1 -1
- 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/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
|
@@ -2,11 +2,11 @@ import "./email-model.mjs";
|
|
|
2
2
|
import "./email-sql.mjs";
|
|
3
3
|
import "./proof-sql.mjs";
|
|
4
4
|
import { LoginIdentifier } from "@yielded/auth/Identity";
|
|
5
|
-
import { TokenDigest } from "@yielded/auth/Schema";
|
|
6
5
|
import { Effect } from "effect";
|
|
7
6
|
import { LifecycleHooks, PreparedCommit } from "@yielded/auth/Hooks";
|
|
8
7
|
import { EmailCommandId, EmailRegistrationDecision, EmailUnavailable, PrepareEmailCommit } from "@yielded/auth/Email";
|
|
9
8
|
import { ProofCompletionPlan } from "@yielded/auth/Proofs";
|
|
9
|
+
import { TokenDigest } from "@yielded/auth/Schema";
|
|
10
10
|
//#region src/drizzle/email-registration.d.ts
|
|
11
11
|
export interface EmailRegistrationAuthority<Registration> {
|
|
12
12
|
readonly inspect: (input: {
|
|
@@ -4,7 +4,7 @@ import "./proof-target.mjs";
|
|
|
4
4
|
import { Context, Effect, Layer } from "effect";
|
|
5
5
|
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
6
6
|
import { EmailAddressPersistence, EmailSignInTargets, EmailUnavailable } from "@yielded/auth/Email";
|
|
7
|
-
import "effect/
|
|
7
|
+
import "effect/sql/SqlError";
|
|
8
8
|
//#region src/drizzle/email-target.d.ts
|
|
9
9
|
export declare const emailSignInTargetsLayer: (services: Effect.Effect<{
|
|
10
10
|
readonly emailSignInTargets: EmailSignInTargets["Service"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email-target.mjs","names":[],"sources":["../../src/drizzle/email-target.ts"],"sourcesContent":["import { EmailAddressPersistence, EmailSignInTargets, EmailUnavailable } from \"@yielded/auth/Email\";\nimport {\n coordinateCommit,\n hasCommitScope,\n LifecycleHooks,\n type HookConfigurationError,\n} from \"@yielded/auth/Hooks\";\n/* oxlint-disable no-explicit-any -- public driver wrappers restore concrete Drizzle generics. */\nimport { type Context, Effect, Layer } from \"effect\";\nimport type * as SqlError from \"effect/unstable/sql/SqlError\";\n\nimport {\n makeSqlEmailRegistrationAuthority,\n type EmailRegistrationAuthority,\n type EmailRegistrationConfiguration,\n} from \"./email-registration\";\nimport {\n makeSqlEmailAddressPersistence,\n makeSqlEmailSignInTargets,\n type EmailSqlConfiguration,\n type EmailSqlDatabase,\n type EmailSqlQuery,\n} from \"./email-sql\";\nimport type { ProofTargetConfiguration } from \"./proof-target\";\nimport { sqlClientStandaloneGuard } from \"./standalone-guard\";\n\nexport interface EmailTargetConfiguration {\n readonly mode: \"interactive\" | \"synchronous\";\n readonly locking: boolean;\n readonly standaloneGuard: Effect.Effect<void, EmailUnavailable>;\n readonly coordinatorGuard?: Effect.Effect<void, EmailUnavailable>;\n readonly generatedSubjectRows: (query: EmailSqlQuery) => EmailSqlQuery;\n readonly proof: ProofTargetConfiguration;\n}\n\ninterface TransactionOwner<Transaction> {\n readonly transaction: <A, E, R>(\n body: (transaction: Transaction) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SqlError.SqlError, R>;\n}\n\nexport type EmailCoordinatorError<E> =\n | E\n | EmailUnavailable\n | HookConfigurationError\n | SqlError.SqlError;\n\nexport const sqlClientEmailStandaloneGuard = (\n database: unknown,\n): Effect.Effect<void, EmailUnavailable> =>\n sqlClientStandaloneGuard(database, () => EmailUnavailable.make({}));\n\nconst proofConfiguration = (configuration: EmailTargetConfiguration, coordinated = false) => ({\n mode: configuration.proof.mode,\n locking: configuration.proof.locking,\n\n standaloneGuard: Effect.void,\n coordinated,\n insertIfAbsent: configuration.proof.insertIfAbsent,\n});\n\nconst addressOptions = (\n configuration: EmailTargetConfiguration,\n proofMapping: any,\n coordinated = false,\n): EmailSqlConfiguration => ({\n mode: configuration.mode,\n locking: configuration.locking,\n\n standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,\n coordinated,\n proof: {\n mapping: proofMapping,\n configuration: proofConfiguration(configuration, true),\n },\n});\n\nconst registrationOptions = (\n configuration: EmailTargetConfiguration,\n proofMapping: any,\n coordinated = false,\n): EmailRegistrationConfiguration => ({\n mode: configuration.mode,\n locking: configuration.locking,\n\n standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,\n generatedSubjectRows: configuration.generatedSubjectRows,\n coordinated,\n proof: {\n mapping: proofMapping,\n configuration: proofConfiguration(configuration, true),\n },\n});\n\nexport const makeTargetEmailSignInServices = (\n database: any,\n mapping: any,\n configuration: EmailTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n emailSignInTargets: yield* makeSqlEmailSignInTargets(database, mapping, {\n mode: configuration.mode,\n locking: false,\n standaloneGuard: configuration.standaloneGuard,\n }),\n };\n });\n\nexport const makeTargetEmailAddressServices = (\n database: any,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n emailAddressPersistence: yield* makeSqlEmailAddressPersistence(\n database,\n mapping,\n addressOptions(configuration, proofMapping),\n ),\n };\n });\n\nexport const makeTargetEmailRegistrationServices = <Registration>(\n database: any,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n registrationAuthority: yield* makeSqlEmailRegistrationAuthority<Registration>(\n database,\n mapping,\n registrationOptions(configuration, proofMapping),\n ),\n };\n });\n\nexport const coordinateTargetEmailAddress = <Transaction, A, E, R>(\n database: TransactionOwner<Transaction>,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n owner: (\n transaction: Transaction,\n services: { readonly emailAddressPersistence: EmailAddressPersistence[\"Service\"] },\n ) => Effect.Effect<A, E, R>,\n): Effect.Effect<A, EmailCoordinatorError<E>, R | LifecycleHooks> =>\n Effect.gen(function* (): Effect.fn.Return<A, EmailCoordinatorError<E>, R | LifecycleHooks> {\n const hooks = yield* LifecycleHooks;\n\n if (yield* hasCommitScope) return yield* EmailUnavailable.make({});\n yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;\n\n const result = yield* coordinateCommit(\n () =>\n database.transaction((transaction) =>\n Effect.gen(function* () {\n return yield* owner(transaction, {\n emailAddressPersistence: yield* makeSqlEmailAddressPersistence(\n transaction as unknown as EmailSqlDatabase,\n mapping,\n addressOptions(configuration, proofMapping, true),\n ),\n });\n }),\n ),\n { mode: configuration.mode },\n ).pipe(Effect.provideService(LifecycleHooks, hooks));\n\n return result.value;\n });\n\nexport const coordinateTargetEmailRegistration = <Registration, Transaction, A, E, R>(\n database: TransactionOwner<Transaction>,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n owner: (\n transaction: Transaction,\n services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },\n ) => Effect.Effect<A, E, R>,\n): Effect.Effect<A, EmailCoordinatorError<E>, R | LifecycleHooks> =>\n Effect.gen(function* (): Effect.fn.Return<A, EmailCoordinatorError<E>, R | LifecycleHooks> {\n const hooks = yield* LifecycleHooks;\n\n if (yield* hasCommitScope) return yield* EmailUnavailable.make({});\n yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;\n\n const result = yield* coordinateCommit(\n () =>\n database.transaction((transaction) =>\n Effect.gen(function* () {\n return yield* owner(transaction, {\n registrationAuthority: yield* makeSqlEmailRegistrationAuthority<Registration>(\n transaction as unknown as EmailSqlDatabase,\n mapping,\n registrationOptions(configuration, proofMapping, true),\n ),\n });\n }),\n ),\n { mode: configuration.mode },\n ).pipe(Effect.provideService(LifecycleHooks, hooks));\n\n return result.value;\n });\n\nexport const emailSignInTargetsLayer = (\n services: Effect.Effect<{ readonly emailSignInTargets: EmailSignInTargets[\"Service\"] }>,\n) =>\n Layer.effect(\n EmailSignInTargets,\n Effect.map(services, (value) => value.emailSignInTargets),\n );\n\nexport const emailAddressPersistenceLayer = (\n services: Effect.Effect<\n { readonly emailAddressPersistence: EmailAddressPersistence[\"Service\"] },\n never,\n LifecycleHooks\n >,\n) =>\n Layer.effect(\n EmailAddressPersistence,\n Effect.map(services, (value) => value.emailAddressPersistence),\n );\n\nexport const emailRegistrationLayer = <Id, Registration>(\n tag: Context.Key<Id, EmailRegistrationAuthority<Registration>>,\n services: Effect.Effect<\n { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },\n never,\n LifecycleHooks\n >,\n) =>\n Layer.effect(\n tag,\n Effect.map(services, (value) => value.registrationAuthority),\n );\n"],"mappings":";;;;;;;AA+CA,MAAa,iCACX,aAEA,yBAAyB,gBAAgB,iBAAiB,KAAK,CAAC,CAAC,CAAC;AAEpE,MAAM,sBAAsB,eAAyC,cAAc,WAAW;CAC5F,MAAM,cAAc,MAAM;CAC1B,SAAS,cAAc,MAAM;CAE7B,iBAAiB,OAAO;CACxB;CACA,gBAAgB,cAAc,MAAM;AACtC;AAEA,MAAM,kBACJ,eACA,cACA,cAAc,WACa;CAC3B,MAAM,cAAc;CACpB,SAAS,cAAc;CAEvB,iBAAiB,CAAC,cAAc,cAAc,kBAAkB,OAAO;CACvE;CACA,OAAO;EACL,SAAS;EACT,eAAe,mBAAmB,eAAe,IAAI;CACvD;AACF;AAEA,MAAM,uBACJ,eACA,cACA,cAAc,WACsB;CACpC,MAAM,cAAc;CACpB,SAAS,cAAc;CAEvB,iBAAiB,CAAC,cAAc,cAAc,kBAAkB,OAAO;CACvE,sBAAsB,cAAc;CACpC;CACA,OAAO;EACL,SAAS;EACT,eAAe,mBAAmB,eAAe,IAAI;CACvD;AACF;AAEA,MAAa,iCACX,UACA,SACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,oBAAoB,OAAO,0BAA0B,UAAU,SAAS;EACtE,MAAM,cAAc;EACpB,SAAS;EACT,iBAAiB,cAAc;CACjC,CAAC,EACH;AACF,CAAC;AAEH,MAAa,kCACX,UACA,SACA,cACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,yBAAyB,OAAO,+BAC9B,UACA,SACA,eAAe,eAAe,YAAY,CAC5C,EACF;AACF,CAAC;AAEH,MAAa,uCACX,UACA,SACA,cACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,uBAAuB,OAAO,kCAC5B,UACA,SACA,oBAAoB,eAAe,YAAY,CACjD,EACF;AACF,CAAC;AAEH,MAAa,gCACX,UACA,SACA,cACA,eACA,UAKA,OAAO,IAAI,aAAgF;CACzF,MAAM,QAAQ,OAAO;CAErB,IAAI,OAAO,gBAAgB,OAAO,OAAO,iBAAiB,KAAK,CAAC,CAAC;CACjE,OAAO,cAAc,oBAAoB,cAAc;CAkBvD,QAAO,OAhBe,uBAElB,SAAS,aAAa,gBACpB,OAAO,IAAI,aAAa;EACtB,OAAO,OAAO,MAAM,aAAa,EAC/B,yBAAyB,OAAO,+BAC9B,aACA,SACA,eAAe,eAAe,cAAc,IAAI,CAClD,EACF,CAAC;CACH,CAAC,CACH,GACF,EAAE,MAAM,cAAc,KAAK,CAC7B,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,KAAK,CAAC,EAAA,CAErC;AAChB,CAAC;AAEH,MAAa,qCACX,UACA,SACA,cACA,eACA,UAKA,OAAO,IAAI,aAAgF;CACzF,MAAM,QAAQ,OAAO;CAErB,IAAI,OAAO,gBAAgB,OAAO,OAAO,iBAAiB,KAAK,CAAC,CAAC;CACjE,OAAO,cAAc,oBAAoB,cAAc;CAkBvD,QAAO,OAhBe,uBAElB,SAAS,aAAa,gBACpB,OAAO,IAAI,aAAa;EACtB,OAAO,OAAO,MAAM,aAAa,EAC/B,uBAAuB,OAAO,kCAC5B,aACA,SACA,oBAAoB,eAAe,cAAc,IAAI,CACvD,EACF,CAAC;CACH,CAAC,CACH,GACF,EAAE,MAAM,cAAc,KAAK,CAC7B,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,KAAK,CAAC,EAAA,CAErC;AAChB,CAAC;AAEH,MAAa,2BACX,aAEA,MAAM,OACJ,oBACA,OAAO,IAAI,WAAW,UAAU,MAAM,kBAAkB,CAC1D;AAEF,MAAa,gCACX,aAMA,MAAM,OACJ,yBACA,OAAO,IAAI,WAAW,UAAU,MAAM,uBAAuB,CAC/D;AAEF,MAAa,0BACX,KACA,aAMA,MAAM,OACJ,KACA,OAAO,IAAI,WAAW,UAAU,MAAM,qBAAqB,CAC7D"}
|
|
1
|
+
{"version":3,"file":"email-target.mjs","names":[],"sources":["../../src/drizzle/email-target.ts"],"sourcesContent":["import { EmailAddressPersistence, EmailSignInTargets, EmailUnavailable } from \"@yielded/auth/Email\";\nimport {\n coordinateCommit,\n hasCommitScope,\n LifecycleHooks,\n type HookConfigurationError,\n} from \"@yielded/auth/Hooks\";\n/* oxlint-disable no-explicit-any -- public driver wrappers restore concrete Drizzle generics. */\nimport { type Context, Effect, Layer } from \"effect\";\nimport type * as SqlError from \"effect/sql/SqlError\";\n\nimport {\n makeSqlEmailRegistrationAuthority,\n type EmailRegistrationAuthority,\n type EmailRegistrationConfiguration,\n} from \"./email-registration\";\nimport {\n makeSqlEmailAddressPersistence,\n makeSqlEmailSignInTargets,\n type EmailSqlConfiguration,\n type EmailSqlDatabase,\n type EmailSqlQuery,\n} from \"./email-sql\";\nimport type { ProofTargetConfiguration } from \"./proof-target\";\nimport { sqlClientStandaloneGuard } from \"./standalone-guard\";\n\nexport interface EmailTargetConfiguration {\n readonly mode: \"interactive\" | \"synchronous\";\n readonly locking: boolean;\n readonly standaloneGuard: Effect.Effect<void, EmailUnavailable>;\n readonly coordinatorGuard?: Effect.Effect<void, EmailUnavailable>;\n readonly generatedSubjectRows: (query: EmailSqlQuery) => EmailSqlQuery;\n readonly proof: ProofTargetConfiguration;\n}\n\ninterface TransactionOwner<Transaction> {\n readonly transaction: <A, E, R>(\n body: (transaction: Transaction) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SqlError.SqlError, R>;\n}\n\nexport type EmailCoordinatorError<E> =\n | E\n | EmailUnavailable\n | HookConfigurationError\n | SqlError.SqlError;\n\nexport const sqlClientEmailStandaloneGuard = (\n database: unknown,\n): Effect.Effect<void, EmailUnavailable> =>\n sqlClientStandaloneGuard(database, () => EmailUnavailable.make({}));\n\nconst proofConfiguration = (configuration: EmailTargetConfiguration, coordinated = false) => ({\n mode: configuration.proof.mode,\n locking: configuration.proof.locking,\n\n standaloneGuard: Effect.void,\n coordinated,\n insertIfAbsent: configuration.proof.insertIfAbsent,\n});\n\nconst addressOptions = (\n configuration: EmailTargetConfiguration,\n proofMapping: any,\n coordinated = false,\n): EmailSqlConfiguration => ({\n mode: configuration.mode,\n locking: configuration.locking,\n\n standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,\n coordinated,\n proof: {\n mapping: proofMapping,\n configuration: proofConfiguration(configuration, true),\n },\n});\n\nconst registrationOptions = (\n configuration: EmailTargetConfiguration,\n proofMapping: any,\n coordinated = false,\n): EmailRegistrationConfiguration => ({\n mode: configuration.mode,\n locking: configuration.locking,\n\n standaloneGuard: !coordinated ? configuration.standaloneGuard : Effect.void,\n generatedSubjectRows: configuration.generatedSubjectRows,\n coordinated,\n proof: {\n mapping: proofMapping,\n configuration: proofConfiguration(configuration, true),\n },\n});\n\nexport const makeTargetEmailSignInServices = (\n database: any,\n mapping: any,\n configuration: EmailTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n emailSignInTargets: yield* makeSqlEmailSignInTargets(database, mapping, {\n mode: configuration.mode,\n locking: false,\n standaloneGuard: configuration.standaloneGuard,\n }),\n };\n });\n\nexport const makeTargetEmailAddressServices = (\n database: any,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n emailAddressPersistence: yield* makeSqlEmailAddressPersistence(\n database,\n mapping,\n addressOptions(configuration, proofMapping),\n ),\n };\n });\n\nexport const makeTargetEmailRegistrationServices = <Registration>(\n database: any,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n) =>\n Effect.gen(function* () {\n return {\n registrationAuthority: yield* makeSqlEmailRegistrationAuthority<Registration>(\n database,\n mapping,\n registrationOptions(configuration, proofMapping),\n ),\n };\n });\n\nexport const coordinateTargetEmailAddress = <Transaction, A, E, R>(\n database: TransactionOwner<Transaction>,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n owner: (\n transaction: Transaction,\n services: { readonly emailAddressPersistence: EmailAddressPersistence[\"Service\"] },\n ) => Effect.Effect<A, E, R>,\n): Effect.Effect<A, EmailCoordinatorError<E>, R | LifecycleHooks> =>\n Effect.gen(function* (): Effect.fn.Return<A, EmailCoordinatorError<E>, R | LifecycleHooks> {\n const hooks = yield* LifecycleHooks;\n\n if (yield* hasCommitScope) return yield* EmailUnavailable.make({});\n yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;\n\n const result = yield* coordinateCommit(\n () =>\n database.transaction((transaction) =>\n Effect.gen(function* () {\n return yield* owner(transaction, {\n emailAddressPersistence: yield* makeSqlEmailAddressPersistence(\n transaction as unknown as EmailSqlDatabase,\n mapping,\n addressOptions(configuration, proofMapping, true),\n ),\n });\n }),\n ),\n { mode: configuration.mode },\n ).pipe(Effect.provideService(LifecycleHooks, hooks));\n\n return result.value;\n });\n\nexport const coordinateTargetEmailRegistration = <Registration, Transaction, A, E, R>(\n database: TransactionOwner<Transaction>,\n mapping: any,\n proofMapping: any,\n configuration: EmailTargetConfiguration,\n owner: (\n transaction: Transaction,\n services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },\n ) => Effect.Effect<A, E, R>,\n): Effect.Effect<A, EmailCoordinatorError<E>, R | LifecycleHooks> =>\n Effect.gen(function* (): Effect.fn.Return<A, EmailCoordinatorError<E>, R | LifecycleHooks> {\n const hooks = yield* LifecycleHooks;\n\n if (yield* hasCommitScope) return yield* EmailUnavailable.make({});\n yield* configuration.coordinatorGuard ?? configuration.standaloneGuard;\n\n const result = yield* coordinateCommit(\n () =>\n database.transaction((transaction) =>\n Effect.gen(function* () {\n return yield* owner(transaction, {\n registrationAuthority: yield* makeSqlEmailRegistrationAuthority<Registration>(\n transaction as unknown as EmailSqlDatabase,\n mapping,\n registrationOptions(configuration, proofMapping, true),\n ),\n });\n }),\n ),\n { mode: configuration.mode },\n ).pipe(Effect.provideService(LifecycleHooks, hooks));\n\n return result.value;\n });\n\nexport const emailSignInTargetsLayer = (\n services: Effect.Effect<{ readonly emailSignInTargets: EmailSignInTargets[\"Service\"] }>,\n) =>\n Layer.effect(\n EmailSignInTargets,\n Effect.map(services, (value) => value.emailSignInTargets),\n );\n\nexport const emailAddressPersistenceLayer = (\n services: Effect.Effect<\n { readonly emailAddressPersistence: EmailAddressPersistence[\"Service\"] },\n never,\n LifecycleHooks\n >,\n) =>\n Layer.effect(\n EmailAddressPersistence,\n Effect.map(services, (value) => value.emailAddressPersistence),\n );\n\nexport const emailRegistrationLayer = <Id, Registration>(\n tag: Context.Key<Id, EmailRegistrationAuthority<Registration>>,\n services: Effect.Effect<\n { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },\n never,\n LifecycleHooks\n >,\n) =>\n Layer.effect(\n tag,\n Effect.map(services, (value) => value.registrationAuthority),\n );\n"],"mappings":";;;;;;;AA+CA,MAAa,iCACX,aAEA,yBAAyB,gBAAgB,iBAAiB,KAAK,CAAC,CAAC,CAAC;AAEpE,MAAM,sBAAsB,eAAyC,cAAc,WAAW;CAC5F,MAAM,cAAc,MAAM;CAC1B,SAAS,cAAc,MAAM;CAE7B,iBAAiB,OAAO;CACxB;CACA,gBAAgB,cAAc,MAAM;AACtC;AAEA,MAAM,kBACJ,eACA,cACA,cAAc,WACa;CAC3B,MAAM,cAAc;CACpB,SAAS,cAAc;CAEvB,iBAAiB,CAAC,cAAc,cAAc,kBAAkB,OAAO;CACvE;CACA,OAAO;EACL,SAAS;EACT,eAAe,mBAAmB,eAAe,IAAI;CACvD;AACF;AAEA,MAAM,uBACJ,eACA,cACA,cAAc,WACsB;CACpC,MAAM,cAAc;CACpB,SAAS,cAAc;CAEvB,iBAAiB,CAAC,cAAc,cAAc,kBAAkB,OAAO;CACvE,sBAAsB,cAAc;CACpC;CACA,OAAO;EACL,SAAS;EACT,eAAe,mBAAmB,eAAe,IAAI;CACvD;AACF;AAEA,MAAa,iCACX,UACA,SACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,oBAAoB,OAAO,0BAA0B,UAAU,SAAS;EACtE,MAAM,cAAc;EACpB,SAAS;EACT,iBAAiB,cAAc;CACjC,CAAC,EACH;AACF,CAAC;AAEH,MAAa,kCACX,UACA,SACA,cACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,yBAAyB,OAAO,+BAC9B,UACA,SACA,eAAe,eAAe,YAAY,CAC5C,EACF;AACF,CAAC;AAEH,MAAa,uCACX,UACA,SACA,cACA,kBAEA,OAAO,IAAI,aAAa;CACtB,OAAO,EACL,uBAAuB,OAAO,kCAC5B,UACA,SACA,oBAAoB,eAAe,YAAY,CACjD,EACF;AACF,CAAC;AAEH,MAAa,gCACX,UACA,SACA,cACA,eACA,UAKA,OAAO,IAAI,aAAgF;CACzF,MAAM,QAAQ,OAAO;CAErB,IAAI,OAAO,gBAAgB,OAAO,OAAO,iBAAiB,KAAK,CAAC,CAAC;CACjE,OAAO,cAAc,oBAAoB,cAAc;CAkBvD,QAAO,OAhBe,uBAElB,SAAS,aAAa,gBACpB,OAAO,IAAI,aAAa;EACtB,OAAO,OAAO,MAAM,aAAa,EAC/B,yBAAyB,OAAO,+BAC9B,aACA,SACA,eAAe,eAAe,cAAc,IAAI,CAClD,EACF,CAAC;CACH,CAAC,CACH,GACF,EAAE,MAAM,cAAc,KAAK,CAC7B,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,KAAK,CAAC,EAAA,CAErC;AAChB,CAAC;AAEH,MAAa,qCACX,UACA,SACA,cACA,eACA,UAKA,OAAO,IAAI,aAAgF;CACzF,MAAM,QAAQ,OAAO;CAErB,IAAI,OAAO,gBAAgB,OAAO,OAAO,iBAAiB,KAAK,CAAC,CAAC;CACjE,OAAO,cAAc,oBAAoB,cAAc;CAkBvD,QAAO,OAhBe,uBAElB,SAAS,aAAa,gBACpB,OAAO,IAAI,aAAa;EACtB,OAAO,OAAO,MAAM,aAAa,EAC/B,uBAAuB,OAAO,kCAC5B,aACA,SACA,oBAAoB,eAAe,cAAc,IAAI,CACvD,EACF,CAAC;CACH,CAAC,CACH,GACF,EAAE,MAAM,cAAc,KAAK,CAC7B,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,KAAK,CAAC,EAAA,CAErC;AAChB,CAAC;AAEH,MAAa,2BACX,aAEA,MAAM,OACJ,oBACA,OAAO,IAAI,WAAW,UAAU,MAAM,kBAAkB,CAC1D;AAEF,MAAa,gCACX,aAMA,MAAM,OACJ,yBACA,OAAO,IAAI,WAAW,UAAU,MAAM,uBAAuB,CAC/D;AAEF,MAAa,0BACX,KACA,aAMA,MAAM,OACJ,KACA,OAAO,IAAI,WAAW,UAAU,MAAM,qBAAqB,CAC7D"}
|
package/dist/drizzle/model.d.mts
CHANGED
|
@@ -1,132 +1,14 @@
|
|
|
1
1
|
import { PersistenceMappingError, PersistenceMappingError as PersistenceMappingError$1, SubjectIdCodec, SubjectIdCodec as SubjectIdCodec$1, isMappedConstraintConflict } from "@yielded/auth-persistence/Adapter";
|
|
2
|
-
import { AuthStore, ConsumeDecision } from "@yielded/auth/AuthStore";
|
|
3
|
-
import { AuthStoreError } from "@yielded/auth/Errors";
|
|
4
2
|
import { ExternalIdentity, ExternalIdentityMutation, LoginIdentifier, SubjectProvisioner, SubjectProvisioningInput } from "@yielded/auth/Identity";
|
|
5
|
-
import {
|
|
6
|
-
import { ConsumeChallenge, NewChallenge, NewRegistration, PendingRegistration } from "@yielded/auth/Schema";
|
|
7
|
-
import { AnyColumn, InferInsertModel, InferSelectModel, Table } from "drizzle-orm";
|
|
3
|
+
import { AnyColumn, InferInsertModel, Table } from "drizzle-orm";
|
|
8
4
|
import { DateTime, Effect, Layer } from "effect";
|
|
9
|
-
import { ChallengeConsumeDecision } from "@yielded/auth/Persistence";
|
|
10
|
-
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
11
5
|
//#region src/drizzle/model.d.ts
|
|
12
6
|
export type CommitMode = "interactive" | "synchronous" | "batch";
|
|
13
|
-
/**
|
|
14
|
-
* Ordinary error-channel consumes must own their commit. Coordinated callers
|
|
15
|
-
* use the decision methods inside their outer transaction and translate only
|
|
16
|
-
* after that owner commits.
|
|
17
|
-
*/
|
|
18
|
-
export interface SqlClientTransactionDatabase {
|
|
19
|
-
readonly $client: Pick<SqlClient.SqlClient, "transactionService">;
|
|
20
|
-
}
|
|
21
|
-
export declare const requireStandaloneConsume: (database: SqlClientTransactionDatabase) => Effect.Effect<void, AuthStoreError>;
|
|
22
7
|
export interface InstantCodec<NativeInstant> {
|
|
23
8
|
readonly encode: (instant: DateTime.Utc) => NativeInstant;
|
|
24
9
|
readonly decode: (native: NativeInstant) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;
|
|
25
10
|
}
|
|
26
|
-
export interface RequiredAuthStoreConstraints {
|
|
27
|
-
readonly series: "unique(namespace,value,purpose)";
|
|
28
|
-
readonly challengeDigest: "unique(tokenDigest)";
|
|
29
|
-
readonly registrationDigest: "unique(tokenDigest)";
|
|
30
|
-
}
|
|
31
|
-
export interface RequiredOAuthStateConstraints {
|
|
32
|
-
readonly oauthStateDigest: "unique(stateDigest)";
|
|
33
|
-
}
|
|
34
|
-
export interface RequiredAuthConstraints extends RequiredAuthStoreConstraints, RequiredOAuthStateConstraints {}
|
|
35
|
-
export declare const requiredAuthConstraints: RequiredAuthConstraints;
|
|
36
|
-
export declare const requiredAuthStoreConstraints: RequiredAuthStoreConstraints;
|
|
37
|
-
export declare const requiredOAuthStateConstraints: RequiredOAuthStateConstraints;
|
|
38
11
|
type ColumnKey<T extends Table> = Extract<keyof T["_"]["columns"], string>;
|
|
39
|
-
export interface ChallengeRecord {
|
|
40
|
-
readonly challenge: NewChallenge;
|
|
41
|
-
readonly namespace: string;
|
|
42
|
-
readonly failedAttempts: number;
|
|
43
|
-
readonly consumed: boolean;
|
|
44
|
-
}
|
|
45
|
-
export interface ChallengeColumns<T extends Table> {
|
|
46
|
-
readonly challengeId: ColumnKey<T>;
|
|
47
|
-
readonly tokenDigest: ColumnKey<T>;
|
|
48
|
-
readonly namespace: ColumnKey<T>;
|
|
49
|
-
readonly value: ColumnKey<T>;
|
|
50
|
-
readonly purpose: ColumnKey<T>;
|
|
51
|
-
readonly otpKeyId: ColumnKey<T>;
|
|
52
|
-
readonly otpDigest: ColumnKey<T>;
|
|
53
|
-
readonly issuedAt: ColumnKey<T>;
|
|
54
|
-
readonly expiresAt: ColumnKey<T>;
|
|
55
|
-
readonly attemptLimit: ColumnKey<T>;
|
|
56
|
-
readonly failedAttempts: ColumnKey<T>;
|
|
57
|
-
readonly consumed: ColumnKey<T>;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Inputs are immutable server-created issuances. Replacements must advance
|
|
61
|
-
* issuedAt; equal or older issuances fail even after consumption or expiry.
|
|
62
|
-
* Instant encoding must preserve this ordering. Retain the series row as an
|
|
63
|
-
* issuance watermark until every previously accepted issuance has expired;
|
|
64
|
-
* current-row expiry alone is insufficient if historical lifetimes were longer.
|
|
65
|
-
*/
|
|
66
|
-
export interface ChallengeTableMapping<T extends Table> {
|
|
67
|
-
readonly table: T;
|
|
68
|
-
readonly columns: ChallengeColumns<T>;
|
|
69
|
-
readonly identifierNamespace: string;
|
|
70
|
-
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
71
|
-
readonly encodeInsert: (input: NewChallenge, state: {
|
|
72
|
-
readonly namespace: string;
|
|
73
|
-
readonly failedAttempts: number;
|
|
74
|
-
readonly consumed: false;
|
|
75
|
-
}) => InferInsertModel<T>;
|
|
76
|
-
readonly encodeUpdate: (input: NewChallenge, state: {
|
|
77
|
-
readonly namespace: string;
|
|
78
|
-
readonly failedAttempts: unknown;
|
|
79
|
-
readonly consumed: false;
|
|
80
|
-
}) => Readonly<Record<string, unknown>>;
|
|
81
|
-
readonly decode: (row: InferSelectModel<T>) => Effect.Effect<ChallengeRecord, PersistenceMappingError>;
|
|
82
|
-
}
|
|
83
|
-
export interface RegistrationRecord {
|
|
84
|
-
readonly registration: PendingRegistration;
|
|
85
|
-
readonly consumed: boolean;
|
|
86
|
-
}
|
|
87
|
-
export interface RegistrationColumns<T extends Table> {
|
|
88
|
-
readonly registrationId: ColumnKey<T>;
|
|
89
|
-
readonly tokenDigest: ColumnKey<T>;
|
|
90
|
-
readonly expiresAt: ColumnKey<T>;
|
|
91
|
-
readonly consumed: ColumnKey<T>;
|
|
92
|
-
}
|
|
93
|
-
export interface RegistrationTableMapping<T extends Table> {
|
|
94
|
-
readonly table: T;
|
|
95
|
-
readonly columns: RegistrationColumns<T>;
|
|
96
|
-
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
97
|
-
readonly encodeInsert: (input: NewRegistration, consumed: false) => InferInsertModel<T>;
|
|
98
|
-
readonly decode: (row: InferSelectModel<T>) => Effect.Effect<RegistrationRecord, PersistenceMappingError>;
|
|
99
|
-
}
|
|
100
|
-
export interface OAuthStateColumns<T extends Table> {
|
|
101
|
-
readonly stateDigest: ColumnKey<T>;
|
|
102
|
-
readonly expiresAt: ColumnKey<T>;
|
|
103
|
-
readonly consumed: ColumnKey<T>;
|
|
104
|
-
}
|
|
105
|
-
export interface OAuthStateTableMapping<T extends Table> {
|
|
106
|
-
readonly table: T;
|
|
107
|
-
readonly columns: OAuthStateColumns<T>;
|
|
108
|
-
readonly encodeInstant: (instant: DateTime.Utc) => unknown;
|
|
109
|
-
readonly encodeInsert: (state: OAuthState, consumed: false) => InferInsertModel<T>;
|
|
110
|
-
readonly decode: (row: InferSelectModel<T>) => Effect.Effect<{
|
|
111
|
-
readonly state: OAuthState;
|
|
112
|
-
readonly consumed: boolean;
|
|
113
|
-
}, PersistenceMappingError>;
|
|
114
|
-
}
|
|
115
|
-
export interface AuthStoreTables<Challenge extends Table, Registration extends Table> {
|
|
116
|
-
readonly constraints: RequiredAuthStoreConstraints;
|
|
117
|
-
readonly challenge: ChallengeTableMapping<Challenge>;
|
|
118
|
-
readonly registration: RegistrationTableMapping<Registration>;
|
|
119
|
-
}
|
|
120
|
-
export interface OAuthStateTables<State extends Table> {
|
|
121
|
-
readonly constraints: RequiredOAuthStateConstraints;
|
|
122
|
-
readonly oauthState: OAuthStateTableMapping<State>;
|
|
123
|
-
}
|
|
124
|
-
export interface AuthTables<Challenge extends Table, Registration extends Table, State extends Table> {
|
|
125
|
-
readonly constraints: RequiredAuthConstraints;
|
|
126
|
-
readonly challenge: ChallengeTableMapping<Challenge>;
|
|
127
|
-
readonly registration: RegistrationTableMapping<Registration>;
|
|
128
|
-
readonly oauthState: OAuthStateTableMapping<State>;
|
|
129
|
-
}
|
|
130
12
|
export interface RequiredIdentityConstraints {
|
|
131
13
|
readonly identifier: "unique(namespace,value)";
|
|
132
14
|
readonly externalIdentity: "unique(provider,issuer,subject)";
|
|
@@ -229,17 +111,11 @@ export declare const provisioningFingerprint: (input: SubjectProvisioningInput)
|
|
|
229
111
|
*/
|
|
230
112
|
export declare const column: <T extends Table>(table: T, key: ColumnKey<T>) => AnyColumn;
|
|
231
113
|
export declare const updateValues: <T extends Table>(entries: ReadonlyArray<readonly [ColumnKey<T>, unknown]>) => Partial<InferInsertModel<T>>;
|
|
232
|
-
export type ChallengeInput = ConsumeChallenge;
|
|
233
|
-
/** Acquire an application database in Effect and expose the auth stores as one layer. */
|
|
234
|
-
export declare const authServicesLayer: <E, R>(acquire: Effect.Effect<{
|
|
235
|
-
readonly authStore: AuthStore["Service"];
|
|
236
|
-
readonly oauthStateStore: OAuthStateStore["Service"];
|
|
237
|
-
}, E, R>) => Layer.Layer<AuthStore | OAuthStateStore, E, Exclude<R, import("effect/Scope").Scope>>;
|
|
238
114
|
/** Acquire an application database in Effect and expose the identity services as one layer. */
|
|
239
115
|
export declare const identityServicesLayer: <E, R>(acquire: Effect.Effect<{
|
|
240
116
|
readonly subjectProvisioner: SubjectProvisioner["Service"];
|
|
241
117
|
readonly externalIdentityMutation: ExternalIdentityMutation["Service"];
|
|
242
118
|
}, E, R>) => Layer.Layer<ExternalIdentityMutation | SubjectProvisioner, E, Exclude<R, import("effect/Scope").Scope>>;
|
|
243
119
|
//#endregion
|
|
244
|
-
export { type
|
|
120
|
+
export { type PersistenceMappingError$1 as PersistenceMappingError, type SubjectIdCodec$1 as SubjectIdCodec, isMappedConstraintConflict };
|
|
245
121
|
//# sourceMappingURL=model.d.mts.map
|
package/dist/drizzle/model.mjs
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
import { PersistenceMappingError as PersistenceMappingError$1, isMappedConstraintConflict
|
|
2
|
-
import { AuthStore } from "@yielded/auth/AuthStore";
|
|
3
|
-
import { AuthStoreError } from "@yielded/auth/Errors";
|
|
1
|
+
import { PersistenceMappingError as PersistenceMappingError$1, isMappedConstraintConflict } from "@yielded/auth-persistence/Adapter";
|
|
4
2
|
import { ExternalIdentityMutation, SubjectProvisioner } from "@yielded/auth/Identity";
|
|
5
|
-
import { OAuthStateStore } from "@yielded/auth/OAuth";
|
|
6
|
-
import "@yielded/auth/Schema";
|
|
7
3
|
import { getTableColumns } from "drizzle-orm";
|
|
8
4
|
import { Context, DateTime, Effect, Layer } from "effect";
|
|
9
5
|
//#region src/drizzle/model.ts
|
|
10
|
-
const requireStandaloneConsume = (database) => requireStandalone(() => AuthStoreError.make({ message: "Use the decision consume API inside an outer database transaction" }), database.$client);
|
|
11
|
-
const requiredAuthConstraints = {
|
|
12
|
-
series: "unique(namespace,value,purpose)",
|
|
13
|
-
challengeDigest: "unique(tokenDigest)",
|
|
14
|
-
registrationDigest: "unique(tokenDigest)",
|
|
15
|
-
oauthStateDigest: "unique(stateDigest)"
|
|
16
|
-
};
|
|
17
|
-
const requiredAuthStoreConstraints = {
|
|
18
|
-
series: "unique(namespace,value,purpose)",
|
|
19
|
-
challengeDigest: "unique(tokenDigest)",
|
|
20
|
-
registrationDigest: "unique(tokenDigest)"
|
|
21
|
-
};
|
|
22
|
-
const requiredOAuthStateConstraints = { oauthStateDigest: "unique(stateDigest)" };
|
|
23
6
|
const requiredIdentityConstraints = {
|
|
24
7
|
identifier: "unique(namespace,value)",
|
|
25
8
|
externalIdentity: "unique(provider,issuer,subject)",
|
|
@@ -45,11 +28,9 @@ const provisioningFingerprint = (input) => JSON.stringify(input.identifier === v
|
|
|
45
28
|
*/
|
|
46
29
|
const column = (table, key) => getTableColumns(table)[key];
|
|
47
30
|
const updateValues = (entries) => Object.fromEntries(entries);
|
|
48
|
-
/** Acquire an application database in Effect and expose the auth stores as one layer. */
|
|
49
|
-
const authServicesLayer = (acquire) => Layer.effectContext(Effect.map(acquire, ({ authStore, oauthStateStore }) => Context.make(AuthStore, authStore).pipe(Context.add(OAuthStateStore, oauthStateStore))));
|
|
50
31
|
/** Acquire an application database in Effect and expose the identity services as one layer. */
|
|
51
32
|
const identityServicesLayer = (acquire) => Layer.effectContext(Effect.map(acquire, ({ subjectProvisioner, externalIdentityMutation }) => Context.make(SubjectProvisioner, subjectProvisioner).pipe(Context.add(ExternalIdentityMutation, externalIdentityMutation))));
|
|
52
33
|
//#endregion
|
|
53
|
-
export { PersistenceMappingError$1 as PersistenceMappingError,
|
|
34
|
+
export { PersistenceMappingError$1 as PersistenceMappingError, column, identityServicesLayer, isMappedConstraintConflict, provisioningFingerprint, requiredExternalIdentityConstraints, requiredIdentityConstraints, requiredSubjectProvisioningConstraints, updateValues };
|
|
54
35
|
|
|
55
36
|
//# sourceMappingURL=model.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.mjs","names":[],"sources":["../../src/drizzle/model.ts"],"sourcesContent":["import { requireStandalone } from \"@yielded/auth-persistence/Adapter\";\nimport { AuthStore } from \"@yielded/auth/AuthStore\";\nimport { AuthStoreError } from \"@yielded/auth/Errors\";\nimport {\n ExternalIdentityMutation,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n type ExternalIdentity,\n type LoginIdentifier,\n} from \"@yielded/auth/Identity\";\nimport { OAuthStateStore, type OAuthState } from \"@yielded/auth/OAuth\";\nimport {\n type ConsumeChallenge,\n type NewChallenge,\n type NewRegistration,\n type PendingRegistration,\n} from \"@yielded/auth/Schema\";\nimport {\n getTableColumns,\n type AnyColumn,\n type InferInsertModel,\n type InferSelectModel,\n type Table,\n} from \"drizzle-orm\";\nimport { Context, DateTime, Effect, Layer } from \"effect\";\nimport type * as SqlClient from \"effect/unstable/sql/SqlClient\";\n\nexport type CommitMode = \"interactive\" | \"synchronous\" | \"batch\";\n\n/**\n * Ordinary error-channel consumes must own their commit. Coordinated callers\n * use the decision methods inside their outer transaction and translate only\n * after that owner commits.\n */\nexport interface SqlClientTransactionDatabase {\n readonly $client: Pick<SqlClient.SqlClient, \"transactionService\">;\n}\n\nexport const requireStandaloneConsume = (\n database: SqlClientTransactionDatabase,\n): Effect.Effect<void, AuthStoreError> =>\n requireStandalone(\n () =>\n AuthStoreError.make({\n message: \"Use the decision consume API inside an outer database transaction\",\n }),\n database.$client,\n );\n\nexport type { ChallengeConsumeDecision } from \"@yielded/auth/Persistence\";\nexport type { ConsumeDecision } from \"@yielded/auth/AuthStore\";\n\nexport {\n PersistenceMappingError,\n isMappedConstraintConflict,\n} from \"@yielded/auth-persistence/Adapter\";\n\nimport type { PersistenceMappingError, SubjectIdCodec } from \"@yielded/auth-persistence/Adapter\";\n\nexport interface InstantCodec<NativeInstant> {\n readonly encode: (instant: DateTime.Utc) => NativeInstant;\n readonly decode: (native: NativeInstant) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;\n}\n\nexport interface RequiredAuthStoreConstraints {\n readonly series: \"unique(namespace,value,purpose)\";\n readonly challengeDigest: \"unique(tokenDigest)\";\n readonly registrationDigest: \"unique(tokenDigest)\";\n}\n\nexport interface RequiredOAuthStateConstraints {\n readonly oauthStateDigest: \"unique(stateDigest)\";\n}\n\nexport interface RequiredAuthConstraints\n extends RequiredAuthStoreConstraints, RequiredOAuthStateConstraints {}\n\nexport const requiredAuthConstraints: RequiredAuthConstraints = {\n series: \"unique(namespace,value,purpose)\",\n challengeDigest: \"unique(tokenDigest)\",\n registrationDigest: \"unique(tokenDigest)\",\n oauthStateDigest: \"unique(stateDigest)\",\n};\n\nexport const requiredAuthStoreConstraints: RequiredAuthStoreConstraints = {\n series: \"unique(namespace,value,purpose)\",\n challengeDigest: \"unique(tokenDigest)\",\n registrationDigest: \"unique(tokenDigest)\",\n};\n\nexport const requiredOAuthStateConstraints: RequiredOAuthStateConstraints = {\n oauthStateDigest: \"unique(stateDigest)\",\n};\n\ntype ColumnKey<T extends Table> = Extract<keyof T[\"_\"][\"columns\"], string>;\n\nexport interface ChallengeRecord {\n readonly challenge: NewChallenge;\n readonly namespace: string;\n readonly failedAttempts: number;\n readonly consumed: boolean;\n}\n\nexport interface ChallengeColumns<T extends Table> {\n readonly challengeId: ColumnKey<T>;\n readonly tokenDigest: ColumnKey<T>;\n readonly namespace: ColumnKey<T>;\n readonly value: ColumnKey<T>;\n readonly purpose: ColumnKey<T>;\n readonly otpKeyId: ColumnKey<T>;\n readonly otpDigest: ColumnKey<T>;\n readonly issuedAt: ColumnKey<T>;\n readonly expiresAt: ColumnKey<T>;\n readonly attemptLimit: ColumnKey<T>;\n readonly failedAttempts: ColumnKey<T>;\n readonly consumed: ColumnKey<T>;\n}\n\n/**\n * Inputs are immutable server-created issuances. Replacements must advance\n * issuedAt; equal or older issuances fail even after consumption or expiry.\n * Instant encoding must preserve this ordering. Retain the series row as an\n * issuance watermark until every previously accepted issuance has expired;\n * current-row expiry alone is insufficient if historical lifetimes were longer.\n */\nexport interface ChallengeTableMapping<T extends Table> {\n readonly table: T;\n readonly columns: ChallengeColumns<T>;\n readonly identifierNamespace: string;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly encodeInsert: (\n input: NewChallenge,\n state: {\n readonly namespace: string;\n readonly failedAttempts: number;\n readonly consumed: false;\n },\n ) => InferInsertModel<T>;\n readonly encodeUpdate: (\n input: NewChallenge,\n state: {\n readonly namespace: string;\n readonly failedAttempts: unknown;\n readonly consumed: false;\n },\n ) => Readonly<Record<string, unknown>>;\n readonly decode: (\n row: InferSelectModel<T>,\n ) => Effect.Effect<ChallengeRecord, PersistenceMappingError>;\n}\n\nexport interface RegistrationRecord {\n readonly registration: PendingRegistration;\n readonly consumed: boolean;\n}\n\nexport interface RegistrationColumns<T extends Table> {\n readonly registrationId: ColumnKey<T>;\n readonly tokenDigest: ColumnKey<T>;\n readonly expiresAt: ColumnKey<T>;\n readonly consumed: ColumnKey<T>;\n}\n\nexport interface RegistrationTableMapping<T extends Table> {\n readonly table: T;\n readonly columns: RegistrationColumns<T>;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly encodeInsert: (input: NewRegistration, consumed: false) => InferInsertModel<T>;\n readonly decode: (\n row: InferSelectModel<T>,\n ) => Effect.Effect<RegistrationRecord, PersistenceMappingError>;\n}\n\nexport interface OAuthStateColumns<T extends Table> {\n readonly stateDigest: ColumnKey<T>;\n readonly expiresAt: ColumnKey<T>;\n readonly consumed: ColumnKey<T>;\n}\n\nexport interface OAuthStateTableMapping<T extends Table> {\n readonly table: T;\n readonly columns: OAuthStateColumns<T>;\n readonly encodeInstant: (instant: DateTime.Utc) => unknown;\n readonly encodeInsert: (state: OAuthState, consumed: false) => InferInsertModel<T>;\n readonly decode: (\n row: InferSelectModel<T>,\n ) => Effect.Effect<\n { readonly state: OAuthState; readonly consumed: boolean },\n PersistenceMappingError\n >;\n}\n\nexport interface AuthStoreTables<Challenge extends Table, Registration extends Table> {\n readonly constraints: RequiredAuthStoreConstraints;\n readonly challenge: ChallengeTableMapping<Challenge>;\n readonly registration: RegistrationTableMapping<Registration>;\n}\n\nexport interface OAuthStateTables<State extends Table> {\n readonly constraints: RequiredOAuthStateConstraints;\n readonly oauthState: OAuthStateTableMapping<State>;\n}\n\nexport interface AuthTables<\n Challenge extends Table,\n Registration extends Table,\n State extends Table,\n> {\n readonly constraints: RequiredAuthConstraints;\n readonly challenge: ChallengeTableMapping<Challenge>;\n readonly registration: RegistrationTableMapping<Registration>;\n readonly oauthState: OAuthStateTableMapping<State>;\n}\n\nexport interface RequiredIdentityConstraints {\n readonly identifier: \"unique(namespace,value)\";\n readonly externalIdentity: \"unique(provider,issuer,subject)\";\n readonly provisioningRequest: \"unique(requestId)\";\n readonly provisioningSubject: \"notNull(provisioningRequest.subjectId)\";\n}\n\nexport interface RequiredSubjectProvisioningConstraints {\n readonly identifier: \"unique(namespace,value)\";\n readonly provisioningRequest: \"unique(requestId)\";\n readonly provisioningSubject: \"notNull(provisioningRequest.subjectId)\";\n}\n\nexport interface RequiredExternalIdentityConstraints {\n readonly externalIdentity: \"unique(provider,issuer,subject)\";\n}\n\nexport const requiredIdentityConstraints: RequiredIdentityConstraints = {\n identifier: \"unique(namespace,value)\",\n externalIdentity: \"unique(provider,issuer,subject)\",\n provisioningRequest: \"unique(requestId)\",\n provisioningSubject: \"notNull(provisioningRequest.subjectId)\",\n};\n\nexport const requiredSubjectProvisioningConstraints: RequiredSubjectProvisioningConstraints = {\n identifier: \"unique(namespace,value)\",\n provisioningRequest: \"unique(requestId)\",\n provisioningSubject: \"notNull(provisioningRequest.subjectId)\",\n};\n\nexport const requiredExternalIdentityConstraints: RequiredExternalIdentityConstraints = {\n externalIdentity: \"unique(provider,issuer,subject)\",\n};\n\nexport type { SubjectIdCodec } from \"@yielded/auth-persistence/Adapter\";\n\nexport interface SubjectProvisioningTables<\n Subject extends Table,\n Identifier extends Table,\n Request extends Table,\n NativeId,\n> {\n readonly constraints: RequiredSubjectProvisioningConstraints;\n readonly subject: {\n readonly table: Subject;\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly encodeInsert: (\n input: SubjectProvisioningInput,\n allocatedId: NativeId | undefined,\n ) => InferInsertModel<Subject>;\n readonly allocateId?: Effect.Effect<NativeId, PersistenceMappingError>;\n /** Required instead of allocateId when a synchronous-only DO transaction preallocates IDs. */\n readonly allocateIdSync?: () => NativeId;\n /** Decodes MySQL `$returningId()` for an autoincrement/runtime-default key. */\n readonly decodeGeneratedId?: (\n rows: ReadonlyArray<unknown>,\n ) => Effect.Effect<NativeId, PersistenceMappingError>;\n };\n readonly identifier: {\n readonly table: Identifier;\n readonly namespace: ColumnKey<Identifier>;\n readonly value: ColumnKey<Identifier>;\n readonly subjectId: ColumnKey<Identifier>;\n readonly encodeInsert: (\n identifier: LoginIdentifier,\n subjectId: NativeId,\n verifiedAt: DateTime.Utc | undefined,\n ) => InferInsertModel<Identifier>;\n };\n readonly provisioningRequest: {\n readonly table: Request;\n readonly requestId: ColumnKey<Request>;\n readonly fingerprint: ColumnKey<Request>;\n readonly subjectId: ColumnKey<Request>;\n readonly encodeInsert: (\n requestId: string,\n fingerprint: string,\n subjectId: NativeId,\n ) => InferInsertModel<Request>;\n };\n readonly subjectId: SubjectIdCodec<NativeId>;\n /** Narrows only database constraint failures; every other cause is unavailable. */\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\nexport interface ExternalIdentityTables<Subject extends Table, External extends Table, NativeId> {\n readonly constraints: RequiredExternalIdentityConstraints;\n readonly subject: {\n readonly table: Subject;\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n };\n readonly externalIdentity: {\n readonly table: External;\n readonly provider: ColumnKey<External>;\n readonly issuer: ColumnKey<External>;\n readonly subject: ColumnKey<External>;\n readonly subjectId: ColumnKey<External>;\n readonly encodeInsert: (\n identity: ExternalIdentity,\n subjectId: NativeId,\n ) => InferInsertModel<External>;\n };\n readonly subjectId: SubjectIdCodec<NativeId>;\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\nexport interface IdentityTables<\n Subject extends Table,\n Identifier extends Table,\n External extends Table,\n Request extends Table,\n NativeId,\n> {\n readonly constraints: RequiredIdentityConstraints;\n readonly subject: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>[\"subject\"];\n readonly identifier: SubjectProvisioningTables<\n Subject,\n Identifier,\n Request,\n NativeId\n >[\"identifier\"];\n readonly externalIdentity: ExternalIdentityTables<\n Subject,\n External,\n NativeId\n >[\"externalIdentity\"];\n readonly provisioningRequest: SubjectProvisioningTables<\n Subject,\n Identifier,\n Request,\n NativeId\n >[\"provisioningRequest\"];\n readonly subjectId: SubjectIdCodec<NativeId>;\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\n/** Extra encoders used by D1's ordered batch when the subject id is database-generated. */\nexport interface D1SubjectProvisioningMapping<\n Subject extends Table,\n Identifier extends Table,\n Request extends Table,\n NativeId,\n> extends SubjectProvisioningTables<Subject, Identifier, Request, NativeId> {\n readonly d1: {\n readonly requestInsertWithoutSubject: (\n requestId: string,\n fingerprint: string,\n ) => Partial<InferInsertModel<Request>>;\n readonly identifierInsertWithoutSubject: (\n identifier: LoginIdentifier,\n verifiedAt: DateTime.Utc | undefined,\n ) => Partial<InferInsertModel<Identifier>>;\n /** Unshadowed hidden-rowid alias; omit for WITHOUT ROWID or preallocated IDs. */\n readonly generatedRowIdAlias?: \"rowid\" | \"_rowid_\" | \"oid\";\n };\n}\n\nexport interface D1ExternalIdentityMapping<\n Subject extends Table,\n External extends Table,\n NativeId,\n> extends ExternalIdentityTables<Subject, External, NativeId> {\n readonly d1: {\n readonly activeStatusValue: unknown;\n };\n}\n\nexport interface D1GeneratedIdentityMapping<\n Subject extends Table,\n Identifier extends Table,\n External extends Table,\n Request extends Table,\n NativeId,\n> extends IdentityTables<Subject, Identifier, External, Request, NativeId> {\n readonly d1: D1SubjectProvisioningMapping<Subject, Identifier, Request, NativeId>[\"d1\"] &\n D1ExternalIdentityMapping<Subject, External, NativeId>[\"d1\"];\n}\n\nexport const provisioningFingerprint = (input: SubjectProvisioningInput): string =>\n // oxlint-disable-next-line no-restricted-properties -- stable internal provisioning fingerprint, never external JSON.\n JSON.stringify(\n input.identifier === undefined\n ? [\"v1\", null]\n : [\n \"v1\",\n input.identifier.namespace,\n input.identifier.value,\n input.verifiedAt === undefined ? null : DateTime.toEpochMillis(input.verifiedAt),\n ],\n );\n\n/**\n * Drizzle wraps Effect SQL failures before adapters observe them. Give the\n * consumer classifier each semantic wrapper in the short `cause`/`reason`\n * chain without exposing query text or bound parameters through public errors.\n */\n\nexport const column = <T extends Table>(table: T, key: ColumnKey<T>): AnyColumn =>\n getTableColumns(table)[key] as AnyColumn;\n\nexport const updateValues = <T extends Table>(\n entries: ReadonlyArray<readonly [ColumnKey<T>, unknown]>,\n): Partial<InferInsertModel<T>> => Object.fromEntries(entries) as Partial<InferInsertModel<T>>;\n\nexport type ChallengeInput = ConsumeChallenge;\n\n/** Acquire an application database in Effect and expose the auth stores as one layer. */\nexport const authServicesLayer = <E, R>(\n acquire: Effect.Effect<\n {\n readonly authStore: AuthStore[\"Service\"];\n readonly oauthStateStore: OAuthStateStore[\"Service\"];\n },\n E,\n R\n >,\n) =>\n Layer.effectContext(\n Effect.map(acquire, ({ authStore, oauthStateStore }) =>\n Context.make(AuthStore, authStore).pipe(Context.add(OAuthStateStore, oauthStateStore)),\n ),\n );\n\n/** Acquire an application database in Effect and expose the identity services as one layer. */\nexport const identityServicesLayer = <E, R>(\n acquire: Effect.Effect<\n {\n readonly subjectProvisioner: SubjectProvisioner[\"Service\"];\n readonly externalIdentityMutation: ExternalIdentityMutation[\"Service\"];\n },\n E,\n R\n >,\n) =>\n Layer.effectContext(\n Effect.map(acquire, ({ subjectProvisioner, externalIdentityMutation }) =>\n Context.make(SubjectProvisioner, subjectProvisioner).pipe(\n Context.add(ExternalIdentityMutation, externalIdentityMutation),\n ),\n ),\n );\n"],"mappings":";;;;;;;;;AAsCA,MAAa,4BACX,aAEA,wBAEI,eAAe,KAAK,EAClB,SAAS,oEACX,CAAC,GACH,SAAS,OACX;AA8BF,MAAa,0BAAmD;CAC9D,QAAQ;CACR,iBAAiB;CACjB,oBAAoB;CACpB,kBAAkB;AACpB;AAEA,MAAa,+BAA6D;CACxE,QAAQ;CACR,iBAAiB;CACjB,oBAAoB;AACtB;AAEA,MAAa,gCAA+D,EAC1E,kBAAkB,sBACpB;AA2IA,MAAa,8BAA2D;CACtE,YAAY;CACZ,kBAAkB;CAClB,qBAAqB;CACrB,qBAAqB;AACvB;AAEA,MAAa,yCAAiF;CAC5F,YAAY;CACZ,qBAAqB;CACrB,qBAAqB;AACvB;AAEA,MAAa,sCAA2E,EACtF,kBAAkB,kCACpB;AAsJA,MAAa,2BAA2B,UAEtC,KAAK,UACH,MAAM,eAAe,KAAA,IACjB,CAAC,MAAM,IAAI,IACX;CACE;CACA,MAAM,WAAW;CACjB,MAAM,WAAW;CACjB,MAAM,eAAe,KAAA,IAAY,OAAO,SAAS,cAAc,MAAM,UAAU;AACjF,CACN;;;;;;AAQF,MAAa,UAA2B,OAAU,QAChD,gBAAgB,KAAK,CAAC,CAAC;AAEzB,MAAa,gBACX,YACiC,OAAO,YAAY,OAAO;;AAK7D,MAAa,qBACX,YASA,MAAM,cACJ,OAAO,IAAI,UAAU,EAAE,WAAW,sBAChC,QAAQ,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,QAAQ,IAAI,iBAAiB,eAAe,CAAC,CACvF,CACF;;AAGF,MAAa,yBACX,YASA,MAAM,cACJ,OAAO,IAAI,UAAU,EAAE,oBAAoB,+BACzC,QAAQ,KAAK,oBAAoB,kBAAkB,CAAC,CAAC,KACnD,QAAQ,IAAI,0BAA0B,wBAAwB,CAChE,CACF,CACF"}
|
|
1
|
+
{"version":3,"file":"model.mjs","names":[],"sources":["../../src/drizzle/model.ts"],"sourcesContent":["import {\n ExternalIdentityMutation,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n type ExternalIdentity,\n type LoginIdentifier,\n} from \"@yielded/auth/Identity\";\nimport { getTableColumns, type AnyColumn, type InferInsertModel, type Table } from \"drizzle-orm\";\nimport { Context, DateTime, Effect, Layer } from \"effect\";\n\nexport type CommitMode = \"interactive\" | \"synchronous\" | \"batch\";\n\nexport {\n PersistenceMappingError,\n isMappedConstraintConflict,\n} from \"@yielded/auth-persistence/Adapter\";\n\nimport type { PersistenceMappingError, SubjectIdCodec } from \"@yielded/auth-persistence/Adapter\";\n\nexport interface InstantCodec<NativeInstant> {\n readonly encode: (instant: DateTime.Utc) => NativeInstant;\n readonly decode: (native: NativeInstant) => Effect.Effect<DateTime.Utc, PersistenceMappingError>;\n}\n\ntype ColumnKey<T extends Table> = Extract<keyof T[\"_\"][\"columns\"], string>;\n\nexport interface RequiredIdentityConstraints {\n readonly identifier: \"unique(namespace,value)\";\n readonly externalIdentity: \"unique(provider,issuer,subject)\";\n readonly provisioningRequest: \"unique(requestId)\";\n readonly provisioningSubject: \"notNull(provisioningRequest.subjectId)\";\n}\n\nexport interface RequiredSubjectProvisioningConstraints {\n readonly identifier: \"unique(namespace,value)\";\n readonly provisioningRequest: \"unique(requestId)\";\n readonly provisioningSubject: \"notNull(provisioningRequest.subjectId)\";\n}\n\nexport interface RequiredExternalIdentityConstraints {\n readonly externalIdentity: \"unique(provider,issuer,subject)\";\n}\n\nexport const requiredIdentityConstraints: RequiredIdentityConstraints = {\n identifier: \"unique(namespace,value)\",\n externalIdentity: \"unique(provider,issuer,subject)\",\n provisioningRequest: \"unique(requestId)\",\n provisioningSubject: \"notNull(provisioningRequest.subjectId)\",\n};\n\nexport const requiredSubjectProvisioningConstraints: RequiredSubjectProvisioningConstraints = {\n identifier: \"unique(namespace,value)\",\n provisioningRequest: \"unique(requestId)\",\n provisioningSubject: \"notNull(provisioningRequest.subjectId)\",\n};\n\nexport const requiredExternalIdentityConstraints: RequiredExternalIdentityConstraints = {\n externalIdentity: \"unique(provider,issuer,subject)\",\n};\n\nexport type { SubjectIdCodec } from \"@yielded/auth-persistence/Adapter\";\n\nexport interface SubjectProvisioningTables<\n Subject extends Table,\n Identifier extends Table,\n Request extends Table,\n NativeId,\n> {\n readonly constraints: RequiredSubjectProvisioningConstraints;\n readonly subject: {\n readonly table: Subject;\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly encodeInsert: (\n input: SubjectProvisioningInput,\n allocatedId: NativeId | undefined,\n ) => InferInsertModel<Subject>;\n readonly allocateId?: Effect.Effect<NativeId, PersistenceMappingError>;\n /** Required instead of allocateId when a synchronous-only DO transaction preallocates IDs. */\n readonly allocateIdSync?: () => NativeId;\n /** Decodes MySQL `$returningId()` for an autoincrement/runtime-default key. */\n readonly decodeGeneratedId?: (\n rows: ReadonlyArray<unknown>,\n ) => Effect.Effect<NativeId, PersistenceMappingError>;\n };\n readonly identifier: {\n readonly table: Identifier;\n readonly namespace: ColumnKey<Identifier>;\n readonly value: ColumnKey<Identifier>;\n readonly subjectId: ColumnKey<Identifier>;\n readonly encodeInsert: (\n identifier: LoginIdentifier,\n subjectId: NativeId,\n verifiedAt: DateTime.Utc | undefined,\n ) => InferInsertModel<Identifier>;\n };\n readonly provisioningRequest: {\n readonly table: Request;\n readonly requestId: ColumnKey<Request>;\n readonly fingerprint: ColumnKey<Request>;\n readonly subjectId: ColumnKey<Request>;\n readonly encodeInsert: (\n requestId: string,\n fingerprint: string,\n subjectId: NativeId,\n ) => InferInsertModel<Request>;\n };\n readonly subjectId: SubjectIdCodec<NativeId>;\n /** Narrows only database constraint failures; every other cause is unavailable. */\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\nexport interface ExternalIdentityTables<Subject extends Table, External extends Table, NativeId> {\n readonly constraints: RequiredExternalIdentityConstraints;\n readonly subject: {\n readonly table: Subject;\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n };\n readonly externalIdentity: {\n readonly table: External;\n readonly provider: ColumnKey<External>;\n readonly issuer: ColumnKey<External>;\n readonly subject: ColumnKey<External>;\n readonly subjectId: ColumnKey<External>;\n readonly encodeInsert: (\n identity: ExternalIdentity,\n subjectId: NativeId,\n ) => InferInsertModel<External>;\n };\n readonly subjectId: SubjectIdCodec<NativeId>;\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\nexport interface IdentityTables<\n Subject extends Table,\n Identifier extends Table,\n External extends Table,\n Request extends Table,\n NativeId,\n> {\n readonly constraints: RequiredIdentityConstraints;\n readonly subject: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>[\"subject\"];\n readonly identifier: SubjectProvisioningTables<\n Subject,\n Identifier,\n Request,\n NativeId\n >[\"identifier\"];\n readonly externalIdentity: ExternalIdentityTables<\n Subject,\n External,\n NativeId\n >[\"externalIdentity\"];\n readonly provisioningRequest: SubjectProvisioningTables<\n Subject,\n Identifier,\n Request,\n NativeId\n >[\"provisioningRequest\"];\n readonly subjectId: SubjectIdCodec<NativeId>;\n readonly isConstraintConflict: (cause: unknown) => boolean;\n}\n\n/** Extra encoders used by D1's ordered batch when the subject id is database-generated. */\nexport interface D1SubjectProvisioningMapping<\n Subject extends Table,\n Identifier extends Table,\n Request extends Table,\n NativeId,\n> extends SubjectProvisioningTables<Subject, Identifier, Request, NativeId> {\n readonly d1: {\n readonly requestInsertWithoutSubject: (\n requestId: string,\n fingerprint: string,\n ) => Partial<InferInsertModel<Request>>;\n readonly identifierInsertWithoutSubject: (\n identifier: LoginIdentifier,\n verifiedAt: DateTime.Utc | undefined,\n ) => Partial<InferInsertModel<Identifier>>;\n /** Unshadowed hidden-rowid alias; omit for WITHOUT ROWID or preallocated IDs. */\n readonly generatedRowIdAlias?: \"rowid\" | \"_rowid_\" | \"oid\";\n };\n}\n\nexport interface D1ExternalIdentityMapping<\n Subject extends Table,\n External extends Table,\n NativeId,\n> extends ExternalIdentityTables<Subject, External, NativeId> {\n readonly d1: {\n readonly activeStatusValue: unknown;\n };\n}\n\nexport interface D1GeneratedIdentityMapping<\n Subject extends Table,\n Identifier extends Table,\n External extends Table,\n Request extends Table,\n NativeId,\n> extends IdentityTables<Subject, Identifier, External, Request, NativeId> {\n readonly d1: D1SubjectProvisioningMapping<Subject, Identifier, Request, NativeId>[\"d1\"] &\n D1ExternalIdentityMapping<Subject, External, NativeId>[\"d1\"];\n}\n\nexport const provisioningFingerprint = (input: SubjectProvisioningInput): string =>\n // oxlint-disable-next-line no-restricted-properties -- stable internal provisioning fingerprint, never external JSON.\n JSON.stringify(\n input.identifier === undefined\n ? [\"v1\", null]\n : [\n \"v1\",\n input.identifier.namespace,\n input.identifier.value,\n input.verifiedAt === undefined ? null : DateTime.toEpochMillis(input.verifiedAt),\n ],\n );\n\n/**\n * Drizzle wraps Effect SQL failures before adapters observe them. Give the\n * consumer classifier each semantic wrapper in the short `cause`/`reason`\n * chain without exposing query text or bound parameters through public errors.\n */\n\nexport const column = <T extends Table>(table: T, key: ColumnKey<T>): AnyColumn =>\n getTableColumns(table)[key] as AnyColumn;\n\nexport const updateValues = <T extends Table>(\n entries: ReadonlyArray<readonly [ColumnKey<T>, unknown]>,\n): Partial<InferInsertModel<T>> => Object.fromEntries(entries) as Partial<InferInsertModel<T>>;\n\n/** Acquire an application database in Effect and expose the identity services as one layer. */\nexport const identityServicesLayer = <E, R>(\n acquire: Effect.Effect<\n {\n readonly subjectProvisioner: SubjectProvisioner[\"Service\"];\n readonly externalIdentityMutation: ExternalIdentityMutation[\"Service\"];\n },\n E,\n R\n >,\n) =>\n Layer.effectContext(\n Effect.map(acquire, ({ subjectProvisioner, externalIdentityMutation }) =>\n Context.make(SubjectProvisioner, subjectProvisioner).pipe(\n Context.add(ExternalIdentityMutation, externalIdentityMutation),\n ),\n ),\n );\n"],"mappings":";;;;;AA2CA,MAAa,8BAA2D;CACtE,YAAY;CACZ,kBAAkB;CAClB,qBAAqB;CACrB,qBAAqB;AACvB;AAEA,MAAa,yCAAiF;CAC5F,YAAY;CACZ,qBAAqB;CACrB,qBAAqB;AACvB;AAEA,MAAa,sCAA2E,EACtF,kBAAkB,kCACpB;AAsJA,MAAa,2BAA2B,UAEtC,KAAK,UACH,MAAM,eAAe,KAAA,IACjB,CAAC,MAAM,IAAI,IACX;CACE;CACA,MAAM,WAAW;CACjB,MAAM,WAAW;CACjB,MAAM,eAAe,KAAA,IAAY,OAAO,SAAS,cAAc,MAAM,UAAU;AACjF,CACN;;;;;;AAQF,MAAa,UAA2B,OAAU,QAChD,gBAAgB,KAAK,CAAC,CAAC;AAEzB,MAAa,gBACX,YACiC,OAAO,YAAY,OAAO;;AAG7D,MAAa,yBACX,YASA,MAAM,cACJ,OAAO,IAAI,UAAU,EAAE,oBAAoB,+BACzC,QAAQ,KAAK,oBAAoB,kBAAkB,CAAC,CAAC,KACnD,QAAQ,IAAI,0BAA0B,wBAAwB,CAChE,CACF,CACF"}
|
|
@@ -7,7 +7,7 @@ import { Effect } from "effect";
|
|
|
7
7
|
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
8
8
|
import { EmailAddressPersistence, EmailUnavailable } from "@yielded/auth/Email";
|
|
9
9
|
import { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
10
|
-
import { SqlError } from "effect/
|
|
10
|
+
import { SqlError } from "effect/sql/SqlError";
|
|
11
11
|
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
12
12
|
//#region src/drizzle/mysql-emails.d.ts
|
|
13
13
|
type Database = EffectMysql2Database<AnyRelations>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql-emails.mjs","names":[],"sources":["../../src/drizzle/mysql-emails.ts"],"sourcesContent":["import { EmailAddressPersistence, type EmailUnavailable } from \"@yielded/auth/Email\";\nimport type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\n/* oxlint-disable no-explicit-any -- proof mapping tables are independently typed by the proof owner; this driver forwards them unchanged to the shared target. */\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport type {\n EmailAddressMapping,\n EmailRegistrationMapping,\n EmailSignInMapping,\n} from \"./email-model\";\nimport type { EmailRegistrationAuthority } from \"./email-registration\";\nimport type { EmailSqlQuery } from \"./email-sql\";\nimport {\n coordinateTargetEmailAddress,\n coordinateTargetEmailRegistration,\n makeTargetEmailAddressServices,\n makeTargetEmailRegistrationServices,\n makeTargetEmailSignInServices,\n sqlClientEmailStandaloneGuard,\n} from \"./email-target\";\nimport type { ProofPersistenceMapping } from \"./proof-model\";\nimport type { ProofSqlQuery } from \"./proof-sql\";\nimport { sqlClientProofStandaloneGuard } from \"./proof-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = EffectMysql2Database<AnyRelations>;\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\ntype ProofMapping = ProofPersistenceMapping<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>;\n\nconst configuration = (database: Database) => ({\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientEmailStandaloneGuard(database),\n generatedSubjectRows: (query: EmailSqlQuery) => query.$returningId(),\n proof: {\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientProofStandaloneGuard(database),\n insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),\n },\n});\n\nexport const makeMysqlEmailSignInServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: EmailSignInMapping<S, I, C, NativeId>,\n) => makeTargetEmailSignInServices(database, mapping, configuration(database));\n\nexport const makeMysqlEmailAddressServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>,\n proofMapping: ProofMapping,\n) => makeTargetEmailAddressServices(database, mapping, proofMapping, configuration(database));\n\nexport function coordinateMysqlEmailAddress<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, EmailAddressPersistence> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailAddress<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, EmailAddressPersistence | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailAddress<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, EmailAddressPersistence> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetEmailAddress<TransactionOf<D>, Out, E, Exclude<R, EmailAddressPersistence>>(\n database,\n options.mapping,\n options.proofMapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly emailAddressPersistence: EmailAddressPersistence[\"Service\"] },\n ) => {\n const provided = Context.make(EmailAddressPersistence, services.emailAddressPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport const makeMysqlEmailRegistrationServices = <\n Registration,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: EmailRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,\n proofMapping: ProofMapping,\n) =>\n makeTargetEmailRegistrationServices<Registration>(\n database,\n mapping,\n proofMapping,\n configuration(database),\n );\n\nexport function coordinateMysqlEmailRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly target: SuppliedService<TargetId, EmailRegistrationAuthority<Registration>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly target: SuppliedService<TargetId, EmailRegistrationAuthority<Registration>>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly target: SuppliedService<TargetId, EmailRegistrationAuthority<Registration>>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetEmailRegistration<Registration, TransactionOf<D>, Out, E, Exclude<R, TargetId>>(\n database,\n options.mapping,\n options.proofMapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },\n ) => {\n const provided = Context.make(options.target, services.registrationAuthority);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n"],"mappings":";;;;;AA8CA,MAAM,iBAAiB,cAAwB;CAC7C,MAAM;CACN,SAAS;CACT,iBAAiB,8BAA8B,QAAQ;CACvD,uBAAuB,UAAyB,MAAM,aAAa;CACnE,OAAO;EACL,MAAM;EACN,SAAS;EACT,iBAAiB,8BAA8B,QAAQ;EACvD,iBAAiB,OAAsB,SAAiB,cACtD,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,UAAU,EAAE,CAAC;CAChE;AACF;AAEA,MAAa,gCAMX,UACA,YACG,8BAA8B,UAAU,SAAS,cAAc,QAAQ,CAAC;AAE7E,MAAa,iCAQX,UACA,SACA,iBACG,+BAA+B,UAAU,SAAS,cAAc,cAAc,QAAQ,CAAC;AA0D5F,SAAgB,4BAgBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,6BACE,UACA,QAAQ,SACR,QAAQ,cACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,yBAAyB,SAAS,uBAAuB;EACvF,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAEA,MAAa,sCASX,UACA,SACA,iBAEA,oCACE,UACA,SACA,cACA,cAAc,QAAQ,CACxB;AAgEF,SAAgB,iCAkBd,SACA,SAMA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,kCACE,UACA,QAAQ,SACR,QAAQ,cACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,qBAAqB;EAC5E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"mysql-emails.mjs","names":[],"sources":["../../src/drizzle/mysql-emails.ts"],"sourcesContent":["import { EmailAddressPersistence, type EmailUnavailable } from \"@yielded/auth/Email\";\nimport type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\n/* oxlint-disable no-explicit-any -- proof mapping tables are independently typed by the proof owner; this driver forwards them unchanged to the shared target. */\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport type {\n EmailAddressMapping,\n EmailRegistrationMapping,\n EmailSignInMapping,\n} from \"./email-model\";\nimport type { EmailRegistrationAuthority } from \"./email-registration\";\nimport type { EmailSqlQuery } from \"./email-sql\";\nimport {\n coordinateTargetEmailAddress,\n coordinateTargetEmailRegistration,\n makeTargetEmailAddressServices,\n makeTargetEmailRegistrationServices,\n makeTargetEmailSignInServices,\n sqlClientEmailStandaloneGuard,\n} from \"./email-target\";\nimport type { ProofPersistenceMapping } from \"./proof-model\";\nimport type { ProofSqlQuery } from \"./proof-sql\";\nimport { sqlClientProofStandaloneGuard } from \"./proof-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = EffectMysql2Database<AnyRelations>;\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\ntype ProofMapping = ProofPersistenceMapping<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>;\n\nconst configuration = (database: Database) => ({\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientEmailStandaloneGuard(database),\n generatedSubjectRows: (query: EmailSqlQuery) => query.$returningId(),\n proof: {\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientProofStandaloneGuard(database),\n insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),\n },\n});\n\nexport const makeMysqlEmailSignInServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: EmailSignInMapping<S, I, C, NativeId>,\n) => makeTargetEmailSignInServices(database, mapping, configuration(database));\n\nexport const makeMysqlEmailAddressServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>,\n proofMapping: ProofMapping,\n) => makeTargetEmailAddressServices(database, mapping, proofMapping, configuration(database));\n\nexport function coordinateMysqlEmailAddress<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, EmailAddressPersistence> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailAddress<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, EmailAddressPersistence | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailAddress<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, EmailAddressPersistence> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetEmailAddress<TransactionOf<D>, Out, E, Exclude<R, EmailAddressPersistence>>(\n database,\n options.mapping,\n options.proofMapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly emailAddressPersistence: EmailAddressPersistence[\"Service\"] },\n ) => {\n const provided = Context.make(EmailAddressPersistence, services.emailAddressPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport const makeMysqlEmailRegistrationServices = <\n Registration,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: EmailRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,\n proofMapping: ProofMapping,\n) =>\n makeTargetEmailRegistrationServices<Registration>(\n database,\n mapping,\n proofMapping,\n configuration(database),\n );\n\nexport function coordinateMysqlEmailRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly target: SuppliedService<TargetId, EmailRegistrationAuthority<Registration>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly target: SuppliedService<TargetId, EmailRegistrationAuthority<Registration>>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlEmailRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: EmailRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly proofMapping: ProofMapping;\n readonly target: SuppliedService<TargetId, EmailRegistrationAuthority<Registration>>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | EmailUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetEmailRegistration<Registration, TransactionOf<D>, Out, E, Exclude<R, TargetId>>(\n database,\n options.mapping,\n options.proofMapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },\n ) => {\n const provided = Context.make(options.target, services.registrationAuthority);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n"],"mappings":";;;;;AA8CA,MAAM,iBAAiB,cAAwB;CAC7C,MAAM;CACN,SAAS;CACT,iBAAiB,8BAA8B,QAAQ;CACvD,uBAAuB,UAAyB,MAAM,aAAa;CACnE,OAAO;EACL,MAAM;EACN,SAAS;EACT,iBAAiB,8BAA8B,QAAQ;EACvD,iBAAiB,OAAsB,SAAiB,cACtD,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,UAAU,EAAE,CAAC;CAChE;AACF;AAEA,MAAa,gCAMX,UACA,YACG,8BAA8B,UAAU,SAAS,cAAc,QAAQ,CAAC;AAE7E,MAAa,iCAQX,UACA,SACA,iBACG,+BAA+B,UAAU,SAAS,cAAc,cAAc,QAAQ,CAAC;AA0D5F,SAAgB,4BAgBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,6BACE,UACA,QAAQ,SACR,QAAQ,cACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,yBAAyB,SAAS,uBAAuB;EACvF,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAEA,MAAa,sCASX,UACA,SACA,iBAEA,oCACE,UACA,SACA,cACA,cAAc,QAAQ,CACxB;AAgEF,SAAgB,iCAkBd,SACA,SAMA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,kCACE,UACA,QAAQ,SACR,QAAQ,cACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,qBAAqB;EAC5E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ExternalIdentityTables, SubjectProvisioningTables } from "./model.mjs";
|
|
2
2
|
import { ExternalIdentity, IdentityConflict, IdentityUnavailable, SubjectProvisioningInput } from "@yielded/auth/Identity";
|
|
3
|
-
import { SubjectId } from "@yielded/auth/Schema";
|
|
4
3
|
import { AnyRelations } from "drizzle-orm";
|
|
5
4
|
import { Effect } from "effect";
|
|
5
|
+
import { SubjectId } from "@yielded/auth/Schema";
|
|
6
6
|
import { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
7
7
|
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
8
8
|
//#region src/drizzle/mysql-identity.d.ts
|
|
@@ -5,7 +5,7 @@ import { Effect } from "effect";
|
|
|
5
5
|
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
6
6
|
import { PasswordPreparedPersistence, PasswordUnavailable } from "@yielded/auth/Password";
|
|
7
7
|
import { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
8
|
-
import { SqlError } from "effect/
|
|
8
|
+
import { SqlError } from "effect/sql/SqlError";
|
|
9
9
|
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
10
10
|
//#region src/drizzle/mysql-password-prepared.d.ts
|
|
11
11
|
type Database = EffectMysql2Database<AnyRelations>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql-password-prepared.mjs","names":[],"sources":["../../src/drizzle/mysql-password-prepared.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport type { PasswordUnavailable, PasswordPreparedPersistence } from \"@yielded/auth/Password\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/
|
|
1
|
+
{"version":3,"file":"mysql-password-prepared.mjs","names":[],"sources":["../../src/drizzle/mysql-password-prepared.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport type { PasswordUnavailable, PasswordPreparedPersistence } from \"@yielded/auth/Password\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { mysqlPasswordConfiguration as configuration } from \"./mysql-passwords\";\nimport type {\n PasswordPreparedPersistenceMapping,\n PasswordPreparedProofMapping,\n} from \"./password-prepared-model\";\nimport {\n makeTargetPasswordPreparedPersistenceServices,\n coordinateTargetPasswordPreparedPersistence,\n} from \"./password-prepared-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\ntype Database = EffectMysql2Database<AnyRelations>;\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nexport const makeMySqlPasswordPreparedPersistenceServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n T extends AnyMySqlTable,\n B extends AnyMySqlTable,\n NativeId,\n PS extends AnyMySqlTable = AnyMySqlTable,\n PC extends AnyMySqlTable = AnyMySqlTable,\n PM extends AnyMySqlTable = AnyMySqlTable,\n PSub extends AnyMySqlTable = AnyMySqlTable,\n PI extends AnyMySqlTable = AnyMySqlTable,\n PCr extends AnyMySqlTable = AnyMySqlTable,\n PNativeId = unknown,\n>(\n database: Database,\n mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>,\n proofMapping?: PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>,\n) =>\n makeTargetPasswordPreparedPersistenceServices(\n database,\n mapping,\n configuration(database),\n proofMapping,\n );\n\nexport function coordinateMySqlPasswordPreparedPersistence<\n TargetId,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n T extends AnyMySqlTable,\n B extends AnyMySqlTable,\n NativeId,\n PS extends AnyMySqlTable,\n PC extends AnyMySqlTable,\n PM extends AnyMySqlTable,\n PSub extends AnyMySqlTable,\n PI extends AnyMySqlTable,\n PCr extends AnyMySqlTable,\n PNativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>;\n readonly proofMapping?:\n | PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>\n | undefined;\n readonly target: SuppliedService<TargetId, PasswordPreparedPersistence>;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMySqlPasswordPreparedPersistence<\n TargetId,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n T extends AnyMySqlTable,\n B extends AnyMySqlTable,\n NativeId,\n PS extends AnyMySqlTable,\n PC extends AnyMySqlTable,\n PM extends AnyMySqlTable,\n PSub extends AnyMySqlTable,\n PI extends AnyMySqlTable,\n PCr extends AnyMySqlTable,\n PNativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>;\n readonly proofMapping?:\n | PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>\n | undefined;\n readonly target: SuppliedService<TargetId, PasswordPreparedPersistence>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMySqlPasswordPreparedPersistence<\n TargetId,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n T extends AnyMySqlTable,\n B extends AnyMySqlTable,\n NativeId,\n PS extends AnyMySqlTable,\n PC extends AnyMySqlTable,\n PM extends AnyMySqlTable,\n PSub extends AnyMySqlTable,\n PI extends AnyMySqlTable,\n PCr extends AnyMySqlTable,\n PNativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>;\n readonly proofMapping?:\n | PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>\n | undefined;\n readonly target: SuppliedService<TargetId, PasswordPreparedPersistence>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetPasswordPreparedPersistence<TransactionOf<D>, Out, E, Exclude<R, TargetId>>(\n database,\n options.mapping,\n configuration(database),\n options.proofMapping,\n (\n transaction: TransactionOf<D>,\n services: { readonly passwordPreparedPersistence: PasswordPreparedPersistence },\n ) => {\n const provided = Context.make(options.target, services.passwordPreparedPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n"],"mappings":";;;;AAqBA,MAAa,gDAoBX,UACA,SACA,iBAEA,8CACE,UACA,SACA,cAAc,QAAQ,GACtB,YACF;AA0FF,SAAgB,2CA6Bd,SACA,SAQA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,4CACE,UACA,QAAQ,SACR,cAAc,QAAQ,GACtB,QAAQ,eAEN,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,2BAA2B;EAClF,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
@@ -9,7 +9,7 @@ import { Effect } from "effect";
|
|
|
9
9
|
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
10
10
|
import { PasswordPersistence, PasswordUnavailable } from "@yielded/auth/Password";
|
|
11
11
|
import { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
12
|
-
import { SqlError } from "effect/
|
|
12
|
+
import { SqlError } from "effect/sql/SqlError";
|
|
13
13
|
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
14
14
|
//#region src/drizzle/mysql-passwords.d.ts
|
|
15
15
|
type Database = EffectMysql2Database<AnyRelations>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql-passwords.mjs","names":[],"sources":["../../src/drizzle/mysql-passwords.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport { type PasswordUnavailable, PasswordPersistence } from \"@yielded/auth/Password\";\n/* oxlint-disable no-explicit-any -- proof mapping tables are independently typed by the proof owner; this driver forwards them unchanged to the shared target. */\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport type { PasswordPersistenceMapping, PasswordRegistrationMapping } from \"./password-model\";\nimport type { PasswordRegistrationAuthority } from \"./password-registration\";\nimport type { PasswordSqlQuery } from \"./password-sql\";\nimport {\n coordinateTargetPasswordPersistence,\n coordinateTargetPasswordRegistration,\n makeTargetPasswordPersistenceServices,\n makeTargetPasswordRegistrationServices,\n sqlClientPasswordStandaloneGuard,\n} from \"./password-target\";\nimport type { ProofPersistenceMapping } from \"./proof-model\";\nimport type { ProofSqlQuery } from \"./proof-sql\";\nimport { sqlClientProofStandaloneGuard } from \"./proof-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = EffectMysql2Database<AnyRelations>;\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nconst configuration = (database: Database) => ({\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientPasswordStandaloneGuard(database),\n insertIfAbsent: (query: PasswordSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),\n generatedSubjectRows: (query: PasswordSqlQuery) => query.$returningId(),\n proof: {\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientProofStandaloneGuard(database),\n insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),\n },\n});\n\ntype Mapping<\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n> = PasswordPersistenceMapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n\nexport const makeMysqlPasswordPersistenceServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>,\n proofMapping?: ProofPersistenceMapping<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n) =>\n makeTargetPasswordPersistenceServices(database, mapping, configuration(database), proofMapping);\n\nexport function coordinateMysqlPasswordPersistence<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n PM extends\n | ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>\n | undefined,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n readonly proofMapping?: PM;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PasswordPersistence> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordPersistence<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n PM extends\n | ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>\n | undefined,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n readonly proofMapping?: PM;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PasswordPersistence | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordPersistence<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n PM extends\n | ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>\n | undefined,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n readonly proofMapping?: PM;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PasswordPersistence> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetPasswordPersistence<TransactionOf<D>, Out, E, Exclude<R, PasswordPersistence>>(\n database,\n options.mapping,\n configuration(database),\n options.proofMapping,\n (\n transaction: TransactionOf<D>,\n services: { readonly passwordPersistence: PasswordPersistence[\"Service\"] },\n ) => {\n const provided = Context.make(PasswordPersistence, services.passwordPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport const makeMysqlPasswordRegistrationServices = <\n Registration,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: PasswordRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,\n) =>\n makeTargetPasswordRegistrationServices<Registration>(database, mapping, configuration(database));\n\nexport function coordinateMysqlPasswordRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetPasswordRegistration<\n Registration,\n TransactionOf<D>,\n Out,\n E,\n Exclude<R, TargetId>\n >(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },\n ) => {\n const provided = Context.make(options.target, services.registrationAuthority);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport { configuration as mysqlPasswordConfiguration };\n"],"mappings":";;;;;AA2BA,MAAM,iBAAiB,cAAwB;CAC7C,MAAM;CACN,SAAS;CACT,iBAAiB,iCAAiC,QAAQ;CAC1D,iBAAiB,OAAyB,SAAiB,cACzD,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,UAAU,EAAE,CAAC;CAC9D,uBAAuB,UAA4B,MAAM,aAAa;CACtE,OAAO;EACL,MAAM;EACN,SAAS;EACT,iBAAiB,8BAA8B,QAAQ;EACvD,iBAAiB,OAAsB,SAAiB,cACtD,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,UAAU,EAAE,CAAC;CAChE;AACF;AAcA,MAAa,wCAWX,UACA,SACA,iBAeA,sCAAsC,UAAU,SAAS,cAAc,QAAQ,GAAG,YAAY;AAsEhG,SAAgB,mCAsBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,oCACE,UACA,QAAQ,SACR,cAAc,QAAQ,GACtB,QAAQ,eAEN,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,qBAAqB,SAAS,mBAAmB;EAC/E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAEA,MAAa,yCASX,UACA,YAEA,uCAAqD,UAAU,SAAS,cAAc,QAAQ,CAAC;AA8DjG,SAAgB,oCAkBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,qCAOE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,qBAAqB;EAC5E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"mysql-passwords.mjs","names":[],"sources":["../../src/drizzle/mysql-passwords.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport { type PasswordUnavailable, PasswordPersistence } from \"@yielded/auth/Password\";\n/* oxlint-disable no-explicit-any -- proof mapping tables are independently typed by the proof owner; this driver forwards them unchanged to the shared target. */\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport type { PasswordPersistenceMapping, PasswordRegistrationMapping } from \"./password-model\";\nimport type { PasswordRegistrationAuthority } from \"./password-registration\";\nimport type { PasswordSqlQuery } from \"./password-sql\";\nimport {\n coordinateTargetPasswordPersistence,\n coordinateTargetPasswordRegistration,\n makeTargetPasswordPersistenceServices,\n makeTargetPasswordRegistrationServices,\n sqlClientPasswordStandaloneGuard,\n} from \"./password-target\";\nimport type { ProofPersistenceMapping } from \"./proof-model\";\nimport type { ProofSqlQuery } from \"./proof-sql\";\nimport { sqlClientProofStandaloneGuard } from \"./proof-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = EffectMysql2Database<AnyRelations>;\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nconst configuration = (database: Database) => ({\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientPasswordStandaloneGuard(database),\n insertIfAbsent: (query: PasswordSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),\n generatedSubjectRows: (query: PasswordSqlQuery) => query.$returningId(),\n proof: {\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientProofStandaloneGuard(database),\n insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({ set: { [selfKey]: selfValue } }),\n },\n});\n\ntype Mapping<\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n> = PasswordPersistenceMapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n\nexport const makeMysqlPasswordPersistenceServices = <\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>,\n proofMapping?: ProofPersistenceMapping<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >,\n) =>\n makeTargetPasswordPersistenceServices(database, mapping, configuration(database), proofMapping);\n\nexport function coordinateMysqlPasswordPersistence<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n PM extends\n | ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>\n | undefined,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n readonly proofMapping?: PM;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PasswordPersistence> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordPersistence<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n PM extends\n | ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>\n | undefined,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n readonly proofMapping?: PM;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PasswordPersistence | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordPersistence<\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n A extends AnyMySqlTable,\n RS extends AnyMySqlTable,\n CE extends AnyMySqlTable,\n M extends AnyMySqlTable,\n NativeId,\n PM extends\n | ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>\n | undefined,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<S, I, C, AC, A, RS, CE, M, NativeId>;\n readonly proofMapping?: PM;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, PasswordPersistence> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetPasswordPersistence<TransactionOf<D>, Out, E, Exclude<R, PasswordPersistence>>(\n database,\n options.mapping,\n configuration(database),\n options.proofMapping,\n (\n transaction: TransactionOf<D>,\n services: { readonly passwordPersistence: PasswordPersistence[\"Service\"] },\n ) => {\n const provided = Context.make(PasswordPersistence, services.passwordPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport const makeMysqlPasswordRegistrationServices = <\n Registration,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: PasswordRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,\n) =>\n makeTargetPasswordRegistrationServices<Registration>(database, mapping, configuration(database));\n\nexport function coordinateMysqlPasswordRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction?: never;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlPasswordRegistration<\n TargetId,\n Registration,\n D extends Database,\n S extends AnyMySqlTable,\n I extends AnyMySqlTable,\n C extends AnyMySqlTable,\n AC extends AnyMySqlTable,\n Rq extends AnyMySqlTable,\n NativeId,\n Out,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasswordRegistrationMapping<NoInfer<Registration>, S, I, C, AC, Rq, NativeId>;\n readonly target: SuppliedService<TargetId, PasswordRegistrationAuthority<Registration>>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<Out, E, R>,\n): Effect.Effect<\n Out,\n E | PasswordUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, TargetId> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetPasswordRegistration<\n Registration,\n TransactionOf<D>,\n Out,\n E,\n Exclude<R, TargetId>\n >(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: TransactionOf<D>,\n services: { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },\n ) => {\n const provided = Context.make(options.target, services.registrationAuthority);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n\nexport { configuration as mysqlPasswordConfiguration };\n"],"mappings":";;;;;AA2BA,MAAM,iBAAiB,cAAwB;CAC7C,MAAM;CACN,SAAS;CACT,iBAAiB,iCAAiC,QAAQ;CAC1D,iBAAiB,OAAyB,SAAiB,cACzD,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,UAAU,EAAE,CAAC;CAC9D,uBAAuB,UAA4B,MAAM,aAAa;CACtE,OAAO;EACL,MAAM;EACN,SAAS;EACT,iBAAiB,8BAA8B,QAAQ;EACvD,iBAAiB,OAAsB,SAAiB,cACtD,MAAM,qBAAqB,EAAE,KAAK,GAAG,UAAU,UAAU,EAAE,CAAC;CAChE;AACF;AAcA,MAAa,wCAWX,UACA,SACA,iBAeA,sCAAsC,UAAU,SAAS,cAAc,QAAQ,GAAG,YAAY;AAsEhG,SAAgB,mCAsBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,oCACE,UACA,QAAQ,SACR,cAAc,QAAQ,GACtB,QAAQ,eAEN,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,qBAAqB,SAAS,mBAAmB;EAC/E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF;AAEA,MAAa,yCASX,UACA,YAEA,uCAAqD,UAAU,SAAS,cAAc,QAAQ,CAAC;AA8DjG,SAAgB,oCAkBd,SACA,SAKA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,qCAOE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,QAAQ,QAAQ,SAAS,qBAAqB;EAC5E,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
@@ -5,7 +5,7 @@ import { Effect } from "effect";
|
|
|
5
5
|
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
6
6
|
import { ProofPersistence, ProofUnavailable } from "@yielded/auth/Proofs";
|
|
7
7
|
import { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
8
|
-
import { SqlError } from "effect/
|
|
8
|
+
import { SqlError } from "effect/sql/SqlError";
|
|
9
9
|
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
10
10
|
//#region src/drizzle/mysql-proofs.d.ts
|
|
11
11
|
type Database = EffectMysql2Database<AnyRelations>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql-proofs.mjs","names":[],"sources":["../../src/drizzle/mysql-proofs.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport { type ProofUnavailable, ProofPersistence } from \"@yielded/auth/Proofs\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/
|
|
1
|
+
{"version":3,"file":"mysql-proofs.mjs","names":[],"sources":["../../src/drizzle/mysql-proofs.ts"],"sourcesContent":["import type { LifecycleHooks, HookConfigurationError } from \"@yielded/auth/Hooks\";\nimport { type ProofUnavailable, ProofPersistence } from \"@yielded/auth/Proofs\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable } from \"drizzle-orm/mysql-core\";\nimport { Effect, Context } from \"effect\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { updateValues } from \"./model\";\nimport type { ProofPersistenceMapping } from \"./proof-model\";\nimport type { ProofSqlQuery } from \"./proof-sql\";\nimport {\n coordinateTargetProofPersistence,\n makeTargetProofPersistenceServices,\n sqlClientProofStandaloneGuard,\n} from \"./proof-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = EffectMysql2Database<AnyRelations>;\ntype Transaction = Parameters<Parameters<Database[\"transaction\"]>[0]>[0];\ntype Mapping<\n Rq extends AnyMySqlTable,\n S extends AnyMySqlTable,\n G extends AnyMySqlTable,\n Cn extends AnyMySqlTable,\n Rs extends AnyMySqlTable,\n A extends AnyMySqlTable,\n F extends AnyMySqlTable,\n C extends AnyMySqlTable,\n Sub extends AnyMySqlTable,\n I extends AnyMySqlTable,\n Cr extends AnyMySqlTable,\n NativeId,\n> = ProofPersistenceMapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, NativeId>;\n\nconst configuration = (database: Database) => ({\n mode: \"interactive\" as const,\n locking: true,\n standaloneGuard: sqlClientProofStandaloneGuard(database),\n insertIfAbsent: (query: ProofSqlQuery, selfKey: string, selfValue: unknown) =>\n query.onDuplicateKeyUpdate({\n set: updateValues([[selfKey, selfValue]]),\n }),\n});\n\nexport const makeMysqlProofPersistenceServices = <\n Rq extends AnyMySqlTable,\n S extends AnyMySqlTable,\n G extends AnyMySqlTable,\n Cn extends AnyMySqlTable,\n Rs extends AnyMySqlTable,\n A extends AnyMySqlTable,\n F extends AnyMySqlTable,\n C extends AnyMySqlTable,\n Sub extends AnyMySqlTable,\n I extends AnyMySqlTable,\n Cr extends AnyMySqlTable,\n NativeId,\n>(\n database: Database,\n mapping: Mapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, NativeId>,\n) => makeTargetProofPersistenceServices(database, mapping, configuration(database));\n\nexport function coordinateMysqlProofPersistence<\n D extends Database,\n Rq extends AnyMySqlTable,\n S extends AnyMySqlTable,\n G extends AnyMySqlTable,\n Cn extends AnyMySqlTable,\n Rs extends AnyMySqlTable,\n Aev extends AnyMySqlTable,\n F extends AnyMySqlTable,\n C extends AnyMySqlTable,\n Sub extends AnyMySqlTable,\n I extends AnyMySqlTable,\n Cr extends AnyMySqlTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<Rq, S, G, Cn, Rs, Aev, F, C, Sub, I, Cr, NativeId>;\n readonly transaction?: never;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | ProofUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, ProofPersistence> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlProofPersistence<\n D extends Database,\n Rq extends AnyMySqlTable,\n S extends AnyMySqlTable,\n G extends AnyMySqlTable,\n Cn extends AnyMySqlTable,\n Rs extends AnyMySqlTable,\n Aev extends AnyMySqlTable,\n F extends AnyMySqlTable,\n C extends AnyMySqlTable,\n Sub extends AnyMySqlTable,\n I extends AnyMySqlTable,\n Cr extends AnyMySqlTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<Rq, S, G, Cn, Rs, Aev, F, C, Sub, I, Cr, NativeId>;\n readonly transaction: SuppliedService<TxId, NoInfer<Transaction>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | ProofUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, ProofPersistence | TxId> | LifecycleHooks | DatabaseRequirements\n>;\n\nexport function coordinateMysqlProofPersistence<\n D extends Database,\n Rq extends AnyMySqlTable,\n S extends AnyMySqlTable,\n G extends AnyMySqlTable,\n Cn extends AnyMySqlTable,\n Rs extends AnyMySqlTable,\n Aev extends AnyMySqlTable,\n F extends AnyMySqlTable,\n C extends AnyMySqlTable,\n Sub extends AnyMySqlTable,\n I extends AnyMySqlTable,\n Cr extends AnyMySqlTable,\n NativeId,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: Mapping<Rq, S, G, Cn, Rs, Aev, F, C, Sub, I, Cr, NativeId>;\n readonly transaction?: SuppliedService<TxId, NoInfer<Transaction>, TxShape>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n E | ProofUnavailable | HookConfigurationError | SqlError | DatabaseError,\n Exclude<R, ProofPersistence> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(acquire, (database) =>\n coordinateTargetProofPersistence<Transaction, A, E, Exclude<R, ProofPersistence>>(\n database,\n options.mapping,\n configuration(database),\n (\n transaction: Transaction,\n services: { readonly proofPersistence: ProofPersistence[\"Service\"] },\n ) => {\n const provided = Context.make(ProofPersistence, services.proofPersistence);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(work, options.transaction, options.transaction.of(transaction));\n },\n ),\n );\n}\n"],"mappings":";;;;;AAmCA,MAAM,iBAAiB,cAAwB;CAC7C,MAAM;CACN,SAAS;CACT,iBAAiB,8BAA8B,QAAQ;CACvD,iBAAiB,OAAsB,SAAiB,cACtD,MAAM,qBAAqB,EACzB,KAAK,aAAa,CAAC,CAAC,SAAS,SAAS,CAAC,CAAC,EAC1C,CAAC;AACL;AAEA,MAAa,qCAcX,UACA,YACG,mCAAmC,UAAU,SAAS,cAAc,QAAQ,CAAC;AAoElF,SAAgB,gCAsBd,SACA,SAIA,MAKA;CACA,OAAO,OAAO,QAAQ,UAAU,aAC9B,iCACE,UACA,QAAQ,SACR,cAAc,QAAQ,IAEpB,aACA,aACG;EACH,MAAM,WAAW,QAAQ,KAAK,kBAAkB,SAAS,gBAAgB;EACzE,MAAM,OAAO,OAAO,eAAe,MAAM,QAAQ;EAEjD,OAAO,QAAQ,gBAAgB,KAAA,IAC3B,OACA,OAAO,eAAe,MAAM,QAAQ,aAAa,QAAQ,YAAY,GAAG,WAAW,CAAC;CAC1F,CACF,CACF;AACF"}
|
|
@@ -6,7 +6,7 @@ import { Context, Effect } from "effect";
|
|
|
6
6
|
import { HookConfigurationError, LifecycleHooks } from "@yielded/auth/Hooks";
|
|
7
7
|
import { AuthenticationAuthority, PendingAuthentication, SessionRepository, SessionStepUpPersistence, SessionUnavailable, SignedSessionValidity, StatefulSessionPersistence } from "@yielded/auth/Sessions";
|
|
8
8
|
import { EffectMysql2Database } from "drizzle-orm/effect-mysql2";
|
|
9
|
-
import { SqlError } from "effect/
|
|
9
|
+
import { SqlError } from "effect/sql/SqlError";
|
|
10
10
|
import { AnyMySqlTable } from "drizzle-orm/mysql-core";
|
|
11
11
|
//#region src/drizzle/mysql-sessions.d.ts
|
|
12
12
|
type Database = EffectMysql2Database<AnyRelations>;
|