@yielded/auth-persistence-drizzle 0.1.0-beta.18 → 0.1.0-beta.20
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 +8 -1
- package/dist/D1.d.mts +8 -8
- package/dist/Libsql.d.mts +38 -38
- package/dist/Mysql2.d.mts +51 -51
- package/dist/Pglite.d.mts +51 -51
- package/dist/Postgres.d.mts +38 -38
- package/dist/SqliteBun.d.mts +51 -51
- package/dist/SqliteDo.d.mts +112 -134
- package/dist/SqliteDo.mjs +30 -45
- package/dist/SqliteDo.mjs.map +1 -1
- package/dist/SqliteNode.d.mts +44 -44
- package/dist/SqliteWasm.d.mts +38 -38
- package/dist/drizzle/crypto.mjs +11 -0
- package/dist/drizzle/crypto.mjs.map +1 -0
- package/dist/drizzle/d1-identity.mjs +2 -2
- package/dist/drizzle/d1-identity.mjs.map +1 -1
- package/dist/drizzle/d1-oauth.d.mts +11 -11
- package/dist/drizzle/d1-oauth.mjs.map +1 -1
- package/dist/drizzle/d1-passkey.d.mts +6 -6
- package/dist/drizzle/d1-passkey.mjs.map +1 -1
- package/dist/drizzle/d1-passwords.d.mts +1 -1
- package/dist/drizzle/d1-phone.d.mts +3 -3
- package/dist/drizzle/d1-phone.mjs.map +1 -1
- package/dist/drizzle/d1-proofs.d.mts +1 -1
- package/dist/drizzle/d1-sessions.d.mts +1 -1
- package/dist/drizzle/d1-totp.d.mts +3 -3
- package/dist/drizzle/d1-totp.mjs.map +1 -1
- package/dist/drizzle/mysql-identity.mjs +2 -2
- package/dist/drizzle/mysql-identity.mjs.map +1 -1
- package/dist/drizzle/oauth-accounts.mjs +9 -8
- package/dist/drizzle/oauth-accounts.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-collection.mjs +1 -1
- package/dist/drizzle/oauth-connected-collection.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-custody.mjs +5 -4
- package/dist/drizzle/oauth-connected-custody.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-flow.mjs +8 -7
- package/dist/drizzle/oauth-connected-flow.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-management.mjs +3 -2
- package/dist/drizzle/oauth-connected-management.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-reference.mjs +8 -4
- package/dist/drizzle/oauth-connected-reference.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-settlement.mjs +4 -4
- package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-sign-in.mjs +11 -10
- package/dist/drizzle/oauth-connected-sign-in.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-state.d.mts +13 -13
- package/dist/drizzle/oauth-connected-state.mjs +23 -20
- package/dist/drizzle/oauth-connected-state.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-target.d.mts +9 -9
- package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
- package/dist/drizzle/oauth-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-flow.mjs +1 -1
- package/dist/drizzle/oauth-flow.mjs.map +1 -1
- package/dist/drizzle/oauth-model.d.mts +4 -4
- package/dist/drizzle/oauth-model.mjs.map +1 -1
- package/dist/drizzle/oauth-registration.mjs +2 -2
- package/dist/drizzle/oauth-registration.mjs.map +1 -1
- package/dist/drizzle/oauth-state.mjs +11 -12
- package/dist/drizzle/oauth-state.mjs.map +1 -1
- package/dist/drizzle/oauth-target.d.mts +4 -4
- package/dist/drizzle/oauth-target.mjs.map +1 -1
- package/dist/drizzle/passkey-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-target.d.mts +1 -1
- package/dist/drizzle/password-prepared-state.mjs +1 -1
- package/dist/drizzle/pg-identity.mjs +2 -2
- package/dist/drizzle/pg-identity.mjs.map +1 -1
- package/dist/drizzle/phone-model.d.mts +2 -2
- package/dist/drizzle/phone-model.mjs +3 -3
- package/dist/drizzle/phone-model.mjs.map +1 -1
- package/dist/drizzle/phone-target.d.mts +1 -1
- package/dist/drizzle/phone-target.mjs +2 -2
- package/dist/drizzle/phone-target.mjs.map +1 -1
- package/dist/drizzle/sqlite-do-database.d.mts +29 -0
- package/dist/drizzle/sqlite-do-database.mjs +45 -0
- package/dist/drizzle/sqlite-do-database.mjs.map +1 -0
- package/dist/drizzle/sqlite-emails.mjs.map +1 -1
- package/dist/drizzle/sqlite-identity.mjs +2 -2
- package/dist/drizzle/sqlite-identity.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/storage-validation.mjs +17 -9
- package/dist/drizzle/storage-validation.mjs.map +1 -1
- package/dist/drizzle/totp-state.mjs +8 -8
- package/dist/drizzle/totp-state.mjs.map +1 -1
- package/dist/drizzle/totp-target.d.mts +1 -1
- package/dist/drizzle/totp-target.mjs +2 -2
- package/dist/drizzle/totp-target.mjs.map +1 -1
- package/package.json +1 -1
- package/src/SqliteDo.ts +63 -70
- package/src/drizzle/crypto.ts +14 -0
- package/src/drizzle/d1-identity.ts +2 -2
- package/src/drizzle/d1-oauth.ts +14 -5
- package/src/drizzle/d1-passkey.ts +5 -1
- package/src/drizzle/d1-phone.ts +2 -1
- package/src/drizzle/d1-totp.ts +6 -2
- package/src/drizzle/mysql-identity.ts +2 -2
- package/src/drizzle/oauth-accounts.ts +14 -13
- package/src/drizzle/oauth-connected-collection.ts +1 -1
- package/src/drizzle/oauth-connected-custody.ts +8 -6
- package/src/drizzle/oauth-connected-drivers.ts +9 -3
- package/src/drizzle/oauth-connected-flow.ts +6 -6
- package/src/drizzle/oauth-connected-management.ts +1 -1
- package/src/drizzle/oauth-connected-reference.ts +14 -9
- package/src/drizzle/oauth-connected-settlement.ts +4 -4
- package/src/drizzle/oauth-connected-sign-in.ts +11 -10
- package/src/drizzle/oauth-connected-state.ts +40 -25
- package/src/drizzle/oauth-connected-target.ts +9 -5
- package/src/drizzle/oauth-drivers.ts +13 -5
- package/src/drizzle/oauth-flow.ts +1 -1
- package/src/drizzle/oauth-model.ts +4 -4
- package/src/drizzle/oauth-registration.ts +2 -2
- package/src/drizzle/oauth-state.ts +17 -15
- package/src/drizzle/oauth-target.ts +11 -3
- package/src/drizzle/passkey-drivers.ts +7 -3
- package/src/drizzle/passkey-write-drivers.ts +11 -2
- package/src/drizzle/pg-identity.ts +2 -2
- package/src/drizzle/phone-model.ts +3 -3
- package/src/drizzle/phone-target.ts +11 -4
- package/src/drizzle/sqlite-do-database.ts +87 -0
- package/src/drizzle/sqlite-emails.ts +1 -1
- package/src/drizzle/sqlite-identity.ts +2 -2
- package/src/drizzle/sqlite-passwords.ts +1 -1
- package/src/drizzle/sqlite-proofs.ts +2 -2
- package/src/drizzle/sqlite-sessions.ts +2 -2
- package/src/drizzle/storage-validation.ts +15 -6
- package/src/drizzle/totp-state.ts +8 -8
- package/src/drizzle/totp-target.ts +11 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-oauth.mjs","names":["DatabaseService"],"sources":["../../src/drizzle/d1-oauth.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n OAuthAccountsPersistence,\n OAuthRegistrationIntents,\n OAuthSignInPersistence,\n OAuthUnavailable,\n} from \"@yielded/auth/OAuth\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { Effect, Context } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport type {\n OAuthAccountsMapping,\n OAuthD1Mapping,\n OAuthRegistrationAuthority,\n OAuthRegistrationIntentMapping,\n OAuthRegistrationMapping,\n OAuthSignInMapping,\n} from \"./oauth-model\";\nimport {\n type OAuthCoordinatorError,\n coordinateTargetOAuthAccounts,\n coordinateTargetOAuthSignIn,\n coordinateTargetOAuthRegistrationIntents,\n coordinateTargetOAuthRegistration,\n makeTargetOAuthRegistrationIntentServices,\n makeTargetOAuthRegistrationServices,\n makeTargetOAuthSignInServices,\n makeTargetOAuthAccountsServices,\n} from \"./oauth-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\ntype SQLiteTable = AnySQLiteTable<{ dialect: \"sqlite\" }>;\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\nconst unavailable = () => OAuthUnavailable.make({});\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\nexport const makeD1OAuthAccountsServices = <\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n U extends SQLiteTable,\n N,\n>(\n mapping: OAuthAccountsMapping<S, O, C, AC, F, T, U, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthAccountsServices(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport const makeD1OAuthSignInServices = <\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n N,\n>(\n mapping: OAuthSignInMapping<S, O, C, AC, F, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthSignInServices(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport const makeD1OAuthRegistrationIntentServices = <\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n N,\n>(\n mapping: OAuthRegistrationIntentMapping<S, O, C, AC, F, T, I, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthRegistrationIntentServices(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport const makeD1OAuthRegistrationServices = <\n Registration,\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n R extends SQLiteTable,\n N,\n>(\n mapping: OAuthRegistrationMapping<Registration, S, O, C, AC, T, I, R, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthRegistrationServices<Registration>(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport function coordinateD1OAuthSignIn<\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthSignInMapping<S, O, C, AC, F, N> & OAuthD1Mapping },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n Exclude<R, OAuthSignInPersistence | D1BatchStatements> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthSignIn<\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, OAuthSignInPersistence | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.oauthSignInPersistence;\n\n const service: OAuthSignInPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(OAuthSignInPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinateD1OAuthRegistrationIntents<\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthRegistrationIntentMapping<S, O, C, AC, F, T, I, N> & OAuthD1Mapping;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n Exclude<R, OAuthRegistrationIntents | D1BatchStatements> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthRegistrationIntents<\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, OAuthRegistrationIntents | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.oauthRegistrationIntents;\n\n const service: OAuthRegistrationIntents[\"Service\"] = {\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n };\n\n const provided = Context.make(OAuthRegistrationIntents, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinateD1OAuthAccounts<\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n U extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthAccountsMapping<S, O, C, AC, F, T, U, N> & OAuthD1Mapping },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n Exclude<R, OAuthAccountsPersistence | D1BatchStatements> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthAccounts<\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, OAuthAccountsPersistence | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.oauthAccountsPersistence;\n\n const service: OAuthAccountsPersistence[\"Service\"] = {\n capture: (input) => owner.run(original.capture(input)),\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n preflight: (input) => owner.run(original.preflight(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n inspectUnlink: (input) => owner.run(original.inspectUnlink(input)),\n unlink: (input, prepare) => owner.run(original.unlink(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(OAuthAccountsPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinateD1OAuthRegistration<\n TargetId,\n Registration,\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n Rq extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthRegistrationMapping<NoInfer<Registration>, S, O, C, AC, T, I, Rq, N> &\n OAuthD1Mapping;\n readonly target: SuppliedService<TargetId, OAuthRegistrationAuthority<Registration>>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n Exclude<R, TargetId | D1BatchStatements> | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthRegistration<\n Registration,\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, TargetId | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.registrationAuthority;\n\n const service: OAuthRegistrationAuthority<Registration> = {\n read: (input) => owner.run(original.read(input)),\n inspect: (input) => owner.run(original.inspect(input)),\n register: (input, prepare) => owner.run(original.register(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(options.target, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"d1-oauth.mjs","names":["DatabaseService"],"sources":["../../src/drizzle/d1-oauth.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n OAuthAccountsPersistence,\n OAuthRegistrationIntents,\n OAuthSignInPersistence,\n OAuthUnavailable,\n} from \"@yielded/auth/OAuth\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { type Crypto, Effect, Context } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport type {\n OAuthAccountsMapping,\n OAuthD1Mapping,\n OAuthRegistrationAuthority,\n OAuthRegistrationIntentMapping,\n OAuthRegistrationMapping,\n OAuthSignInMapping,\n} from \"./oauth-model\";\nimport {\n type OAuthCoordinatorError,\n coordinateTargetOAuthAccounts,\n coordinateTargetOAuthSignIn,\n coordinateTargetOAuthRegistrationIntents,\n coordinateTargetOAuthRegistration,\n makeTargetOAuthRegistrationIntentServices,\n makeTargetOAuthRegistrationServices,\n makeTargetOAuthSignInServices,\n makeTargetOAuthAccountsServices,\n} from \"./oauth-target\";\nimport type { SuppliedService } from \"./SuppliedService\";\ntype SQLiteTable = AnySQLiteTable<{ dialect: \"sqlite\" }>;\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\nconst unavailable = () => OAuthUnavailable.make({});\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\nexport const makeD1OAuthAccountsServices = <\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n U extends SQLiteTable,\n N,\n>(\n mapping: OAuthAccountsMapping<S, O, C, AC, F, T, U, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthAccountsServices(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport const makeD1OAuthSignInServices = <\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n N,\n>(\n mapping: OAuthSignInMapping<S, O, C, AC, F, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthSignInServices(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport const makeD1OAuthRegistrationIntentServices = <\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n N,\n>(\n mapping: OAuthRegistrationIntentMapping<S, O, C, AC, F, T, I, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthRegistrationIntentServices(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport const makeD1OAuthRegistrationServices = <\n Registration,\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n R extends SQLiteTable,\n N,\n>(\n mapping: OAuthRegistrationMapping<Registration, S, O, C, AC, T, I, R, N> & OAuthD1Mapping,\n) =>\n makeTargetOAuthRegistrationServices<Registration>(mapping, configuration).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n );\n\nexport function coordinateD1OAuthSignIn<\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthSignInMapping<S, O, C, AC, F, N> & OAuthD1Mapping },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n | Exclude<R, OAuthSignInPersistence | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthSignIn<\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, OAuthSignInPersistence | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.oauthSignInPersistence;\n\n const service: OAuthSignInPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(OAuthSignInPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinateD1OAuthRegistrationIntents<\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthRegistrationIntentMapping<S, O, C, AC, F, T, I, N> & OAuthD1Mapping;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n | Exclude<R, OAuthRegistrationIntents | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthRegistrationIntents<\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, OAuthRegistrationIntents | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.oauthRegistrationIntents;\n\n const service: OAuthRegistrationIntents[\"Service\"] = {\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n };\n\n const provided = Context.make(OAuthRegistrationIntents, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinateD1OAuthAccounts<\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n F extends SQLiteTable,\n T extends SQLiteTable,\n U extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthAccountsMapping<S, O, C, AC, F, T, U, N> & OAuthD1Mapping },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n | Exclude<R, OAuthAccountsPersistence | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthAccounts<\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, OAuthAccountsPersistence | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.oauthAccountsPersistence;\n\n const service: OAuthAccountsPersistence[\"Service\"] = {\n capture: (input) => owner.run(original.capture(input)),\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n preflight: (input) => owner.run(original.preflight(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n inspectUnlink: (input) => owner.run(original.inspectUnlink(input)),\n unlink: (input, prepare) => owner.run(original.unlink(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(OAuthAccountsPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinateD1OAuthRegistration<\n TargetId,\n Registration,\n S extends SQLiteTable,\n O extends SQLiteTable,\n C extends SQLiteTable,\n AC extends SQLiteTable,\n T extends SQLiteTable,\n I extends SQLiteTable,\n Rq extends SQLiteTable,\n N,\n A,\n E,\n R,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthRegistrationMapping<NoInfer<Registration>, S, O, C, AC, T, I, Rq, N> &\n OAuthD1Mapping;\n readonly target: SuppliedService<TargetId, OAuthRegistrationAuthority<Registration>>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n OAuthCoordinatorError<E> | DatabaseError,\n Exclude<R, TargetId | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | DatabaseRequirements\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetOAuthRegistration<\n Registration,\n never,\n A,\n E | OAuthUnavailable,\n Exclude<R, TargetId | D1BatchStatements>\n >(database, options.mapping, configuration, (_transaction, services, append) =>\n Effect.gen(function* () {\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const original = services.registrationAuthority;\n\n const service: OAuthRegistrationAuthority<Registration> = {\n read: (input) => owner.run(original.read(input)),\n inspect: (input) => owner.run(original.inspect(input)),\n register: (input, prepare) => owner.run(original.register(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(options.target, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { D1BatchStatements } from "./D1BatchStatements.mjs";
|
|
|
6
6
|
import { PasskeyCoordinatorError } from "./passkey-target.mjs";
|
|
7
7
|
import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
|
|
8
8
|
import { AnyRelations } from "drizzle-orm";
|
|
9
|
-
import { Context, Effect } from "effect";
|
|
9
|
+
import { Context, Crypto, Effect } from "effect";
|
|
10
10
|
import { LifecycleHooks } from "@yielded/auth/Hooks";
|
|
11
11
|
import { EffectSQLiteD1Database } from "drizzle-orm/effect-d1";
|
|
12
12
|
import { PasskeyManagementPersistence, PasskeyPersistence } from "@yielded/auth/Passkey";
|
|
@@ -19,19 +19,19 @@ type Table$1 = AnySQLiteTable<{
|
|
|
19
19
|
type Database = EffectSQLiteD1Database<AnyRelations> & {
|
|
20
20
|
readonly $client: D1Client;
|
|
21
21
|
};
|
|
22
|
-
export declare const makePasskeyCredentialServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyCredentialMapping<S, C, F, O, H, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyCredentialServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Database$1 | Exclude<RSetup, NativeDatabase>>, makePasskeyEnrollmentContextServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyEnrollmentContextMapping<PasskeyCredentialMapping<S, C, F, O, H, N>, M, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyEnrollmentContextServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Database$1 | Exclude<RSetup, NativeDatabase>>, makePasskeyPersistenceServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyPersistenceMapping<PasskeyCredentialMapping<S, C, F, O, H, N>, M, Flow, Admission, Charge, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyPersistenceServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>, makePasskeyRegistrationCeremonyServices: <M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Intent extends Table$1, H extends Table$1, RSetup = never>(mapping: PasskeyMappingSource<PasskeyRegistrationCeremonyMapping<M, Flow, Admission, Charge, Intent, H> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyRegistrationCeremonyServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>, makePasskeyManagementServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Command extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyManagementMapping<S, C, F, O, H, M, Flow, Admission, Charge, Command, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyManagementServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>, makePasskeyRegistrationServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Intent extends Table$1, N, Value, RSetup = never>(mapping: PasskeyMappingSource<PasskeyRegistrationMapping<S, C, F, O, H, M, Flow, Admission, Charge, Intent, N, Value> & D1PasskeyMapping, RSetup>) => Effect.Effect<PasskeyRegistrationServices<Value>, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
|
|
22
|
+
export declare const makePasskeyCredentialServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyCredentialMapping<S, C, F, O, H, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyCredentialServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Crypto.Crypto | Database$1 | Exclude<RSetup, NativeDatabase>>, makePasskeyEnrollmentContextServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyEnrollmentContextMapping<PasskeyCredentialMapping<S, C, F, O, H, N>, M, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyEnrollmentContextServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Crypto.Crypto | Database$1 | Exclude<RSetup, NativeDatabase>>, makePasskeyPersistenceServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyPersistenceMapping<PasskeyCredentialMapping<S, C, F, O, H, N>, M, Flow, Admission, Charge, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyPersistenceServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Crypto.Crypto | Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>, makePasskeyRegistrationCeremonyServices: <M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Intent extends Table$1, H extends Table$1, RSetup = never>(mapping: PasskeyMappingSource<PasskeyRegistrationCeremonyMapping<M, Flow, Admission, Charge, Intent, H> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyRegistrationCeremonyServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Crypto.Crypto | Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>, makePasskeyManagementServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Command extends Table$1, N, RSetup = never>(mapping: PasskeyMappingSource<PasskeyManagementMapping<S, C, F, O, H, M, Flow, Admission, Charge, Command, N> & D1PasskeyMapping, RSetup>) => Effect.Effect<import("@yielded/auth-persistence/Adapter").PasskeyManagementServices, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Crypto.Crypto | Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>, makePasskeyRegistrationServices: <S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Intent extends Table$1, N, Value, RSetup = never>(mapping: PasskeyMappingSource<PasskeyRegistrationMapping<S, C, F, O, H, M, Flow, Admission, Charge, Intent, N, Value> & D1PasskeyMapping, RSetup>) => Effect.Effect<PasskeyRegistrationServices<Value>, import("@yielded/auth/Passkey").PasskeyConfigurationError | import("@yielded/auth-persistence/Adapter").PersistenceMappingError, Crypto.Crypto | Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
|
|
23
23
|
export declare function coordinatePasskeyPersistence<D extends Database, S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, N, A, E, R, RSetup = never, DatabaseError = never, DatabaseRequirements = never>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
24
24
|
readonly mapping: PasskeyMappingSource<PasskeyPersistenceMapping<PasskeyCredentialMapping<S, C, F, O, H, N>, M, Flow, Admission, Charge, N> & D1PasskeyMapping, RSetup>;
|
|
25
|
-
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | D1BatchStatements> | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
25
|
+
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
26
26
|
export declare function coordinatePasskeyRegistrationCeremony<D extends Database, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Intent extends Table$1, H extends Table$1, A, E, R, RSetup = never, DatabaseError = never, DatabaseRequirements = never>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
27
27
|
readonly mapping: PasskeyMappingSource<PasskeyRegistrationCeremonyMapping<M, Flow, Admission, Charge, Intent, H> & D1PasskeyMapping, RSetup>;
|
|
28
|
-
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | D1BatchStatements> | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
28
|
+
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
29
29
|
export declare function coordinatePasskeyManagement<D extends Database, S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Command extends Table$1, N, A, E, R, RSetup = never, DatabaseError = never, DatabaseRequirements = never>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
30
30
|
readonly mapping: PasskeyMappingSource<PasskeyManagementMapping<S, C, F, O, H, M, Flow, Admission, Charge, Command, N> & D1PasskeyMapping, RSetup>;
|
|
31
|
-
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | PasskeyManagementPersistence | D1BatchStatements> | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
31
|
+
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | PasskeyManagementPersistence | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
32
32
|
export declare function coordinatePasskeyRegistration<D extends Database, S extends Table$1, C extends Table$1, F extends Table$1, O extends Table$1, H extends Table$1, M extends Table$1, Flow extends Table$1, Admission extends Table$1, Charge extends Table$1, Intent extends Table$1, N, Value, AuthorityId, A, E, R, RSetup = never, DatabaseError = never, DatabaseRequirements = never>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
33
33
|
readonly mapping: PasskeyMappingSource<PasskeyRegistrationMapping<S, C, F, O, H, M, Flow, Admission, Charge, Intent, N, Value> & D1PasskeyMapping, RSetup>;
|
|
34
34
|
readonly authority: Context.Key<AuthorityId, PasskeyRegistrationWriter<Value>>;
|
|
35
|
-
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | AuthorityId | D1BatchStatements> | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
35
|
+
}, body: Effect.Effect<A, E, R>): Effect.Effect<A, PasskeyCoordinatorError<E> | DatabaseError, Exclude<R, PasskeyPersistence | AuthorityId | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | DatabaseRequirements | RSetup>;
|
|
36
36
|
//#endregion
|
|
37
37
|
//# sourceMappingURL=d1-passkey.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-passkey.mjs","names":["DatabaseService"],"sources":["../../src/drizzle/d1-passkey.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n PasskeyUnavailable,\n PasskeyPersistence,\n PasskeyManagementPersistence,\n} from \"@yielded/auth/Passkey\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { Effect, Context } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport { makePasskeyTarget } from \"./passkey-drivers\";\nimport type {\n D1PasskeyMapping,\n PasskeyCredentialMapping,\n PasskeyMappingSource,\n PasskeyPersistenceMapping,\n} from \"./passkey-model\";\nimport type { PasskeyRegistrationCeremonyMapping } from \"./passkey-registration-ceremony-model\";\nimport {\n type PasskeyCoordinatorError,\n coordinateTargetPasskey,\n coordinateTargetPasskeyRegistration,\n} from \"./passkey-target\";\n\ntype Table = AnySQLiteTable<{ dialect: \"sqlite\" }>;\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\n\nconst unavailable = () => PasskeyUnavailable.make({});\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\nconst target = makePasskeyTarget<DatabaseService, Database, Table, D1PasskeyMapping>(\n DatabaseService,\n configuration,\n);\n\nexport const {\n makePasskeyCredentialServices,\n makePasskeyEnrollmentContextServices,\n makePasskeyPersistenceServices,\n makePasskeyRegistrationCeremonyServices,\n makePasskeyManagementServices,\n makePasskeyRegistrationServices,\n} = target;\n\nexport function coordinatePasskeyPersistence<\n D extends Database,\n S extends Table,\n C extends Table,\n F extends Table,\n O extends Table,\n H extends Table,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyPersistenceMapping<\n PasskeyCredentialMapping<S, C, F, O, H, N>,\n M,\n Flow,\n Admission,\n Charge,\n N\n > &\n D1PasskeyMapping,\n RSetup\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | D1BatchStatements>\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskey(database, options.mapping, configuration, (_, services, append) =>\n Effect.gen(function* () {\n const original = services.passkeyPersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(PasskeyPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinatePasskeyRegistrationCeremony<\n D extends Database,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Intent extends Table,\n H extends Table,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyRegistrationCeremonyMapping<M, Flow, Admission, Charge, Intent, H> & D1PasskeyMapping,\n RSetup\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | D1BatchStatements>\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskeyRegistration(\n database,\n options.mapping,\n configuration,\n (_, services, append) =>\n Effect.gen(function* () {\n const original = services.passkeyPersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(PasskeyPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nimport type {\n PasskeyManagementMapping,\n PasskeyRegistrationMapping,\n PasskeyRegistrationServices,\n PasskeyRegistrationWriter,\n} from \"./passkey-write-model\";\nimport {\n coordinateTargetPasskeyManagement,\n coordinateTargetPasskeyRegistrationWriter,\n} from \"./passkey-write-target\";\n\nexport function coordinatePasskeyManagement<\n D extends Database,\n S extends Table,\n C extends Table,\n F extends Table,\n O extends Table,\n H extends Table,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Command extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyManagementMapping<S, C, F, O, H, M, Flow, Admission, Charge, Command, N> &\n D1PasskeyMapping,\n RSetup\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | PasskeyManagementPersistence | D1BatchStatements>\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskeyManagement(\n database,\n options.mapping,\n configuration,\n (_, services, append) =>\n Effect.gen(function* () {\n const collector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, collector),\n );\n\n const original = services.passkeyPersistence;\n\n const persistence: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const authority = services.passkeyManagementPersistence;\n\n const service: PasskeyManagementPersistence[\"Service\"] = {\n list: (input) => owner.run(authority.list(input)),\n inspectRemove: (input) => owner.run(authority.inspectRemove(input)),\n issueEnrollment: (input, prepare) =>\n owner.run(authority.issueEnrollment(input, prepare)),\n completeEnrollment: (input, prepare) =>\n owner.run(authority.completeEnrollment(input, prepare)),\n rename: (input, prepare) => owner.run(authority.rename(input, prepare)),\n remove: (input, prepare) => owner.run(authority.remove(input, prepare)),\n };\n\n const context = Context.make(PasskeyPersistence, persistence).pipe(\n Context.add(PasskeyManagementPersistence, service),\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, context));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinatePasskeyRegistration<\n D extends Database,\n S extends Table,\n C extends Table,\n F extends Table,\n O extends Table,\n H extends Table,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Intent extends Table,\n N,\n Value,\n AuthorityId,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyRegistrationMapping<S, C, F, O, H, M, Flow, Admission, Charge, Intent, N, Value> &\n D1PasskeyMapping,\n RSetup\n >;\n readonly authority: Context.Key<AuthorityId, PasskeyRegistrationWriter<Value>>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | AuthorityId | D1BatchStatements>\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskeyRegistrationWriter(\n database,\n options.mapping,\n configuration,\n (_, services: PasskeyRegistrationServices<Value>, append) =>\n Effect.gen(function* () {\n const collector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, collector),\n );\n\n const original = services.passkeyPersistence;\n\n const persistence: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const authority = services.passkeyRegistrationAuthority;\n\n const service: PasskeyRegistrationWriter<Value> = {\n inspect: (input) => owner.run(authority.inspect(input)),\n issueRegistration: (input, prepare) =>\n owner.run(authority.issueRegistration(input, prepare)),\n completeRegistration: (input, prepare) =>\n owner.run(authority.completeRegistration(input, prepare)),\n };\n\n const context = Context.make(PasskeyPersistence, persistence).pipe(\n Context.add(options.authority, service),\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, context));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"d1-passkey.mjs","names":["DatabaseService"],"sources":["../../src/drizzle/d1-passkey.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n PasskeyUnavailable,\n PasskeyPersistence,\n PasskeyManagementPersistence,\n} from \"@yielded/auth/Passkey\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { type Crypto, Effect, Context } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport { makePasskeyTarget } from \"./passkey-drivers\";\nimport type {\n D1PasskeyMapping,\n PasskeyCredentialMapping,\n PasskeyMappingSource,\n PasskeyPersistenceMapping,\n} from \"./passkey-model\";\nimport type { PasskeyRegistrationCeremonyMapping } from \"./passkey-registration-ceremony-model\";\nimport {\n type PasskeyCoordinatorError,\n coordinateTargetPasskey,\n coordinateTargetPasskeyRegistration,\n} from \"./passkey-target\";\n\ntype Table = AnySQLiteTable<{ dialect: \"sqlite\" }>;\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\n\nconst unavailable = () => PasskeyUnavailable.make({});\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\nconst target = makePasskeyTarget<DatabaseService, Database, Table, D1PasskeyMapping>(\n DatabaseService,\n configuration,\n);\n\nexport const {\n makePasskeyCredentialServices,\n makePasskeyEnrollmentContextServices,\n makePasskeyPersistenceServices,\n makePasskeyRegistrationCeremonyServices,\n makePasskeyManagementServices,\n makePasskeyRegistrationServices,\n} = target;\n\nexport function coordinatePasskeyPersistence<\n D extends Database,\n S extends Table,\n C extends Table,\n F extends Table,\n O extends Table,\n H extends Table,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyPersistenceMapping<\n PasskeyCredentialMapping<S, C, F, O, H, N>,\n M,\n Flow,\n Admission,\n Charge,\n N\n > &\n D1PasskeyMapping,\n RSetup\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskey(database, options.mapping, configuration, (_, services, append) =>\n Effect.gen(function* () {\n const original = services.passkeyPersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(PasskeyPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinatePasskeyRegistrationCeremony<\n D extends Database,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Intent extends Table,\n H extends Table,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyRegistrationCeremonyMapping<M, Flow, Admission, Charge, Intent, H> & D1PasskeyMapping,\n RSetup\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskeyRegistration(\n database,\n options.mapping,\n configuration,\n (_, services, append) =>\n Effect.gen(function* () {\n const original = services.passkeyPersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const provided = Context.make(PasskeyPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nimport type {\n PasskeyManagementMapping,\n PasskeyRegistrationMapping,\n PasskeyRegistrationServices,\n PasskeyRegistrationWriter,\n} from \"./passkey-write-model\";\nimport {\n coordinateTargetPasskeyManagement,\n coordinateTargetPasskeyRegistrationWriter,\n} from \"./passkey-write-target\";\n\nexport function coordinatePasskeyManagement<\n D extends Database,\n S extends Table,\n C extends Table,\n F extends Table,\n O extends Table,\n H extends Table,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Command extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyManagementMapping<S, C, F, O, H, M, Flow, Admission, Charge, Command, N> &\n D1PasskeyMapping,\n RSetup\n >;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | PasskeyManagementPersistence | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskeyManagement(\n database,\n options.mapping,\n configuration,\n (_, services, append) =>\n Effect.gen(function* () {\n const collector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, collector),\n );\n\n const original = services.passkeyPersistence;\n\n const persistence: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const authority = services.passkeyManagementPersistence;\n\n const service: PasskeyManagementPersistence[\"Service\"] = {\n list: (input) => owner.run(authority.list(input)),\n inspectRemove: (input) => owner.run(authority.inspectRemove(input)),\n issueEnrollment: (input, prepare) =>\n owner.run(authority.issueEnrollment(input, prepare)),\n completeEnrollment: (input, prepare) =>\n owner.run(authority.completeEnrollment(input, prepare)),\n rename: (input, prepare) => owner.run(authority.rename(input, prepare)),\n remove: (input, prepare) => owner.run(authority.remove(input, prepare)),\n };\n\n const context = Context.make(PasskeyPersistence, persistence).pipe(\n Context.add(PasskeyManagementPersistence, service),\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, context));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n\nexport function coordinatePasskeyRegistration<\n D extends Database,\n S extends Table,\n C extends Table,\n F extends Table,\n O extends Table,\n H extends Table,\n M extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Intent extends Table,\n N,\n Value,\n AuthorityId,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PasskeyMappingSource<\n PasskeyRegistrationMapping<S, C, F, O, H, M, Flow, Admission, Charge, Intent, N, Value> &\n D1PasskeyMapping,\n RSetup\n >;\n readonly authority: Context.Key<AuthorityId, PasskeyRegistrationWriter<Value>>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PasskeyCoordinatorError<E> | DatabaseError,\n | Exclude<R, PasskeyPersistence | AuthorityId | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | DatabaseRequirements\n | RSetup\n> {\n return Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPasskeyRegistrationWriter(\n database,\n options.mapping,\n configuration,\n (_, services: PasskeyRegistrationServices<Value>, append) =>\n Effect.gen(function* () {\n const collector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(unavailable()).pipe(\n Effect.provideService(D1BatchStatements, collector),\n );\n\n const original = services.passkeyPersistence;\n\n const persistence: PasskeyPersistence[\"Service\"] = {\n issue: (input, prepare) => owner.run(original.issue(input, prepare)),\n context: (input) => owner.run(original.context(input)),\n claim: (input, prepare) => owner.run(original.claim(input, prepare)),\n settle: (input, prepare) => owner.run(original.settle(input, prepare)),\n cleanup: (input, prepare) => owner.run(original.cleanup(input, prepare)),\n };\n\n const authority = services.passkeyRegistrationAuthority;\n\n const service: PasskeyRegistrationWriter<Value> = {\n inspect: (input) => owner.run(authority.inspect(input)),\n issueRegistration: (input, prepare) =>\n owner.run(authority.issueRegistration(input, prepare)),\n completeRegistration: (input, prepare) =>\n owner.run(authority.completeRegistration(input, prepare)),\n };\n\n const context = Context.make(PasskeyPersistence, persistence).pipe(\n Context.add(options.authority, service),\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, context));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n}\n"],"mappings":"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"}
|
|
@@ -16,9 +16,9 @@ import { ProofCompletionInput, ProofCompletionPlan } from "@yielded/auth/Proofs"
|
|
|
16
16
|
import { PasswordAttemptDecision, PasswordAttemptPolicy, PasswordCredentialSnapshot, PasswordMutationDecision, PasswordMutationInput, PasswordPersistence, PasswordUnavailable, PreparePasswordCommit } from "@yielded/auth/Password";
|
|
17
17
|
import { EffectSQLiteD1Database } from "drizzle-orm/effect-d1";
|
|
18
18
|
import { AnySQLiteTable } from "drizzle-orm/sqlite-core";
|
|
19
|
+
import "drizzle-orm/effect-core";
|
|
19
20
|
import { Statement } from "effect/sql/Statement";
|
|
20
21
|
import { D1Client } from "@effect/sql-d1/D1Client";
|
|
21
|
-
import "drizzle-orm/effect-core";
|
|
22
22
|
//#region src/drizzle/d1-passwords.d.ts
|
|
23
23
|
type Database = EffectSQLiteD1Database<AnyRelations> & {
|
|
24
24
|
readonly $client: D1Client;
|
|
@@ -4,7 +4,7 @@ import { D1BatchStatements } from "./D1BatchStatements.mjs";
|
|
|
4
4
|
import { PhoneCoordinatorError } from "./phone-target.mjs";
|
|
5
5
|
import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
|
|
6
6
|
import { AnyRelations } from "drizzle-orm";
|
|
7
|
-
import { Effect } from "effect";
|
|
7
|
+
import { Crypto, Effect } from "effect";
|
|
8
8
|
import { LifecycleHooks } from "@yielded/auth/Hooks";
|
|
9
9
|
import { PhoneAdmission, PhonePersistence, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
|
|
10
10
|
import { EffectSQLiteD1Database } from "drizzle-orm/effect-d1";
|
|
@@ -15,9 +15,9 @@ type Database = EffectSQLiteD1Database<AnyRelations> & {
|
|
|
15
15
|
readonly $client: D1Client;
|
|
16
16
|
};
|
|
17
17
|
type Table$1 = AnySQLiteTable;
|
|
18
|
-
export declare const makePhonePersistenceServices: <S extends Table$1, I extends Table$1, F extends Table$1, C extends Table$1, N, RSetup = never>(mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & D1PhoneMapping, RSetup>) => Effect.Effect<PhonePersistenceServices, import("@yielded/auth-persistence/Adapter").PersistenceMappingError | import("@yielded/auth/PhoneOtp").PhoneConfigurationError, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
|
|
18
|
+
export declare const makePhonePersistenceServices: <S extends Table$1, I extends Table$1, F extends Table$1, C extends Table$1, N, RSetup = never>(mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & D1PhoneMapping, RSetup>) => Effect.Effect<PhonePersistenceServices, import("@yielded/auth-persistence/Adapter").PersistenceMappingError | import("@yielded/auth/PhoneOtp").PhoneConfigurationError, Crypto.Crypto | Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
|
|
19
19
|
export declare const coordinatePhonePersistence: <D extends Database, S extends Table$1, I extends Table$1, F extends Table$1, C extends Table$1, N, A, E, R, RSetup = never, DatabaseError = never, DatabaseRequirements = never>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
20
20
|
readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & D1PhoneMapping, RSetup>;
|
|
21
|
-
}, body: Effect.Effect<A, E, R>) => Effect.Effect<A, PhoneCoordinatorError<E> | DatabaseError, Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets | D1BatchStatements> | LifecycleHooks | RSetup | DatabaseRequirements>;
|
|
21
|
+
}, body: Effect.Effect<A, E, R>) => Effect.Effect<A, PhoneCoordinatorError<E> | DatabaseError, Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | RSetup | DatabaseRequirements>;
|
|
22
22
|
//#endregion
|
|
23
23
|
//# sourceMappingURL=d1-phone.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-phone.mjs","names":["DatabaseService","PhoneUnavailable"],"sources":["../../src/drizzle/d1-phone.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n PhoneOtpUnavailable as PhoneUnavailable,\n PhoneAdmission,\n PhonePersistence,\n PhoneSignInTargets,\n} from \"@yielded/auth/PhoneOtp\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { Context, Effect } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport type { D1PhoneMapping, PhoneMapping, PhoneMappingSource } from \"./phone-model\";\nimport { coordinateTargetPhone, makePhoneTarget, type PhoneCoordinatorError } from \"./phone-target\";\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\ntype Table = AnySQLiteTable;\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\n/** Reads use a primary D1 session; observations and expiry are asserted in the same batch. */\nconst target = makePhoneTarget<DatabaseService, Database, Table, D1PhoneMapping>(\n DatabaseService,\n configuration,\n);\n\nexport const { makePhonePersistenceServices } = target;\n\nexport const coordinatePhonePersistence = <\n D extends Database,\n S extends Table,\n I extends Table,\n F extends Table,\n C extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & D1PhoneMapping, RSetup>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PhoneCoordinatorError<E> | DatabaseError,\n | Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets | D1BatchStatements>\n | LifecycleHooks\n | RSetup\n | DatabaseRequirements\n> =>\n Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPhone(\n database,\n options.mapping,\n configuration,\n (_transaction, services, append) =>\n Effect.gen(function* () {\n const original = services.phonePersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(PhoneUnavailable.make({})).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: PhonePersistence[\"Service\"] = {\n target: (input) => owner.run(original.target(input)),\n mutate: (input, prepare) => owner.run(original.mutate(input, prepare)),\n };\n\n const provided = Context.make(PhonePersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n Context.add(PhoneAdmission, {\n admit: (input) => owner.run(services.phoneAdmission.admit(input)),\n cleanup: (input) => owner.run(services.phoneAdmission.cleanup(input)),\n }),\n Context.add(PhoneSignInTargets, {\n lookup: (input) => owner.run(services.phoneSignInTargets.lookup(input)),\n }),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n"],"mappings":";;;;;;;;;AAuBA,MAAM,gBAAgB;CACpB,MAAM;CACN,SAAS;CACT,SAAS;CACT,uBAAuB,OAAO;AAChC;AAQA,MAAa,EAAE,iCALA,gBACbA,UACA,aAG8C;AAEhD,MAAa,8BAcX,SACA,SAGA,
|
|
1
|
+
{"version":3,"file":"d1-phone.mjs","names":["DatabaseService","PhoneUnavailable"],"sources":["../../src/drizzle/d1-phone.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport {\n PhoneOtpUnavailable as PhoneUnavailable,\n PhoneAdmission,\n PhonePersistence,\n PhoneSignInTargets,\n} from \"@yielded/auth/PhoneOtp\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { type Crypto, Context, Effect } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport type { D1PhoneMapping, PhoneMapping, PhoneMappingSource } from \"./phone-model\";\nimport { coordinateTargetPhone, makePhoneTarget, type PhoneCoordinatorError } from \"./phone-target\";\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\ntype Table = AnySQLiteTable;\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\n/** Reads use a primary D1 session; observations and expiry are asserted in the same batch. */\nconst target = makePhoneTarget<DatabaseService, Database, Table, D1PhoneMapping>(\n DatabaseService,\n configuration,\n);\n\nexport const { makePhonePersistenceServices } = target;\n\nexport const coordinatePhonePersistence = <\n D extends Database,\n S extends Table,\n I extends Table,\n F extends Table,\n C extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & D1PhoneMapping, RSetup>;\n },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n PhoneCoordinatorError<E> | DatabaseError,\n | Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | RSetup\n | DatabaseRequirements\n> =>\n Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetPhone(\n database,\n options.mapping,\n configuration,\n (_transaction, services, append) =>\n Effect.gen(function* () {\n const original = services.phonePersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(PhoneUnavailable.make({})).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: PhonePersistence[\"Service\"] = {\n target: (input) => owner.run(original.target(input)),\n mutate: (input, prepare) => owner.run(original.mutate(input, prepare)),\n };\n\n const provided = Context.make(PhonePersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n Context.add(PhoneAdmission, {\n admit: (input) => owner.run(services.phoneAdmission.admit(input)),\n cleanup: (input) => owner.run(services.phoneAdmission.cleanup(input)),\n }),\n Context.add(PhoneSignInTargets, {\n lookup: (input) => owner.run(services.phoneSignInTargets.lookup(input)),\n }),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n"],"mappings":";;;;;;;;;AAuBA,MAAM,gBAAgB;CACpB,MAAM;CACN,SAAS;CACT,SAAS;CACT,uBAAuB,OAAO;AAChC;AAQA,MAAa,EAAE,iCALA,gBACbA,UACA,aAG8C;AAEhD,MAAa,8BAcX,SACA,SAGA,SAUA,OAAO,QAAQ,eAAe,OAAO,IAAI,aACvC,sBACE,UACA,QAAQ,SACR,gBACC,cAAc,UAAU,WACvB,OAAO,IAAI,aAAa;CACtB,MAAM,WAAW,SAAS;CAE1B,MAAM,kBAAkB,kBAAkB,GAAG,EAC3C,SAAS,cAAc,OAAO,WAAW,OAAO,SAAS,CAAC,EAC5D,CAAC;CAED,MAAM,QAAQ,OAAO,YAAYC,oBAAiB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAC1D,OAAO,eAAe,mBAAmB,eAAe,CAC1D;CAOA,MAAM,WAAW,QAAQ,KAAK,kBAAkB;EAJ9C,SAAS,UAAU,MAAM,IAAI,SAAS,OAAO,KAAK,CAAC;EACnD,SAAS,OAAO,YAAY,MAAM,IAAI,SAAS,OAAO,OAAO,OAAO,CAAC;CAGjB,CAAC,CAAC,CAAC,KACvD,QAAQ,IAAI,mBAAmB,MAAM,SAAS,GAC9C,QAAQ,IAAI,gBAAgB;EAC1B,QAAQ,UAAU,MAAM,IAAI,SAAS,eAAe,MAAM,KAAK,CAAC;EAChE,UAAU,UAAU,MAAM,IAAI,SAAS,eAAe,QAAQ,KAAK,CAAC;CACtE,CAAC,GACD,QAAQ,IAAI,oBAAoB,EAC9B,SAAS,UAAU,MAAM,IAAI,SAAS,mBAAmB,OAAO,KAAK,CAAC,EACxE,CAAC,CACH;CAEA,OAAO,OAAO,MAAM,MAAM,OAAO,eAAe,MAAM,QAAQ,CAAC;AACjE,CAAC,CACL,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,QAAQ,CAAC,CACxD"}
|
|
@@ -9,9 +9,9 @@ import { CurrentCommitJournal, HookConfigurationError, LifecycleHooks, PreparedC
|
|
|
9
9
|
import { PrepareProofCommit, ProofAttemptDecision, ProofBinding, ProofCleanupResult, ProofCompletionDecision, ProofCompletionPlan, ProofDeliveryClaim, ProofDeliveryOutcome, ProofPersistence, ProofPolicy, ProofRequestConflict, ProofUnavailable, ProofVersion } from "@yielded/auth/Proofs";
|
|
10
10
|
import { EffectSQLiteD1Database } from "drizzle-orm/effect-d1";
|
|
11
11
|
import { AnySQLiteTable } from "drizzle-orm/sqlite-core";
|
|
12
|
+
import "drizzle-orm/effect-core";
|
|
12
13
|
import { Statement } from "effect/sql/Statement";
|
|
13
14
|
import { D1Client } from "@effect/sql-d1/D1Client";
|
|
14
|
-
import "drizzle-orm/effect-core";
|
|
15
15
|
//#region src/drizzle/d1-proofs.d.ts
|
|
16
16
|
type Database = EffectSQLiteD1Database<AnyRelations> & {
|
|
17
17
|
readonly $client: D1Client;
|
|
@@ -11,9 +11,9 @@ import { HookConfigurationError, LifecycleHooks, PreparedCommit } from "@yielded
|
|
|
11
11
|
import { AuthenticationAuthority, AuthenticationEvidence, AuthenticationRequirement, AuthenticationRevision, PendingAuthentication, PendingAuthenticationInvalid, PendingConsumption, PrepareSessionCommit, SessionConflict, SessionInvalid, SessionRepository, SessionStepUpInvalid, SessionStepUpPersistence, SessionUnavailable, SignedSessionValidity, StaleAuthentication, StatefulSessionPersistence } from "@yielded/auth/Sessions";
|
|
12
12
|
import { SubjectId } from "@yielded/auth/Schema";
|
|
13
13
|
import { AnySQLiteTable } from "drizzle-orm/sqlite-core";
|
|
14
|
+
import "drizzle-orm/effect-core";
|
|
14
15
|
import "effect/sql/SqlError";
|
|
15
16
|
import { Statement } from "effect/sql/Statement";
|
|
16
|
-
import "drizzle-orm/effect-core";
|
|
17
17
|
//#region src/drizzle/d1-sessions.d.ts
|
|
18
18
|
type Database = D1PlanningDatabase;
|
|
19
19
|
type D1DomainError = SessionStepUpInvalid | PendingAuthenticationInvalid | SessionConflict | SessionInvalid | SessionUnavailable | StaleAuthentication;
|
|
@@ -4,7 +4,7 @@ import { D1BatchStatements } from "./D1BatchStatements.mjs";
|
|
|
4
4
|
import { TotpCoordinatorError } from "./totp-target.mjs";
|
|
5
5
|
import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
|
|
6
6
|
import { AnyRelations } from "drizzle-orm";
|
|
7
|
-
import { Effect } from "effect";
|
|
7
|
+
import { Crypto, Effect } from "effect";
|
|
8
8
|
import { LifecycleHooks } from "@yielded/auth/Hooks";
|
|
9
9
|
import { TotpPersistence } from "@yielded/auth/Totp";
|
|
10
10
|
import { EffectSQLiteD1Database } from "drizzle-orm/effect-d1";
|
|
@@ -15,9 +15,9 @@ type Database = EffectSQLiteD1Database<AnyRelations> & {
|
|
|
15
15
|
readonly $client: D1Client;
|
|
16
16
|
};
|
|
17
17
|
type Table$1 = AnySQLiteTable;
|
|
18
|
-
export declare const makeTotpPersistenceServices: <S extends Table$1, F extends Table$1, C extends Table$1, N, RSetup = never>(mapping: TotpMappingSource<TotpMapping<S, F, C, N> & D1TotpMapping, RSetup>) => Effect.Effect<TotpPersistenceServices, import("@yielded/auth-persistence/Adapter").PersistenceMappingError | import("@yielded/auth/Totp").TotpConfigurationError, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
|
|
18
|
+
export declare const makeTotpPersistenceServices: <S extends Table$1, F extends Table$1, C extends Table$1, N, RSetup = never>(mapping: TotpMappingSource<TotpMapping<S, F, C, N> & D1TotpMapping, RSetup>) => Effect.Effect<TotpPersistenceServices, import("@yielded/auth-persistence/Adapter").PersistenceMappingError | import("@yielded/auth/Totp").TotpConfigurationError, Crypto.Crypto | Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
|
|
19
19
|
export declare const coordinateTotpPersistence: <D extends Database, S extends Table$1, F extends Table$1, C extends Table$1, N, A, E, R, RSetup = never, DatabaseError = never, DatabaseRequirements = never>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
20
20
|
readonly mapping: TotpMappingSource<TotpMapping<S, F, C, N> & D1TotpMapping, RSetup>;
|
|
21
|
-
}, body: Effect.Effect<A, E, R>) => Effect.Effect<A, TotpCoordinatorError<E> | DatabaseError, Exclude<R, TotpPersistence | D1BatchStatements> | LifecycleHooks | RSetup | DatabaseRequirements>;
|
|
21
|
+
}, body: Effect.Effect<A, E, R>) => Effect.Effect<A, TotpCoordinatorError<E> | DatabaseError, Exclude<R, TotpPersistence | D1BatchStatements> | Crypto.Crypto | LifecycleHooks | RSetup | DatabaseRequirements>;
|
|
22
22
|
//#endregion
|
|
23
23
|
//# sourceMappingURL=d1-totp.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"d1-totp.mjs","names":["DatabaseService"],"sources":["../../src/drizzle/d1-totp.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport { TotpUnavailable, TotpPersistence } from \"@yielded/auth/Totp\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { Context, Effect } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport type { D1TotpMapping, TotpMapping, TotpMappingSource } from \"./totp-model\";\nimport { coordinateTargetTotp, makeTotpTarget, type TotpCoordinatorError } from \"./totp-target\";\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\ntype Table = AnySQLiteTable;\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\n/** Reads use a primary D1 session; observations and expiry are asserted in the same batch. */\nconst target = makeTotpTarget<DatabaseService, Database, Table, D1TotpMapping>(\n DatabaseService,\n configuration,\n);\n\nexport const { makeTotpPersistenceServices } = target;\n\nexport const coordinateTotpPersistence = <\n D extends Database,\n S extends Table,\n F extends Table,\n C extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: TotpMappingSource<TotpMapping<S, F, C, N> & D1TotpMapping, RSetup> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n TotpCoordinatorError<E> | DatabaseError,\n Exclude<R, TotpPersistence | D1BatchStatements
|
|
1
|
+
{"version":3,"file":"d1-totp.mjs","names":["DatabaseService"],"sources":["../../src/drizzle/d1-totp.ts"],"sourcesContent":["import type { D1Client } from \"@effect/sql-d1/D1Client\";\nimport { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport { TotpUnavailable, TotpPersistence } from \"@yielded/auth/Totp\";\nimport type { AnyRelations } from \"drizzle-orm\";\nimport type { EffectSQLiteD1Database } from \"drizzle-orm/effect-d1\";\nimport type { AnySQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport { type Crypto, Context, Effect } from \"effect\";\n\nimport { Database as DatabaseService } from \"./d1-database\";\nimport { makeD1Owner } from \"./d1-planning\";\nimport { D1BatchStatements } from \"./D1BatchStatements\";\nimport { nativeDatabase } from \"./native-database\";\nimport type { D1TotpMapping, TotpMapping, TotpMappingSource } from \"./totp-model\";\nimport { coordinateTargetTotp, makeTotpTarget, type TotpCoordinatorError } from \"./totp-target\";\ntype Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };\ntype Table = AnySQLiteTable;\n\nconst configuration = {\n mode: \"batch\" as const,\n dialect: \"sqlite\" as const,\n locking: false,\n standaloneGuard: () => Effect.void,\n};\n\n/** Reads use a primary D1 session; observations and expiry are asserted in the same batch. */\nconst target = makeTotpTarget<DatabaseService, Database, Table, D1TotpMapping>(\n DatabaseService,\n configuration,\n);\n\nexport const { makeTotpPersistenceServices } = target;\n\nexport const coordinateTotpPersistence = <\n D extends Database,\n S extends Table,\n F extends Table,\n C extends Table,\n N,\n A,\n E,\n R,\n RSetup = never,\n DatabaseError = never,\n DatabaseRequirements = never,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: TotpMappingSource<TotpMapping<S, F, C, N> & D1TotpMapping, RSetup> },\n body: Effect.Effect<A, E, R>,\n): Effect.Effect<\n A,\n TotpCoordinatorError<E> | DatabaseError,\n | Exclude<R, TotpPersistence | D1BatchStatements>\n | Crypto.Crypto\n | LifecycleHooks\n | RSetup\n | DatabaseRequirements\n> =>\n Effect.flatMap(nativeDatabase(acquire), (database) =>\n coordinateTargetTotp(\n database,\n options.mapping,\n configuration,\n (_transaction, services, append) =>\n Effect.gen(function* () {\n const original = services.totpPersistence;\n\n const nativeCollector = D1BatchStatements.of({\n append: (statement) => Effect.sync(() => append(statement)),\n });\n\n const owner = yield* makeD1Owner(TotpUnavailable.make({})).pipe(\n Effect.provideService(D1BatchStatements, nativeCollector),\n );\n\n const service: TotpPersistence[\"Service\"] = {\n snapshot: (input) => owner.run(original.snapshot(input)),\n mutate: (input, prepare) => owner.run(original.mutate(input, prepare)),\n };\n\n const provided = Context.make(TotpPersistence, service).pipe(\n Context.add(D1BatchStatements, owner.collector),\n );\n\n return yield* owner.close(Effect.provideContext(body, provided));\n }),\n ).pipe(Effect.provideService(NativeDatabase, database)),\n );\n"],"mappings":";;;;;;;;;AAkBA,MAAM,gBAAgB;CACpB,MAAM;CACN,SAAS;CACT,SAAS;CACT,uBAAuB,OAAO;AAChC;AAQA,MAAa,EAAE,gCALA,eACbA,UACA,aAG6C;AAE/C,MAAa,6BAaX,SACA,SACA,SAUA,OAAO,QAAQ,eAAe,OAAO,IAAI,aACvC,qBACE,UACA,QAAQ,SACR,gBACC,cAAc,UAAU,WACvB,OAAO,IAAI,aAAa;CACtB,MAAM,WAAW,SAAS;CAE1B,MAAM,kBAAkB,kBAAkB,GAAG,EAC3C,SAAS,cAAc,OAAO,WAAW,OAAO,SAAS,CAAC,EAC5D,CAAC;CAED,MAAM,QAAQ,OAAO,YAAY,gBAAgB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KACzD,OAAO,eAAe,mBAAmB,eAAe,CAC1D;CAOA,MAAM,WAAW,QAAQ,KAAK,iBAAiB;EAJ7C,WAAW,UAAU,MAAM,IAAI,SAAS,SAAS,KAAK,CAAC;EACvD,SAAS,OAAO,YAAY,MAAM,IAAI,SAAS,OAAO,OAAO,OAAO,CAAC;CAGlB,CAAC,CAAC,CAAC,KACtD,QAAQ,IAAI,mBAAmB,MAAM,SAAS,CAChD;CAEA,OAAO,OAAO,MAAM,MAAM,OAAO,eAAe,MAAM,QAAQ,CAAC;AACjE,CAAC,CACL,CAAC,CAAC,KAAK,OAAO,eAAe,gBAAgB,QAAQ,CAAC,CACxD"}
|
|
@@ -2,7 +2,7 @@ import { PersistenceMappingError as PersistenceMappingError$1, column, isMappedC
|
|
|
2
2
|
import { validateDrizzleStorage } from "./storage-validation.mjs";
|
|
3
3
|
import { nativeDatabase } from "./native-database.mjs";
|
|
4
4
|
import { Database } from "./mysql-database.mjs";
|
|
5
|
-
import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
|
|
5
|
+
import { NativeDatabase, withStorageValidation } from "@yielded/auth-persistence/Adapter";
|
|
6
6
|
import { ExternalIdentityMutation, IdentityConflict, IdentityUnavailable, SubjectProvisioned, SubjectProvisioner } from "@yielded/auth/Identity";
|
|
7
7
|
import { and, eq } from "drizzle-orm";
|
|
8
8
|
import { Cause, Effect, Schema } from "effect";
|
|
@@ -96,7 +96,7 @@ const makeMysqlIdentityServices = Effect.fnUntraced(function* (mapping) {
|
|
|
96
96
|
...yield* makeMysqlSubjectProvisioningServices(mapping),
|
|
97
97
|
...yield* makeMysqlExternalIdentityServices(mapping)
|
|
98
98
|
};
|
|
99
|
-
});
|
|
99
|
+
}, withStorageValidation);
|
|
100
100
|
//#endregion
|
|
101
101
|
export { makeMysqlExternalIdentityServices, makeMysqlIdentityServices, makeMysqlSubjectProvisioningServices };
|
|
102
102
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql-identity.mjs","names":["DatabaseService","PersistenceMappingError"],"sources":["../../src/drizzle/mysql-identity.ts"],"sourcesContent":["import { NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport {\n ExternalIdentityMutation,\n type ExternalIdentity,\n IdentityConflict,\n IdentityUnavailable,\n SubjectProvisioned,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n} from \"@yielded/auth/Identity\";\nimport { reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport type { SubjectId } from \"@yielded/auth/Schema\";\n/* oxlint-disable no-explicit-any -- Drizzle generic query types are narrowed at this technology boundary. */\nimport { and, eq } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable, MySqlColumn } from \"drizzle-orm/mysql-core\";\nimport { Cause, Effect, Schema } from \"effect\";\n\nimport {\n column,\n isMappedConstraintConflict,\n PersistenceMappingError,\n provisioningFingerprint,\n type ExternalIdentityTables,\n type IdentityTables,\n type SubjectProvisioningTables,\n} from \"./model\";\nimport { Database as DatabaseService } from \"./mysql-database\";\nimport { nativeDatabase } from \"./native-database\";\nimport { validateDrizzleStorage } from \"./storage-validation\";\n\ntype RuntimeDatabase = EffectMysql2Database<any>;\nconst unavailable = () => IdentityUnavailable.make();\nconst isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));\n\nconst mapUnavailable = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n reportPersistenceFailure(effect, isIdentityFailure).pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) => (isIdentityFailure(error) ? error : unavailable())),\n ),\n ),\n );\n\nexport const makeMysqlSubjectProvisioningServices = Effect.fnUntraced(function* <\n Subject extends AnyMySqlTable,\n Identifier extends AnyMySqlTable,\n Request extends AnyMySqlTable,\n NativeId,\n>(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\n\n const db = database as RuntimeDatabase;\n const requestTable = mapping.provisioningRequest.table;\n\n const requestIdColumn = column(\n requestTable,\n mapping.provisioningRequest.requestId,\n ) as MySqlColumn;\n\n const requestFingerprintColumn = column(\n requestTable,\n mapping.provisioningRequest.fingerprint,\n ) as MySqlColumn;\n\n const requestSubjectColumn = column(\n requestTable,\n mapping.provisioningRequest.subjectId,\n ) as MySqlColumn;\n\n const identifierTable = mapping.identifier.table;\n\n const identifierNamespaceColumn = column(\n identifierTable,\n mapping.identifier.namespace,\n ) as MySqlColumn;\n\n const identifierValueColumn = column(identifierTable, mapping.identifier.value) as MySqlColumn;\n\n const findReceipt = Effect.fn(\"DrizzleMysqlIdentity.findReceipt\")(function* (requestId: string) {\n const rows = yield* db\n .select({ fingerprint: requestFingerprintColumn, subjectId: requestSubjectColumn })\n .from(requestTable as any)\n .where(eq(requestIdColumn, requestId))\n .limit(1);\n\n return rows[0];\n });\n\n const provision = Effect.fn(\"DrizzleMysqlIdentity.provision\")(function* (\n input: SubjectProvisioningInput,\n ) {\n const fingerprint = provisioningFingerprint(input);\n const existing = yield* findReceipt(input.requestId);\n\n if (existing !== undefined) {\n if (existing.fingerprint !== fingerprint) return yield* IdentityConflict.make();\n const subjectId = yield* mapping.subjectId.toSubject(existing.subjectId as NativeId);\n\n return SubjectProvisioned.make({ subjectId });\n }\n\n const attempt = db.transaction((tx) =>\n Effect.gen(function* () {\n const allocated =\n mapping.subject.allocateId === undefined\n ? mapping.subject.allocateIdSync?.()\n : yield* mapping.subject.allocateId;\n\n const insert = tx\n .insert(mapping.subject.table as any)\n .values(mapping.subject.encodeInsert(input, allocated) as any);\n\n let nativeId = allocated;\n\n if (nativeId === undefined) {\n if (mapping.subject.decodeGeneratedId === undefined)\n return yield* PersistenceMappingError.make({\n operation: \"provisionSubject.generatedId\",\n cause: new Error(\"MySQL generated IDs require decodeGeneratedId\"),\n });\n const ids = yield* insert.$returningId();\n\n nativeId = yield* mapping.subject.decodeGeneratedId(ids as ReadonlyArray<unknown>);\n } else {\n yield* insert;\n }\n if (input.identifier !== undefined)\n yield* tx\n .insert(identifierTable as any)\n .values(\n mapping.identifier.encodeInsert(input.identifier, nativeId, input.verifiedAt) as any,\n );\n yield* tx\n .insert(requestTable as any)\n .values(\n mapping.provisioningRequest.encodeInsert(input.requestId, fingerprint, nativeId) as any,\n );\n\n return nativeId;\n }),\n );\n\n const nativeId = yield* attempt.pipe(\n Effect.catchCause(\n (\n cause,\n ): Effect.Effect<\n NativeId,\n | Effect.Error<typeof attempt>\n | Effect.Error<ReturnType<typeof findReceipt>>\n | IdentityConflict\n > => {\n if (\n cause.reasons.length === 0 ||\n !cause.reasons.every(\n (reason) =>\n Cause.isFailReason(reason) &&\n isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),\n )\n )\n return Effect.failCause(cause);\n\n return findReceipt(input.requestId).pipe(\n Effect.flatMap((receipt) => {\n if (receipt !== undefined && receipt.fingerprint === fingerprint)\n return Effect.succeed(receipt.subjectId as NativeId);\n if (input.identifier === undefined) return IdentityConflict.make();\n\n return db\n .select({\n subjectId: column(identifierTable, mapping.identifier.subjectId) as MySqlColumn,\n })\n .from(identifierTable as any)\n .where(\n and(\n eq(identifierNamespaceColumn, input.identifier.namespace),\n eq(identifierValueColumn, input.identifier.value),\n ),\n )\n .limit(1)\n .pipe(Effect.flatMap(() => IdentityConflict.make()));\n }),\n );\n },\n ),\n );\n\n const subjectId = yield* mapping.subjectId.toSubject(nativeId);\n\n return SubjectProvisioned.make({ subjectId });\n }, mapUnavailable);\n\n return { subjectProvisioner: SubjectProvisioner.of({ provision }) } as const;\n});\n\nexport const makeMysqlExternalIdentityServices = Effect.fnUntraced(function* <\n Subject extends AnyMySqlTable,\n External extends AnyMySqlTable,\n NativeId,\n>(mapping: ExternalIdentityTables<Subject, External, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\n\n const db = database as RuntimeDatabase;\n const externalTable = mapping.externalIdentity.table;\n\n const externalProviderColumn = column(\n externalTable,\n mapping.externalIdentity.provider,\n ) as MySqlColumn;\n\n const externalIssuerColumn = column(\n externalTable,\n mapping.externalIdentity.issuer,\n ) as MySqlColumn;\n\n const externalSubjectColumn = column(\n externalTable,\n mapping.externalIdentity.subject,\n ) as MySqlColumn;\n\n const externalSubjectIdColumn = column(\n externalTable,\n mapping.externalIdentity.subjectId,\n ) as MySqlColumn;\n\n const subjectIdColumn = column(mapping.subject.table, mapping.subject.id) as MySqlColumn;\n const subjectStatusColumn = column(mapping.subject.table, mapping.subject.status) as MySqlColumn;\n\n const bind = Effect.fn(\"DrizzleMysqlIdentity.bindExternalIdentity\")(function* (\n subjectId: SubjectId,\n identity: ExternalIdentity,\n ) {\n const nativeId = yield* mapping.subjectId.toNative(subjectId);\n\n const decision = yield* db\n .transaction((tx) =>\n Effect.gen(function* () {\n const subjects = yield* tx\n .select({ status: subjectStatusColumn })\n .from(mapping.subject.table as any)\n .where(eq(subjectIdColumn, nativeId))\n .for(\"update\")\n .limit(1);\n\n if (subjects[0] === undefined || !mapping.subject.isActiveStatus(subjects[0].status))\n return { _tag: \"conflict\" } as const;\n\n const links = yield* tx\n .select({ subjectId: externalSubjectIdColumn })\n .from(externalTable as any)\n .where(\n and(\n eq(externalProviderColumn, identity.provider),\n eq(externalIssuerColumn, identity.issuer),\n eq(externalSubjectColumn, identity.subject),\n ),\n )\n .for(\"update\")\n .limit(1);\n\n if (links[0] !== undefined)\n return mapping.subjectId.equals(links[0].subjectId as NativeId, nativeId)\n ? ({ _tag: \"bound\" } as const)\n : ({ _tag: \"conflict\" } as const);\n yield* tx\n .insert(externalTable as any)\n .values(mapping.externalIdentity.encodeInsert(identity, nativeId) as any);\n\n return { _tag: \"bound\" } as const;\n }),\n )\n .pipe(\n Effect.catchCause((cause) => {\n if (\n cause.reasons.length === 0 ||\n !cause.reasons.every(\n (reason) =>\n Cause.isFailReason(reason) &&\n isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),\n )\n )\n return Effect.failCause(cause);\n\n return db\n .select({ subjectId: externalSubjectIdColumn })\n .from(externalTable as any)\n .where(\n and(\n eq(externalProviderColumn, identity.provider),\n eq(externalIssuerColumn, identity.issuer),\n eq(externalSubjectColumn, identity.subject),\n ),\n )\n .limit(1)\n .pipe(\n Effect.map((rows) =>\n rows[0] !== undefined &&\n mapping.subjectId.equals(rows[0].subjectId as NativeId, nativeId)\n ? ({ _tag: \"bound\" } as const)\n : ({ _tag: \"conflict\" } as const),\n ),\n );\n }),\n );\n\n if (decision._tag === \"conflict\") return yield* IdentityConflict.make();\n }, mapUnavailable);\n\n return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) } as const;\n});\n\nexport const makeMysqlIdentityServices = Effect.fnUntraced(function* <\n Subject extends AnyMySqlTable,\n Identifier extends AnyMySqlTable,\n External extends AnyMySqlTable,\n Request extends AnyMySqlTable,\n NativeId,\n>(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {\n return {\n ...(yield* makeMysqlSubjectProvisioningServices(mapping)),\n ...(yield* makeMysqlExternalIdentityServices(mapping)),\n };\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mysql-identity.mjs","names":["DatabaseService","PersistenceMappingError"],"sources":["../../src/drizzle/mysql-identity.ts"],"sourcesContent":["import { withStorageValidation, NativeDatabase } from \"@yielded/auth-persistence/Adapter\";\nimport {\n ExternalIdentityMutation,\n type ExternalIdentity,\n IdentityConflict,\n IdentityUnavailable,\n SubjectProvisioned,\n SubjectProvisioner,\n type SubjectProvisioningInput,\n} from \"@yielded/auth/Identity\";\nimport { reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport type { SubjectId } from \"@yielded/auth/Schema\";\n/* oxlint-disable no-explicit-any -- Drizzle generic query types are narrowed at this technology boundary. */\nimport { and, eq } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable, MySqlColumn } from \"drizzle-orm/mysql-core\";\nimport { Cause, Effect, Schema } from \"effect\";\n\nimport {\n column,\n isMappedConstraintConflict,\n PersistenceMappingError,\n provisioningFingerprint,\n type ExternalIdentityTables,\n type IdentityTables,\n type SubjectProvisioningTables,\n} from \"./model\";\nimport { Database as DatabaseService } from \"./mysql-database\";\nimport { nativeDatabase } from \"./native-database\";\nimport { validateDrizzleStorage } from \"./storage-validation\";\n\ntype RuntimeDatabase = EffectMysql2Database<any>;\nconst unavailable = () => IdentityUnavailable.make();\nconst isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));\n\nconst mapUnavailable = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n reportPersistenceFailure(effect, isIdentityFailure).pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) => (isIdentityFailure(error) ? error : unavailable())),\n ),\n ),\n );\n\nexport const makeMysqlSubjectProvisioningServices = Effect.fnUntraced(function* <\n Subject extends AnyMySqlTable,\n Identifier extends AnyMySqlTable,\n Request extends AnyMySqlTable,\n NativeId,\n>(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\n\n const db = database as RuntimeDatabase;\n const requestTable = mapping.provisioningRequest.table;\n\n const requestIdColumn = column(\n requestTable,\n mapping.provisioningRequest.requestId,\n ) as MySqlColumn;\n\n const requestFingerprintColumn = column(\n requestTable,\n mapping.provisioningRequest.fingerprint,\n ) as MySqlColumn;\n\n const requestSubjectColumn = column(\n requestTable,\n mapping.provisioningRequest.subjectId,\n ) as MySqlColumn;\n\n const identifierTable = mapping.identifier.table;\n\n const identifierNamespaceColumn = column(\n identifierTable,\n mapping.identifier.namespace,\n ) as MySqlColumn;\n\n const identifierValueColumn = column(identifierTable, mapping.identifier.value) as MySqlColumn;\n\n const findReceipt = Effect.fn(\"DrizzleMysqlIdentity.findReceipt\")(function* (requestId: string) {\n const rows = yield* db\n .select({ fingerprint: requestFingerprintColumn, subjectId: requestSubjectColumn })\n .from(requestTable as any)\n .where(eq(requestIdColumn, requestId))\n .limit(1);\n\n return rows[0];\n });\n\n const provision = Effect.fn(\"DrizzleMysqlIdentity.provision\")(function* (\n input: SubjectProvisioningInput,\n ) {\n const fingerprint = provisioningFingerprint(input);\n const existing = yield* findReceipt(input.requestId);\n\n if (existing !== undefined) {\n if (existing.fingerprint !== fingerprint) return yield* IdentityConflict.make();\n const subjectId = yield* mapping.subjectId.toSubject(existing.subjectId as NativeId);\n\n return SubjectProvisioned.make({ subjectId });\n }\n\n const attempt = db.transaction((tx) =>\n Effect.gen(function* () {\n const allocated =\n mapping.subject.allocateId === undefined\n ? mapping.subject.allocateIdSync?.()\n : yield* mapping.subject.allocateId;\n\n const insert = tx\n .insert(mapping.subject.table as any)\n .values(mapping.subject.encodeInsert(input, allocated) as any);\n\n let nativeId = allocated;\n\n if (nativeId === undefined) {\n if (mapping.subject.decodeGeneratedId === undefined)\n return yield* PersistenceMappingError.make({\n operation: \"provisionSubject.generatedId\",\n cause: new Error(\"MySQL generated IDs require decodeGeneratedId\"),\n });\n const ids = yield* insert.$returningId();\n\n nativeId = yield* mapping.subject.decodeGeneratedId(ids as ReadonlyArray<unknown>);\n } else {\n yield* insert;\n }\n if (input.identifier !== undefined)\n yield* tx\n .insert(identifierTable as any)\n .values(\n mapping.identifier.encodeInsert(input.identifier, nativeId, input.verifiedAt) as any,\n );\n yield* tx\n .insert(requestTable as any)\n .values(\n mapping.provisioningRequest.encodeInsert(input.requestId, fingerprint, nativeId) as any,\n );\n\n return nativeId;\n }),\n );\n\n const nativeId = yield* attempt.pipe(\n Effect.catchCause(\n (\n cause,\n ): Effect.Effect<\n NativeId,\n | Effect.Error<typeof attempt>\n | Effect.Error<ReturnType<typeof findReceipt>>\n | IdentityConflict\n > => {\n if (\n cause.reasons.length === 0 ||\n !cause.reasons.every(\n (reason) =>\n Cause.isFailReason(reason) &&\n isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),\n )\n )\n return Effect.failCause(cause);\n\n return findReceipt(input.requestId).pipe(\n Effect.flatMap((receipt) => {\n if (receipt !== undefined && receipt.fingerprint === fingerprint)\n return Effect.succeed(receipt.subjectId as NativeId);\n if (input.identifier === undefined) return IdentityConflict.make();\n\n return db\n .select({\n subjectId: column(identifierTable, mapping.identifier.subjectId) as MySqlColumn,\n })\n .from(identifierTable as any)\n .where(\n and(\n eq(identifierNamespaceColumn, input.identifier.namespace),\n eq(identifierValueColumn, input.identifier.value),\n ),\n )\n .limit(1)\n .pipe(Effect.flatMap(() => IdentityConflict.make()));\n }),\n );\n },\n ),\n );\n\n const subjectId = yield* mapping.subjectId.toSubject(nativeId);\n\n return SubjectProvisioned.make({ subjectId });\n }, mapUnavailable);\n\n return { subjectProvisioner: SubjectProvisioner.of({ provision }) } as const;\n});\n\nexport const makeMysqlExternalIdentityServices = Effect.fnUntraced(function* <\n Subject extends AnyMySqlTable,\n External extends AnyMySqlTable,\n NativeId,\n>(mapping: ExternalIdentityTables<Subject, External, NativeId>) {\n const database = yield* DatabaseService;\n\n yield* validateDrizzleStorage(mapping).pipe(\n Effect.provideServiceEffect(NativeDatabase, nativeDatabase(DatabaseService)),\n Effect.mapError(() => IdentityUnavailable.make()),\n );\n\n const db = database as RuntimeDatabase;\n const externalTable = mapping.externalIdentity.table;\n\n const externalProviderColumn = column(\n externalTable,\n mapping.externalIdentity.provider,\n ) as MySqlColumn;\n\n const externalIssuerColumn = column(\n externalTable,\n mapping.externalIdentity.issuer,\n ) as MySqlColumn;\n\n const externalSubjectColumn = column(\n externalTable,\n mapping.externalIdentity.subject,\n ) as MySqlColumn;\n\n const externalSubjectIdColumn = column(\n externalTable,\n mapping.externalIdentity.subjectId,\n ) as MySqlColumn;\n\n const subjectIdColumn = column(mapping.subject.table, mapping.subject.id) as MySqlColumn;\n const subjectStatusColumn = column(mapping.subject.table, mapping.subject.status) as MySqlColumn;\n\n const bind = Effect.fn(\"DrizzleMysqlIdentity.bindExternalIdentity\")(function* (\n subjectId: SubjectId,\n identity: ExternalIdentity,\n ) {\n const nativeId = yield* mapping.subjectId.toNative(subjectId);\n\n const decision = yield* db\n .transaction((tx) =>\n Effect.gen(function* () {\n const subjects = yield* tx\n .select({ status: subjectStatusColumn })\n .from(mapping.subject.table as any)\n .where(eq(subjectIdColumn, nativeId))\n .for(\"update\")\n .limit(1);\n\n if (subjects[0] === undefined || !mapping.subject.isActiveStatus(subjects[0].status))\n return { _tag: \"conflict\" } as const;\n\n const links = yield* tx\n .select({ subjectId: externalSubjectIdColumn })\n .from(externalTable as any)\n .where(\n and(\n eq(externalProviderColumn, identity.provider),\n eq(externalIssuerColumn, identity.issuer),\n eq(externalSubjectColumn, identity.subject),\n ),\n )\n .for(\"update\")\n .limit(1);\n\n if (links[0] !== undefined)\n return mapping.subjectId.equals(links[0].subjectId as NativeId, nativeId)\n ? ({ _tag: \"bound\" } as const)\n : ({ _tag: \"conflict\" } as const);\n yield* tx\n .insert(externalTable as any)\n .values(mapping.externalIdentity.encodeInsert(identity, nativeId) as any);\n\n return { _tag: \"bound\" } as const;\n }),\n )\n .pipe(\n Effect.catchCause((cause) => {\n if (\n cause.reasons.length === 0 ||\n !cause.reasons.every(\n (reason) =>\n Cause.isFailReason(reason) &&\n isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),\n )\n )\n return Effect.failCause(cause);\n\n return db\n .select({ subjectId: externalSubjectIdColumn })\n .from(externalTable as any)\n .where(\n and(\n eq(externalProviderColumn, identity.provider),\n eq(externalIssuerColumn, identity.issuer),\n eq(externalSubjectColumn, identity.subject),\n ),\n )\n .limit(1)\n .pipe(\n Effect.map((rows) =>\n rows[0] !== undefined &&\n mapping.subjectId.equals(rows[0].subjectId as NativeId, nativeId)\n ? ({ _tag: \"bound\" } as const)\n : ({ _tag: \"conflict\" } as const),\n ),\n );\n }),\n );\n\n if (decision._tag === \"conflict\") return yield* IdentityConflict.make();\n }, mapUnavailable);\n\n return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) } as const;\n});\n\nexport const makeMysqlIdentityServices = Effect.fnUntraced(function* <\n Subject extends AnyMySqlTable,\n Identifier extends AnyMySqlTable,\n External extends AnyMySqlTable,\n Request extends AnyMySqlTable,\n NativeId,\n>(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {\n return {\n ...(yield* makeMysqlSubjectProvisioningServices(mapping)),\n ...(yield* makeMysqlExternalIdentityServices(mapping)),\n };\n}, withStorageValidation);\n"],"mappings":"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"}
|
|
@@ -17,14 +17,14 @@ const accountCurrent = (mapping, subjectId) => Effect.gen(function* () {
|
|
|
17
17
|
const authorization = (mapping, current, auth, action, flowId, commandId, intent, maximumAge) => Effect.flatMap(CurrentOAuthTransaction, (owner) => Effect.gen(function* () {
|
|
18
18
|
const now = yield* owner.now(mapping.clock);
|
|
19
19
|
const currentRequirement = snapshotOAuthSync(AuthenticationRequirement, mapping.subject.decodeActionRequirement(copiedRow(current.row), action));
|
|
20
|
-
if (!validAction(auth, {
|
|
20
|
+
if (!(yield* validAction(auth, {
|
|
21
21
|
moduleId: auth.challenge.moduleId,
|
|
22
22
|
action,
|
|
23
23
|
flowId,
|
|
24
24
|
commandId,
|
|
25
25
|
revision: current.revision,
|
|
26
26
|
intent
|
|
27
|
-
}, currentRequirement, now, maximumAge)) return false;
|
|
27
|
+
}, currentRequirement, now, maximumAge))) return false;
|
|
28
28
|
const age = Math.min(maximumAge, auth.requirement.maximumAgeMillis, currentRequirement.maximumAgeMillis);
|
|
29
29
|
const fresh = auth.evidence.proofs.filter((proof) => now - DateTime.toEpochMillis(proof.verifiedAt) < age);
|
|
30
30
|
invariant(fresh.length > 0);
|
|
@@ -197,7 +197,7 @@ const targetCredential = (mapping, moduleId, credentialId, current) => Effect.fl
|
|
|
197
197
|
issuer: ownership[t.issuer],
|
|
198
198
|
subject: ownership[t.externalSubject]
|
|
199
199
|
};
|
|
200
|
-
invariant(oauthIdentityKey(identity) === row[cr.identityKey]);
|
|
200
|
+
invariant((yield* oauthIdentityKey(identity)) === row[cr.identityKey]);
|
|
201
201
|
if (current.revision.credentials.find((item) => item.credentialId === credentialId)?.revision !== row[cr.credentialRevision] || !(yield* owner.check(sql`exists(select 1 from ${cr.table} where ${both(eq(col(cr.table, cr.credentialId), credentialId), cr.activeCondition)})`))) return void 0;
|
|
202
202
|
return snapshotOAuthSync(OAuthCredentialSnapshot, {
|
|
203
203
|
moduleId,
|
|
@@ -273,12 +273,13 @@ const unlink = (mapping, input) => Effect.flatMap(CurrentOAuthTransaction, (owne
|
|
|
273
273
|
const guards = mapping.connectedReferenceGuards ?? [];
|
|
274
274
|
invariant(guards.length <= 32);
|
|
275
275
|
let referencesGuarded = mapping.connectedReference !== void 0 && guards.length > 0;
|
|
276
|
-
if (mapping.connectedReference !== void 0) {
|
|
277
|
-
|
|
276
|
+
if (mapping.connectedReference !== void 0) for (const guard of guards) {
|
|
277
|
+
const condition = guard.condition({
|
|
278
278
|
identity: snapshotOAuthSync(OAuthCredentialSnapshot.fields.identity, expected.identity),
|
|
279
|
-
identityKey: oauthIdentityKey(expected.identity),
|
|
279
|
+
identityKey: yield* oauthIdentityKey(expected.identity),
|
|
280
280
|
subjectId: copiedRow({ value: current.nativeId }).value
|
|
281
|
-
})
|
|
281
|
+
});
|
|
282
|
+
if ((yield* owner.read(guard.table, Effect.isEffect(condition) ? yield* condition : condition, { orderBy: col(guard.table, guard.orderBy) })).rows.length === 0) referencesGuarded = false;
|
|
282
283
|
}
|
|
283
284
|
const command = yield* unlinkCommand(mapping, input.moduleId, input.commandId), r = mapping.command;
|
|
284
285
|
const previous = command.rows[0];
|
|
@@ -299,7 +300,7 @@ const unlink = (mapping, input) => Effect.flatMap(CurrentOAuthTransaction, (owne
|
|
|
299
300
|
if (auth.challenge.moduleId !== input.moduleId || !(yield* authorization(mapping, current, auth, "unlink", input.commandId, input.commandId, credentialStorage.encode(expected), auth.requirement.maximumAgeMillis))) return { _tag: "Rejected" };
|
|
300
301
|
if (!(yield* remainingEligibility(mapping, current, expected.credentialId))) return { _tag: "LastSignInMethod" };
|
|
301
302
|
const invalidation = checkInvalidation(mapping, input.invalidation), cr = mapping.credential, a = mapping.authority;
|
|
302
|
-
const key = oauthIdentityKey(expected.identity), t = mapping.ownership.tuple;
|
|
303
|
+
const key = yield* oauthIdentityKey(expected.identity), t = mapping.ownership.tuple;
|
|
303
304
|
const connected = mapping.connectedReference?.({
|
|
304
305
|
identityKey: key,
|
|
305
306
|
subjectId: copiedRow({ value: current.nativeId }).value
|