@yielded/auth-persistence-drizzle 0.1.0-beta.14 → 0.1.0-beta.16

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.
Files changed (190) hide show
  1. package/dist/D1.d.mts +123 -9
  2. package/dist/Libsql.d.mts +141 -27
  3. package/dist/Mysql2.d.mts +124 -10
  4. package/dist/Pglite.d.mts +124 -10
  5. package/dist/Postgres.d.mts +129 -15
  6. package/dist/SqliteBun.d.mts +135 -21
  7. package/dist/SqliteDo.d.mts +135 -21
  8. package/dist/SqliteNode.d.mts +135 -21
  9. package/dist/SqliteWasm.d.mts +135 -21
  10. package/dist/drizzle/d1-emails.d.mts +3 -3
  11. package/dist/drizzle/d1-emails.mjs +56 -11
  12. package/dist/drizzle/d1-emails.mjs.map +1 -1
  13. package/dist/drizzle/d1-identity.mjs +9 -2
  14. package/dist/drizzle/d1-identity.mjs.map +1 -1
  15. package/dist/drizzle/d1-oauth.d.mts +6 -6
  16. package/dist/drizzle/d1-oauth.mjs +8 -8
  17. package/dist/drizzle/d1-oauth.mjs.map +1 -1
  18. package/dist/drizzle/d1-passkey.d.mts +2 -1
  19. package/dist/drizzle/d1-passkey.mjs +10 -8
  20. package/dist/drizzle/d1-passkey.mjs.map +1 -1
  21. package/dist/drizzle/d1-password-prepared.d.mts +1 -1
  22. package/dist/drizzle/d1-password-prepared.mjs +16 -5
  23. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  24. package/dist/drizzle/d1-passwords.d.mts +2 -2
  25. package/dist/drizzle/d1-passwords.mjs +19 -6
  26. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  27. package/dist/drizzle/d1-phone.d.mts +2 -1
  28. package/dist/drizzle/d1-phone.mjs +4 -2
  29. package/dist/drizzle/d1-phone.mjs.map +1 -1
  30. package/dist/drizzle/d1-proofs.d.mts +1 -1
  31. package/dist/drizzle/d1-proofs.mjs +18 -7
  32. package/dist/drizzle/d1-proofs.mjs.map +1 -1
  33. package/dist/drizzle/d1-sessions.d.mts +6 -5
  34. package/dist/drizzle/d1-sessions.mjs +29 -19
  35. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  36. package/dist/drizzle/d1-totp.d.mts +2 -1
  37. package/dist/drizzle/d1-totp.mjs +4 -2
  38. package/dist/drizzle/d1-totp.mjs.map +1 -1
  39. package/dist/drizzle/email-registration.d.mts +5 -1
  40. package/dist/drizzle/email-registration.mjs +48 -4
  41. package/dist/drizzle/email-registration.mjs.map +1 -1
  42. package/dist/drizzle/email-target.d.mts +1 -0
  43. package/dist/drizzle/email-target.mjs +9 -0
  44. package/dist/drizzle/email-target.mjs.map +1 -1
  45. package/dist/drizzle/mysql-emails.d.mts +4 -4
  46. package/dist/drizzle/mysql-emails.mjs +8 -7
  47. package/dist/drizzle/mysql-emails.mjs.map +1 -1
  48. package/dist/drizzle/mysql-identity.mjs +11 -4
  49. package/dist/drizzle/mysql-identity.mjs.map +1 -1
  50. package/dist/drizzle/mysql-password-prepared.d.mts +2 -2
  51. package/dist/drizzle/mysql-password-prepared.mjs +4 -3
  52. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
  53. package/dist/drizzle/mysql-passwords.d.mts +3 -3
  54. package/dist/drizzle/mysql-passwords.mjs +7 -6
  55. package/dist/drizzle/mysql-passwords.mjs.map +1 -1
  56. package/dist/drizzle/mysql-proofs.d.mts +2 -2
  57. package/dist/drizzle/mysql-proofs.mjs +4 -3
  58. package/dist/drizzle/mysql-proofs.mjs.map +1 -1
  59. package/dist/drizzle/mysql-sessions.d.mts +6 -6
  60. package/dist/drizzle/mysql-sessions.mjs +16 -15
  61. package/dist/drizzle/mysql-sessions.mjs.map +1 -1
  62. package/dist/drizzle/native-database.mjs +1 -1
  63. package/dist/drizzle/native-database.mjs.map +1 -1
  64. package/dist/drizzle/oauth-connected-drivers.mjs +10 -8
  65. package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
  66. package/dist/drizzle/oauth-connected-flow.mjs +62 -13
  67. package/dist/drizzle/oauth-connected-flow.mjs.map +1 -1
  68. package/dist/drizzle/oauth-connected-input.mjs +6 -0
  69. package/dist/drizzle/oauth-connected-input.mjs.map +1 -1
  70. package/dist/drizzle/oauth-connected-maintenance.mjs +3 -3
  71. package/dist/drizzle/oauth-connected-maintenance.mjs.map +1 -1
  72. package/dist/drizzle/oauth-connected-target.d.mts +116 -2
  73. package/dist/drizzle/oauth-connected-target.mjs +5 -3
  74. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  75. package/dist/drizzle/oauth-drivers.mjs +8 -8
  76. package/dist/drizzle/oauth-drivers.mjs.map +1 -1
  77. package/dist/drizzle/oauth-target.d.mts +3 -3
  78. package/dist/drizzle/oauth-target.mjs +8 -6
  79. package/dist/drizzle/oauth-target.mjs.map +1 -1
  80. package/dist/drizzle/passkey-drivers.mjs +4 -4
  81. package/dist/drizzle/passkey-drivers.mjs.map +1 -1
  82. package/dist/drizzle/passkey-write-drivers.mjs +4 -4
  83. package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
  84. package/dist/drizzle/passkey-write-target.d.mts +1 -1
  85. package/dist/drizzle/password-prepared-sql.mjs +5 -0
  86. package/dist/drizzle/password-prepared-sql.mjs.map +1 -1
  87. package/dist/drizzle/password-prepared-target.d.mts +2 -1
  88. package/dist/drizzle/password-prepared-target.mjs +5 -0
  89. package/dist/drizzle/password-prepared-target.mjs.map +1 -1
  90. package/dist/drizzle/password-registration.d.mts +1 -1
  91. package/dist/drizzle/password-registration.mjs +2 -0
  92. package/dist/drizzle/password-registration.mjs.map +1 -1
  93. package/dist/drizzle/password-target.d.mts +1 -0
  94. package/dist/drizzle/password-target.mjs +6 -0
  95. package/dist/drizzle/password-target.mjs.map +1 -1
  96. package/dist/drizzle/pg-emails.d.mts +4 -4
  97. package/dist/drizzle/pg-emails.mjs +8 -7
  98. package/dist/drizzle/pg-emails.mjs.map +1 -1
  99. package/dist/drizzle/pg-identity.mjs +12 -5
  100. package/dist/drizzle/pg-identity.mjs.map +1 -1
  101. package/dist/drizzle/pg-password-prepared.d.mts +2 -2
  102. package/dist/drizzle/pg-password-prepared.mjs +4 -3
  103. package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
  104. package/dist/drizzle/pg-passwords.d.mts +3 -3
  105. package/dist/drizzle/pg-passwords.mjs +7 -6
  106. package/dist/drizzle/pg-passwords.mjs.map +1 -1
  107. package/dist/drizzle/pg-proofs.d.mts +2 -2
  108. package/dist/drizzle/pg-proofs.mjs +4 -3
  109. package/dist/drizzle/pg-proofs.mjs.map +1 -1
  110. package/dist/drizzle/pg-sessions.d.mts +6 -6
  111. package/dist/drizzle/pg-sessions.mjs +16 -15
  112. package/dist/drizzle/pg-sessions.mjs.map +1 -1
  113. package/dist/drizzle/phone-target.mjs +11 -2
  114. package/dist/drizzle/phone-target.mjs.map +1 -1
  115. package/dist/drizzle/proof-target.d.mts +1 -0
  116. package/dist/drizzle/proof-target.mjs +2 -0
  117. package/dist/drizzle/proof-target.mjs.map +1 -1
  118. package/dist/drizzle/query-operations.mjs +2 -0
  119. package/dist/drizzle/query-operations.mjs.map +1 -1
  120. package/dist/drizzle/session-target.d.mts +1 -0
  121. package/dist/drizzle/session-target.mjs +9 -6
  122. package/dist/drizzle/session-target.mjs.map +1 -1
  123. package/dist/drizzle/sqlite-emails.mjs +8 -7
  124. package/dist/drizzle/sqlite-emails.mjs.map +1 -1
  125. package/dist/drizzle/sqlite-identity.mjs +7 -2
  126. package/dist/drizzle/sqlite-identity.mjs.map +1 -1
  127. package/dist/drizzle/sqlite-password-prepared.mjs +4 -3
  128. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
  129. package/dist/drizzle/sqlite-passwords.mjs +7 -6
  130. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  131. package/dist/drizzle/sqlite-proofs.mjs +4 -3
  132. package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
  133. package/dist/drizzle/sqlite-sessions.mjs +16 -15
  134. package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
  135. package/dist/drizzle/storage-validation.mjs +234 -0
  136. package/dist/drizzle/storage-validation.mjs.map +1 -0
  137. package/dist/drizzle/totp-target.mjs +5 -2
  138. package/dist/drizzle/totp-target.mjs.map +1 -1
  139. package/dist/drizzle/transaction-mysql.mjs +1 -1
  140. package/package.json +1 -1
  141. package/src/drizzle/d1-emails.ts +158 -40
  142. package/src/drizzle/d1-identity.ts +13 -0
  143. package/src/drizzle/d1-oauth.ts +8 -8
  144. package/src/drizzle/d1-passkey.ts +10 -8
  145. package/src/drizzle/d1-password-prepared.ts +14 -2
  146. package/src/drizzle/d1-passwords.ts +22 -4
  147. package/src/drizzle/d1-phone.ts +4 -2
  148. package/src/drizzle/d1-proofs.ts +55 -3
  149. package/src/drizzle/d1-sessions.ts +67 -18
  150. package/src/drizzle/d1-totp.ts +4 -2
  151. package/src/drizzle/email-registration.ts +160 -12
  152. package/src/drizzle/email-target.ts +22 -4
  153. package/src/drizzle/mysql-emails.ts +17 -7
  154. package/src/drizzle/mysql-identity.ts +13 -0
  155. package/src/drizzle/mysql-password-prepared.ts +7 -3
  156. package/src/drizzle/mysql-passwords.ts +13 -6
  157. package/src/drizzle/mysql-proofs.ts +7 -3
  158. package/src/drizzle/mysql-sessions.ts +31 -15
  159. package/src/drizzle/native-database.ts +5 -4
  160. package/src/drizzle/oauth-connected-drivers.ts +10 -8
  161. package/src/drizzle/oauth-connected-flow.ts +98 -10
  162. package/src/drizzle/oauth-connected-input.ts +7 -0
  163. package/src/drizzle/oauth-connected-maintenance.ts +3 -2
  164. package/src/drizzle/oauth-connected-target.ts +4 -2
  165. package/src/drizzle/oauth-drivers.ts +8 -8
  166. package/src/drizzle/oauth-target.ts +13 -7
  167. package/src/drizzle/passkey-drivers.ts +4 -4
  168. package/src/drizzle/passkey-write-drivers.ts +8 -5
  169. package/src/drizzle/password-prepared-sql.ts +13 -1
  170. package/src/drizzle/password-prepared-target.ts +7 -1
  171. package/src/drizzle/password-registration.ts +10 -3
  172. package/src/drizzle/password-target.ts +22 -4
  173. package/src/drizzle/pg-emails.ts +17 -7
  174. package/src/drizzle/pg-identity.ts +13 -0
  175. package/src/drizzle/pg-password-prepared.ts +7 -3
  176. package/src/drizzle/pg-passwords.ts +13 -6
  177. package/src/drizzle/pg-proofs.ts +7 -3
  178. package/src/drizzle/pg-sessions.ts +31 -15
  179. package/src/drizzle/phone-target.ts +30 -5
  180. package/src/drizzle/proof-target.ts +10 -2
  181. package/src/drizzle/query-operations.ts +2 -0
  182. package/src/drizzle/session-target.ts +20 -3
  183. package/src/drizzle/sqlite-emails.ts +17 -7
  184. package/src/drizzle/sqlite-identity.ts +5 -0
  185. package/src/drizzle/sqlite-password-prepared.ts +7 -3
  186. package/src/drizzle/sqlite-passwords.ts +13 -6
  187. package/src/drizzle/sqlite-proofs.ts +7 -3
  188. package/src/drizzle/sqlite-sessions.ts +31 -15
  189. package/src/drizzle/storage-validation.ts +285 -0
  190. package/src/drizzle/totp-target.ts +16 -4
@@ -2,6 +2,7 @@ import { D1PhoneMapping, PhoneMapping, PhoneMappingSource, PhonePersistenceServi
2
2
  import { Database as Database$1 } from "./d1-database.mjs";
3
3
  import { D1BatchStatements } from "./D1BatchStatements.mjs";
4
4
  import { PhoneCoordinatorError } from "./phone-target.mjs";
5
+ import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
5
6
  import { AnyRelations } from "drizzle-orm";
6
7
  import { Effect } from "effect";
7
8
  import { LifecycleHooks } from "@yielded/auth/Hooks";
@@ -14,7 +15,7 @@ type Database = EffectSQLiteD1Database<AnyRelations> & {
14
15
  readonly $client: D1Client;
15
16
  };
16
17
  type Table$1 = AnySQLiteTable;
17
- 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, import("@yielded/auth-persistence/Adapter").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, Database$1 | LifecycleHooks | Exclude<RSetup, NativeDatabase>>;
18
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: {
19
20
  readonly mapping: PhoneMappingSource<PhoneMapping<S, I, C, F, N> & D1PhoneMapping, RSetup>;
20
21
  }, body: Effect.Effect<A, E, R>) => Effect.Effect<A, PhoneCoordinatorError<E> | DatabaseError, Exclude<R, PhonePersistence | PhoneAdmission | PhoneSignInTargets | D1BatchStatements> | LifecycleHooks | RSetup | DatabaseRequirements>;
@@ -1,7 +1,9 @@
1
1
  import { Database } from "./d1-database.mjs";
2
2
  import { D1BatchStatements } from "./D1BatchStatements.mjs";
3
3
  import { makeD1Owner } from "./d1-planning.mjs";
4
+ import { nativeDatabase } from "./native-database.mjs";
4
5
  import { coordinateTargetPhone, makePhoneTarget } from "./phone-target.mjs";
6
+ import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
5
7
  import { Context, Effect } from "effect";
6
8
  import { PhoneAdmission, PhoneOtpUnavailable, PhonePersistence, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
7
9
  //#region src/drizzle/d1-phone.ts
@@ -12,7 +14,7 @@ const configuration = {
12
14
  standaloneGuard: () => Effect.void
13
15
  };
14
16
  const { makePhonePersistenceServices } = makePhoneTarget(Database, configuration);
15
- const coordinatePhonePersistence = (acquire, options, body) => Effect.flatMap(acquire, (database) => coordinateTargetPhone(database, options.mapping, configuration, (_transaction, services, append) => Effect.gen(function* () {
17
+ const coordinatePhonePersistence = (acquire, options, body) => Effect.flatMap(nativeDatabase(acquire), (database) => coordinateTargetPhone(database, options.mapping, configuration, (_transaction, services, append) => Effect.gen(function* () {
16
18
  const original = services.phonePersistence;
17
19
  const nativeCollector = D1BatchStatements.of({ append: (statement) => Effect.sync(() => append(statement)) });
18
20
  const owner = yield* makeD1Owner(PhoneOtpUnavailable.make({})).pipe(Effect.provideService(D1BatchStatements, nativeCollector));
@@ -24,7 +26,7 @@ const coordinatePhonePersistence = (acquire, options, body) => Effect.flatMap(ac
24
26
  cleanup: (input) => owner.run(services.phoneAdmission.cleanup(input))
25
27
  }), Context.add(PhoneSignInTargets, { lookup: (input) => owner.run(services.phoneSignInTargets.lookup(input)) }));
26
28
  return yield* owner.close(Effect.provideContext(body, provided));
27
- })));
29
+ })).pipe(Effect.provideService(NativeDatabase, database)));
28
30
  //#endregion
29
31
  export { coordinatePhonePersistence, makePhonePersistenceServices };
30
32
 
@@ -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 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 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(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 ),\n );\n"],"mappings":";;;;;;;AAqBA,MAAM,gBAAgB;CACpB,MAAM;CACN,SAAS;CACT,SAAS;CACT,uBAAuB,OAAO;AAChC;AAQA,MAAa,EAAE,iCALA,gBACbA,UACA,aAG8C;AAEhD,MAAa,8BAcX,SACA,SAGA,SASA,OAAO,QAAQ,UAAU,aACvB,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,CACF"}
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,SASA,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"}
@@ -66,7 +66,7 @@ export declare const makeD1ProofPersistenceServices: <Rq extends AnySQLiteTable,
66
66
  readonly limit: number;
67
67
  }, prepare: PrepareProofCommit<ProofCleanupResult, A_1>) => Effect.Effect<PreparedCommit<A_1>, ProofUnavailable>;
68
68
  };
69
- }, never, Database$1 | LifecycleHooks>;
69
+ }, ProofUnavailable, Database$1 | LifecycleHooks>;
70
70
  type CoordinatorError<E> = E | ProofUnavailable | HookConfigurationError;
71
71
  /**
72
72
  * Owns one proof transition plus application statements in one D1 batch. It
@@ -1,9 +1,12 @@
1
1
  import { requiredProofConstraints } from "./proof-model.mjs";
2
- import { PersistenceMappingError, column, isMappedConstraintConflict, updateValues } from "./model.mjs";
2
+ import { PersistenceMappingError as PersistenceMappingError$1, column, isMappedConstraintConflict, updateValues } from "./model.mjs";
3
3
  import { balancedD1And } from "./d1-generated-statement.mjs";
4
+ import { validateDrizzleStorage } from "./storage-validation.mjs";
4
5
  import { Database } from "./d1-database.mjs";
5
6
  import { D1BatchStatements } from "./D1BatchStatements.mjs";
6
7
  import { CurrentD1PlanningDatabase, makeD1Owner } from "./d1-planning.mjs";
8
+ import { nativeDatabase } from "./native-database.mjs";
9
+ import { NativeDatabase } from "@yielded/auth-persistence/Adapter";
7
10
  import { and, count, eq, gte, inArray, isNull, lte, notExists, or, sql } from "drizzle-orm";
8
11
  import { Cause, Context, Effect, Schema } from "effect";
9
12
  import { CurrentCommitJournal, HookConfigurationError, LifecycleHooks, coordinateCommit, hasCommitScope } from "@yielded/auth/Hooks";
@@ -62,7 +65,7 @@ const assertion = Effect.fn(function* (condition, marker) {
62
65
  });
63
66
  const allocateVersion = (mapping) => mapping.allocateVersion !== void 0 ? mapping.allocateVersion : mapping.allocateVersionSync === void 0 ? Effect.fail(unavailable()) : Effect.try({
64
67
  try: mapping.allocateVersionSync,
65
- catch: (cause) => new PersistenceMappingError({
68
+ catch: (cause) => new PersistenceMappingError$1({
66
69
  operation: "mapping",
67
70
  cause
68
71
  })
@@ -309,8 +312,12 @@ const issuePlan = Effect.fn("Drizzle.issuePlan")(function* (mapping, input, prep
309
312
  const existingSeries = actionOpen ? (yield* readSeries(mapping, input.record.moduleId, input.record.purpose, keys.series))[0] : void 0;
310
313
  const seriesVersion = yield* allocateVersion(mapping);
311
314
  const active = existingSeries?.[mapping.series.activeProofId];
315
+ const activeGeneration = active === null || active === void 0 ? void 0 : (yield* readGeneration(mapping, input.record.moduleId, active))[0];
316
+ if (active !== null && active !== void 0 && (activeGeneration === void 0 || activeGeneration[mapping.generation.purpose] !== input.record.purpose)) return yield* unavailable();
317
+ const matchesActiveBinding = activeGeneration !== void 0 && sameBinding(yield* mapping.generation.decodeBinding(activeGeneration), input.record.binding);
318
+ const replacesLiveProof = activeGeneration !== void 0 && activeGeneration[mapping.generation.state] === "active" && (yield* mapping.decodeInstant(activeGeneration[mapping.generation.expiresAt])) > now;
312
319
  const lastIssue = existingSeries?.[mapping.series.lastIssueAt] === null || existingSeries?.[mapping.series.lastIssueAt] === void 0 ? void 0 : yield* mapping.decodeInstant(existingSeries[mapping.series.lastIssueAt]);
313
- const allowed = current.current && input.eligible && admitted.length === scopes.length && input.record.issuedAtMillis <= now && input.record.expiresAtMillis > now && (input.supersedes === void 0 || input.supersedes === active) && (lastIssue === void 0 || now - lastIssue >= input.policy.abuse.resendCooldownMillis);
320
+ const allowed = current.current && input.eligible && admitted.length === scopes.length && input.record.issuedAtMillis <= now && input.record.expiresAtMillis > now && (!replacesLiveProof || matchesActiveBinding) && (input.supersedes === void 0 || input.supersedes === active) && (lastIssue === void 0 || now - lastIssue >= input.policy.abuse.resendCooldownMillis);
314
321
  const receipt = {
315
322
  requestId: input.record.requestId,
316
323
  reference: {
@@ -333,11 +340,13 @@ const issuePlan = Effect.fn("Drizzle.issuePlan")(function* (mapping, input, prep
333
340
  record: input.record,
334
341
  createdAtMillis: now,
335
342
  retentionUntilMillis: retentionUntil
336
- }), [[mapping.request.createdAt, mapping.d1.engineNow], [mapping.request.retentionUntil, mapping.d1.engineInstantPlus(input.policy.requestRetentionMillis)]]))), ...yield* anchorStatements(mapping, input.record.moduleId, input.record.purpose, "issue", actionOpen ? scopes : scopes.slice(0, 1), keys.series, seriesVersion, actionOpen), ...yield* insertScopeStatements(mapping, input.record.moduleId, input.record.purpose, "issue", input.record.requestId, admitted, now, retentionUntil, marker));
343
+ }), [[mapping.request.createdAt, mapping.d1.engineNow], [mapping.request.retentionUntil, mapping.d1.engineInstantPlus(input.policy.requestRetentionMillis)]]))), ...yield* anchorStatements(mapping, input.record.moduleId, input.record.purpose, "issue", actionOpen ? scopes : scopes.slice(0, 1), keys.series, seriesVersion, actionOpen), ...yield* insertScopeStatements(mapping, input.record.moduleId, input.record.purpose, "issue", input.record.requestId, allowed ? scopes : [], now, retentionUntil, marker));
337
344
  if (allowed) {
338
345
  const sc = seriesColumns(mapping);
346
+ const gc = generationColumns(mapping);
347
+ const replacementCondition = activeGeneration === void 0 ? sql`1 = 1` : sql`exists(select 1 from ${mapping.generation.table} where ${and(eq(gc.moduleId, input.record.moduleId), eq(gc.proofId, activeGeneration[mapping.generation.proofId]), eq(gc.version, activeGeneration[mapping.generation.version]), eq(column(mapping.generation.table, mapping.generation.binding), activeGeneration[mapping.generation.binding]), matchesActiveBinding ? sql`1 = 1` : sql`(${gc.state} <> 'active' or ${gc.expiresAt} <= ${mapping.d1.engineNow})`)})`;
339
348
  const seriesCondition = and(eq(sc.moduleId, input.record.moduleId), eq(sc.purpose, input.record.purpose), eq(sc.scopeKey, keys.series), active === null || active === void 0 ? or(eq(sc.activeProofId, null), sql`${sc.activeProofId} is null`) : eq(sc.activeProofId, active), lastIssue === void 0 ? sql`1 = 1` : lte(sc.lastIssueAt, mapping.d1.engineInstantMinus(input.policy.abuse.resendCooldownMillis)));
340
- statements.push(yield* assertion(and(current.condition, sql`${mapping.d1.engineNowMillis} >= ${input.record.issuedAtMillis}`, sql`${mapping.d1.engineNow} < ${sql.param(mapping.encodeInstant(input.record.expiresAtMillis), generationColumns(mapping).expiresAt)}`, sql`exists(select 1 from ${mapping.series.table} where ${seriesCondition})`), marker));
349
+ statements.push(yield* assertion(and(current.condition, replacementCondition, sql`${mapping.d1.engineNowMillis} >= ${input.record.issuedAtMillis}`, sql`${mapping.d1.engineNow} < ${sql.param(mapping.encodeInstant(input.record.expiresAtMillis), generationColumns(mapping).expiresAt)}`, sql`exists(select 1 from ${mapping.series.table} where ${seriesCondition})`), marker));
341
350
  if (active !== null && active !== void 0) statements.push(yield* statement(database.update(mapping.generation.table).set(updateValues([[mapping.generation.state, "superseded"]])).where(and(eq(generationColumns(mapping).moduleId, input.record.moduleId), eq(generationColumns(mapping).proofId, active), eq(generationColumns(mapping).state, "active")))));
342
351
  statements.push(yield* statement(database.insert(mapping.generation.table).values(driverValues(mapping.generation.encodeInsert({
343
352
  record: input.record,
@@ -733,6 +742,7 @@ const makeProofPlans = (mapping) => {
733
742
  };
734
743
  const makeD1ProofPersistenceServices = Effect.fnUntraced(function* (mapping) {
735
744
  const database = yield* Database;
745
+ yield* validateDrizzleStorage(mapping).pipe(Effect.provideServiceEffect(NativeDatabase, nativeDatabase(Database)), Effect.mapError(unavailable));
736
746
  const hooks = yield* LifecycleHooks;
737
747
  const plans = makeProofPlans(mapping);
738
748
  const run = (plan) => Effect.gen(function* () {
@@ -755,7 +765,8 @@ const makeD1ProofPersistenceServices = Effect.fnUntraced(function* (mapping) {
755
765
  * ProofUnavailable so the caller can retry the entire command with fresh secrets.
756
766
  */
757
767
  function coordinateD1ProofPersistence(acquire, options, body) {
758
- return Effect.flatMap(acquire, (database) => Effect.gen(function* () {
768
+ return Effect.flatMap(nativeDatabase(acquire), (database) => Effect.gen(function* () {
769
+ yield* validateDrizzleStorage(options.mapping).pipe(Effect.mapError(unavailable));
759
770
  const hooks = yield* LifecycleHooks;
760
771
  if (yield* hasCommitScope) return yield* unavailable();
761
772
  return (yield* coordinateCommit(() => Effect.gen(function* () {
@@ -794,7 +805,7 @@ function coordinateD1ProofPersistence(acquire, options, body) {
794
805
  yield* database.$client.batch(statements).pipe(Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, (error) => everyFailureMatches(cause, mutation?.retryable) ? unavailable() : error))), translateFailure);
795
806
  return value;
796
807
  }), { mode: "batch" }).pipe(Effect.provideService(LifecycleHooks, hooks))).value;
797
- }));
808
+ }).pipe(Effect.provideService(NativeDatabase, database)));
798
809
  }
799
810
  /** Private compiler seam for a future same-owner D1 password-reset batch. */
800
811
  const compileD1ProofCompletionPlan = Effect.fn("Drizzle.compileD1ProofCompletionPlan")(function* (mapping, plan, protectedMutation, project) {