@fragno-dev/db 0.1.15 → 0.2.0

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 (407) hide show
  1. package/.turbo/turbo-build.log +242 -179
  2. package/CHANGELOG.md +23 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +5 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -21
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -54
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +3 -0
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +36 -28
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -18
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -165
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +47 -61
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{drizzle/shared.d.ts → shared/table-name-mapper.d.ts} +2 -4
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +53 -19
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +89 -19
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/fragments/internal-fragment.d.ts +39 -5
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  85. package/dist/fragments/internal-fragment.js +82 -10
  86. package/dist/fragments/internal-fragment.js.map +1 -1
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +23 -61
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +34 -10
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +47 -16
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/{rou3@0.7.8 → rou3@0.7.10}/node_modules/rou3/dist/index.js +1 -1
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/fragment-instantiator.js +69 -31
  102. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  103. package/dist/query/column-defaults.js +27 -0
  104. package/dist/query/column-defaults.js.map +1 -0
  105. package/dist/query/cursor.d.ts +4 -4
  106. package/dist/query/cursor.d.ts.map +1 -1
  107. package/dist/query/cursor.js +8 -6
  108. package/dist/query/cursor.js.map +1 -1
  109. package/dist/query/orm/orm.d.ts +1 -1
  110. package/dist/query/orm/orm.js.map +1 -1
  111. package/dist/query/serialize/create-sql-serializer.js +30 -0
  112. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  113. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  114. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  115. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  116. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  117. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  118. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  119. package/dist/query/serialize/sql-serializer.js +67 -0
  120. package/dist/query/serialize/sql-serializer.js.map +1 -0
  121. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +5 -5
  122. package/dist/query/simple-query-interface.d.ts.map +1 -0
  123. package/dist/query/{execute-unit-of-work.d.ts → unit-of-work/execute-unit-of-work.d.ts} +13 -3
  124. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  125. package/dist/query/{execute-unit-of-work.js → unit-of-work/execute-unit-of-work.js} +17 -4
  126. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  127. package/dist/query/{retry-policy.d.ts → unit-of-work/retry-policy.d.ts} +1 -1
  128. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  129. package/dist/query/{retry-policy.js → unit-of-work/retry-policy.js} +1 -1
  130. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  131. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +51 -18
  132. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  133. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +58 -11
  134. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  135. package/dist/query/value-decoding.js +71 -0
  136. package/dist/query/value-decoding.js.map +1 -0
  137. package/dist/query/value-encoding.js +124 -0
  138. package/dist/query/value-encoding.js.map +1 -0
  139. package/dist/schema/create.d.ts +3 -0
  140. package/dist/schema/create.d.ts.map +1 -1
  141. package/dist/schema/create.js +4 -0
  142. package/dist/schema/create.js.map +1 -1
  143. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  144. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  145. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  146. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  147. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  148. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  149. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  150. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  151. package/dist/schema/type-conversion/type-mapping.js +63 -0
  152. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  153. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  154. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  155. package/dist/sql-driver/connection/connection-provider.js +19 -0
  156. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  157. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  158. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  159. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  160. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  161. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  162. package/dist/sql-driver/dialects/dialects.js +3 -0
  163. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  164. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  165. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  166. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  167. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  168. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  169. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  170. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  171. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  172. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  173. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  174. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  175. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  176. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  177. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  178. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  179. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  180. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  181. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  182. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  183. package/dist/sql-driver/sql-driver.d.ts +38 -0
  184. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  185. package/dist/sql-driver/sql-driver.js +1 -0
  186. package/dist/sql-driver/sql.js +50 -0
  187. package/dist/sql-driver/sql.js.map +1 -0
  188. package/dist/with-database.d.ts +6 -2
  189. package/dist/with-database.d.ts.map +1 -1
  190. package/dist/with-database.js +1 -1
  191. package/dist/with-database.js.map +1 -1
  192. package/package.json +37 -10
  193. package/src/adapters/adapters.ts +8 -5
  194. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +60 -169
  195. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +31 -55
  196. package/src/adapters/drizzle/drizzle-adapter.ts +15 -107
  197. package/src/adapters/drizzle/generate.test.ts +2 -2
  198. package/src/adapters/drizzle/generate.ts +78 -34
  199. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  200. package/src/adapters/drizzle/shared.ts +0 -34
  201. package/src/adapters/drizzle/test-utils.ts +3 -3
  202. package/src/adapters/generic-sql/README.md +14 -0
  203. package/src/adapters/generic-sql/driver-config.ts +144 -0
  204. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  205. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  206. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  207. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  208. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  209. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  210. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  211. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  212. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  213. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  214. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  215. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  216. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  217. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  218. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  219. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  220. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  221. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  222. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  223. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  224. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  225. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  226. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  227. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  228. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  229. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  230. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  231. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  232. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  233. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  234. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  235. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  236. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  237. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +26 -76
  238. package/src/adapters/kysely/{kysely-adapter-sqlite.test.ts → kysely-adapter-sqlocal.test.ts} +76 -17
  239. package/src/adapters/kysely/kysely-adapter.ts +10 -250
  240. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +110 -104
  241. package/src/adapters/shared/table-name-mapper.ts +50 -0
  242. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  243. package/src/db-fragment-definition-builder.test.ts +2 -2
  244. package/src/db-fragment-definition-builder.ts +281 -50
  245. package/src/db-fragment-instantiator.test.ts +78 -2
  246. package/src/db-fragment-integration.test.ts +14 -16
  247. package/src/fragments/internal-fragment.test.ts +434 -45
  248. package/src/fragments/internal-fragment.ts +184 -20
  249. package/src/hooks/hooks.test.ts +575 -0
  250. package/src/hooks/hooks.ts +179 -0
  251. package/src/migration-engine/generation-engine.test.ts +44 -54
  252. package/src/migration-engine/generation-engine.ts +48 -94
  253. package/src/mod.ts +117 -29
  254. package/src/query/column-defaults.ts +49 -0
  255. package/src/query/cursor.test.ts +31 -6
  256. package/src/query/cursor.ts +11 -7
  257. package/src/query/orm/orm.ts +1 -1
  258. package/src/query/query-type.test.ts +9 -9
  259. package/src/query/serialize/create-sql-serializer.ts +34 -0
  260. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  261. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  262. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  263. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  264. package/src/query/serialize/sql-serializer.ts +143 -0
  265. package/src/query/{query.ts → simple-query-interface.ts} +2 -2
  266. package/src/query/{execute-unit-of-work.test.ts → unit-of-work/execute-unit-of-work.test.ts} +16 -16
  267. package/src/query/{execute-unit-of-work.ts → unit-of-work/execute-unit-of-work.ts} +49 -8
  268. package/src/query/{unit-of-work-coordinator.test.ts → unit-of-work/unit-of-work-coordinator.test.ts} +41 -43
  269. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +5 -3
  270. package/src/query/{unit-of-work.test.ts → unit-of-work/unit-of-work.test.ts} +100 -9
  271. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +135 -32
  272. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -427
  273. package/src/query/value-decoding.ts +113 -0
  274. package/src/query/value-encoding.test.ts +390 -0
  275. package/src/query/value-encoding.ts +168 -0
  276. package/src/schema/create.test.ts +5 -1
  277. package/src/schema/create.ts +5 -0
  278. package/src/schema/serialize.test.ts +165 -407
  279. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  280. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  281. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  282. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  283. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  284. package/src/schema/type-conversion/type-mapping.ts +153 -0
  285. package/src/shared/connection-pool.ts +5 -5
  286. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  287. package/src/sql-driver/connection/connection-provider.ts +27 -0
  288. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  289. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  290. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  291. package/src/sql-driver/dialects/dialects.ts +1 -0
  292. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  293. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  294. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  295. package/src/sql-driver/query-executor/plugin.ts +22 -0
  296. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  297. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  298. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  299. package/src/sql-driver/sql-driver.ts +53 -0
  300. package/src/sql-driver/sql.ts +57 -0
  301. package/src/sql-driver/sqlocal.test.ts +117 -0
  302. package/src/with-database.ts +35 -23
  303. package/tsdown.config.ts +7 -2
  304. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  305. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  306. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  307. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  308. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  309. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  310. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  311. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -334
  312. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  313. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -123
  314. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  315. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -160
  316. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  317. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  318. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  319. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  320. package/dist/adapters/drizzle/shared.js +0 -35
  321. package/dist/adapters/drizzle/shared.js.map +0 -1
  322. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  323. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  324. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  325. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  326. package/dist/adapters/kysely/kysely-query-compiler.js +0 -67
  327. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  328. package/dist/adapters/kysely/kysely-query.d.ts +0 -23
  329. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  330. package/dist/adapters/kysely/kysely-query.js +0 -230
  331. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  332. package/dist/adapters/kysely/kysely-shared.d.ts +0 -14
  333. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  334. package/dist/adapters/kysely/kysely-shared.js +0 -33
  335. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  336. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -193
  337. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  338. package/dist/adapters/kysely/kysely-uow-executor.js +0 -93
  339. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  340. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  341. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  342. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  343. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  344. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  345. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  346. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  347. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  348. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  349. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  350. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  351. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  352. package/dist/adapters/kysely/migration/execute.js +0 -34
  353. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  354. package/dist/migration-engine/create.d.ts +0 -37
  355. package/dist/migration-engine/create.d.ts.map +0 -1
  356. package/dist/migration-engine/create.js +0 -58
  357. package/dist/migration-engine/create.js.map +0 -1
  358. package/dist/migration-engine/shared.d.ts +0 -112
  359. package/dist/migration-engine/shared.d.ts.map +0 -1
  360. package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +0 -1
  361. package/dist/query/execute-unit-of-work.d.ts.map +0 -1
  362. package/dist/query/execute-unit-of-work.js.map +0 -1
  363. package/dist/query/query.d.ts.map +0 -1
  364. package/dist/query/result-transform.js +0 -170
  365. package/dist/query/result-transform.js.map +0 -1
  366. package/dist/query/retry-policy.d.ts.map +0 -1
  367. package/dist/query/retry-policy.js.map +0 -1
  368. package/dist/query/unit-of-work.d.ts.map +0 -1
  369. package/dist/query/unit-of-work.js.map +0 -1
  370. package/dist/schema/serialize.js +0 -111
  371. package/dist/schema/serialize.js.map +0 -1
  372. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -122
  373. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  374. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  375. package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +0 -1442
  376. package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +0 -1414
  377. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1400
  378. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -677
  379. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -228
  380. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -309
  381. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  382. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  383. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  384. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  385. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  386. package/src/adapters/kysely/kysely-query-compiler.ts +0 -127
  387. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  388. package/src/adapters/kysely/kysely-query.ts +0 -399
  389. package/src/adapters/kysely/kysely-shared.ts +0 -57
  390. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -986
  391. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -350
  392. package/src/adapters/kysely/kysely-uow-executor.ts +0 -164
  393. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -794
  394. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  395. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  396. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  397. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  398. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  399. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  400. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  401. package/src/adapters/kysely/migration/execute.ts +0 -50
  402. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  403. package/src/query/result-transform.ts +0 -274
  404. package/src/schema/serialize.ts +0 -407
  405. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
  406. /package/src/query/{retry-policy.test.ts → unit-of-work/retry-policy.test.ts} +0 -0
  407. /package/src/query/{retry-policy.ts → unit-of-work/retry-policy.ts} +0 -0
@@ -1,23 +1,12 @@
1
- import { sql, type Kysely } from "kysely";
1
+ import { type Kysely } from "kysely";
2
2
  import type { SQLProvider } from "../../shared/providers";
3
+ import { type DatabaseAdapter } from "../adapters";
4
+ import { createTableNameMapper } from "../shared/table-name-mapper";
3
5
  import {
4
- fragnoDatabaseAdapterNameFakeSymbol,
5
- fragnoDatabaseAdapterVersionFakeSymbol,
6
- type DatabaseAdapter,
7
- type DatabaseContextStorage,
8
- } from "../adapters";
9
- import { createMigrator, type Migrator } from "../../migration-engine/create";
10
- import type { AnySchema } from "../../schema/create";
11
- import type { CustomOperation, MigrationOperation } from "../../migration-engine/shared";
12
- import { execute, preprocessOperations } from "./migration/execute";
13
- import type { AbstractQuery } from "../../query/query";
14
- import { fromKysely, type KyselyUOWConfig } from "./kysely-query";
15
- import { createTableNameMapper } from "./kysely-shared";
16
- import { createHash } from "node:crypto";
17
- import { SETTINGS_TABLE_NAME } from "../../fragments/internal-fragment";
18
- import type { ConnectionPool } from "../../shared/connection-pool";
19
- import { createKyselyConnectionPool } from "./kysely-connection-pool";
20
- import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
6
+ GenericSQLAdapter,
7
+ type GenericSQLOptions,
8
+ type UnitOfWorkConfig,
9
+ } from "../generic-sql/generic-sql-adapter";
21
10
 
22
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
12
  type KyselyAny = Kysely<any>;
@@ -27,241 +16,12 @@ export interface KyselyConfig {
27
16
  provider: SQLProvider;
28
17
  }
29
18
 
30
- export class KyselyAdapter implements DatabaseAdapter<KyselyUOWConfig> {
31
- #connectionPool: ConnectionPool<KyselyAny>;
32
- #provider: SQLProvider;
33
- #schemaNamespaceMap = new WeakMap<AnySchema, string>();
34
- #contextStorage: RequestContextStorage<DatabaseContextStorage>;
35
-
36
- constructor(config: KyselyConfig) {
37
- this.#connectionPool = createKyselyConnectionPool(config.db);
38
- this.#provider = config.provider;
39
- this.#contextStorage = new RequestContextStorage();
40
- }
41
-
42
- get [fragnoDatabaseAdapterNameFakeSymbol](): string {
43
- return "kysely";
44
- }
45
-
46
- get [fragnoDatabaseAdapterVersionFakeSymbol](): number {
47
- return 0;
48
- }
49
-
50
- get contextStorage(): RequestContextStorage<DatabaseContextStorage> {
51
- return this.#contextStorage;
52
- }
53
-
54
- async close(): Promise<void> {
55
- await this.#connectionPool.close();
19
+ export class KyselyAdapter extends GenericSQLAdapter implements DatabaseAdapter<UnitOfWorkConfig> {
20
+ constructor(options: GenericSQLOptions) {
21
+ super(options);
56
22
  }
57
23
 
58
24
  createTableNameMapper(namespace: string) {
59
25
  return createTableNameMapper(namespace);
60
26
  }
61
-
62
- createQueryEngine<T extends AnySchema>(
63
- schema: T,
64
- namespace: string,
65
- ): AbstractQuery<T, KyselyUOWConfig> {
66
- // Register schema-namespace mapping
67
- this.#schemaNamespaceMap.set(schema, namespace);
68
-
69
- // Only create mapper if namespace is non-empty
70
- const mapper = namespace ? createTableNameMapper(namespace) : undefined;
71
- return fromKysely(
72
- schema,
73
- this.#connectionPool,
74
- this.#provider,
75
- mapper,
76
- undefined,
77
- this.#schemaNamespaceMap,
78
- );
79
- }
80
-
81
- async isConnectionHealthy(): Promise<boolean> {
82
- const conn = await this.#connectionPool.connect();
83
- try {
84
- const result = await conn.db.executeQuery(sql`SELECT 1 as healthy`.compile(conn.db));
85
- return (result.rows[0] as Record<string, unknown>)["healthy"] === 1;
86
- } catch {
87
- return false;
88
- } finally {
89
- await conn.release();
90
- }
91
- }
92
-
93
- createMigrationEngine(schema: AnySchema, namespace: string): Migrator {
94
- const mapper = namespace ? createTableNameMapper(namespace) : undefined;
95
-
96
- const preprocessMigrationOperations = (operations: MigrationOperation[], db: KyselyAny) => {
97
- // Preprocess operations using the provided db instance
98
- const config: KyselyConfig = {
99
- db,
100
- provider: this.#provider,
101
- };
102
- let preprocessed = preprocessOperations(operations, config);
103
-
104
- if (this.#provider === "mysql") {
105
- preprocessed.unshift({ type: "custom", sql: "SET FOREIGN_KEY_CHECKS = 0" });
106
- preprocessed.push({ type: "custom", sql: "SET FOREIGN_KEY_CHECKS = 1" });
107
- }
108
-
109
- return preprocessed;
110
- };
111
-
112
- // Convert operations to executable nodes bound to specific db instance
113
- const toExecutableNodes = (operations: MigrationOperation[], db: KyselyAny) => {
114
- const onCustomNode = (node: CustomOperation, db: KyselyAny) => {
115
- const statement = sql.raw(node["sql"] as string);
116
-
117
- return {
118
- compile() {
119
- return statement.compile(db);
120
- },
121
- execute() {
122
- return statement.execute(db);
123
- },
124
- };
125
- };
126
-
127
- const config: KyselyConfig = { db, provider: this.#provider };
128
- return operations.flatMap((op) =>
129
- execute(op, config, (node) => onCustomNode(node, db), mapper),
130
- );
131
- };
132
-
133
- const migrator = createMigrator({
134
- schema,
135
- executor: async (operations) => {
136
- const conn = await this.#connectionPool.connect();
137
- try {
138
- // For SQLite, execute PRAGMA defer_foreign_keys BEFORE transaction
139
- if (this.#provider === "sqlite") {
140
- await sql.raw("PRAGMA defer_foreign_keys = ON").execute(conn.db);
141
- }
142
-
143
- await conn.db.transaction().execute(async (tx) => {
144
- // Use the transaction instance for both preprocessing and execution
145
- const preprocessed = preprocessMigrationOperations(operations, tx);
146
- const nodes = toExecutableNodes(preprocessed, tx);
147
- for (const node of nodes) {
148
- try {
149
- await node.execute();
150
- } catch (e) {
151
- console.error("failed at", node.compile(), e);
152
- throw e;
153
- }
154
- }
155
- });
156
- } finally {
157
- await conn.release();
158
- }
159
- },
160
- sql: {
161
- toSql: (operations) => {
162
- const parts: string[] = [];
163
-
164
- // Add SQLite PRAGMA at the beginning
165
- if (this.#provider === "sqlite") {
166
- parts.push("PRAGMA defer_foreign_keys = ON;");
167
- }
168
-
169
- // Use getDatabaseSync for SQL generation (doesn't execute, just builds SQL strings)
170
- const db = this.#connectionPool.getDatabaseSync();
171
- const preprocessed = preprocessMigrationOperations(operations, db);
172
- const nodes = toExecutableNodes(preprocessed, db);
173
- const compiled = nodes.map((node) => `${node.compile().sql};`);
174
-
175
- parts.push(...compiled);
176
-
177
- return parts.join("\n\n");
178
- },
179
- },
180
-
181
- settings: {
182
- getVersion: async () => {
183
- const conn = await this.#connectionPool.connect();
184
- try {
185
- const manager = createSettingsManager(conn.db, namespace);
186
- const v = await manager.get(`schema_version`);
187
- return v ? parseInt(v) : 0;
188
- } finally {
189
- await conn.release();
190
- }
191
- },
192
- updateSettingsInMigration: async (fromVersion, toVersion) => {
193
- const conn = await this.#connectionPool.connect();
194
- try {
195
- const manager = createSettingsManager(conn.db, namespace);
196
- return [
197
- {
198
- type: "custom",
199
- sql:
200
- fromVersion === 0
201
- ? manager.insert(`schema_version`, toVersion.toString())
202
- : manager.update(`schema_version`, toVersion.toString()),
203
- },
204
- ];
205
- } finally {
206
- await conn.release();
207
- }
208
- },
209
- },
210
- });
211
-
212
- return migrator;
213
- }
214
-
215
- async getSchemaVersion(namespace: string): Promise<string | undefined> {
216
- const conn = await this.#connectionPool.connect();
217
- try {
218
- const manager = createSettingsManager(conn.db, namespace);
219
- return await manager.get(`schema_version`);
220
- } finally {
221
- await conn.release();
222
- }
223
- }
224
- }
225
-
226
- function createSettingsManager(db: KyselyAny, namespace: string) {
227
- // Settings table is never namespaced, but keys include namespace prefix
228
- const tableName = SETTINGS_TABLE_NAME;
229
-
230
- return {
231
- async get(key: string): Promise<string | undefined> {
232
- try {
233
- const result = await db
234
- .selectFrom(tableName)
235
- .where("key", "=", sql.lit(`${namespace}.${key}`))
236
- .select(["value"])
237
- .executeTakeFirstOrThrow();
238
- return result.value as string;
239
- } catch {
240
- return;
241
- }
242
- },
243
-
244
- insert(key: string, value: string) {
245
- return db
246
- .insertInto(tableName)
247
- .values({
248
- id: sql.lit(
249
- createHash("md5").update(`${namespace}.${key}`).digest("base64url").replace(/=/g, ""),
250
- ),
251
- key: sql.lit(`${namespace}.${key}`),
252
- value: sql.lit(value),
253
- })
254
- .compile().sql;
255
- },
256
-
257
- update(key: string, value: string) {
258
- return db
259
- .updateTable(tableName)
260
- .set({
261
- value: sql.lit(value),
262
- })
263
- .where("key", "=", sql.lit(`${namespace}.${key}`))
264
- .compile().sql;
265
- },
266
- };
267
27
  }
@@ -1,24 +1,25 @@
1
- import type { AbstractQuery } from "../../query/query";
2
- import type { AnySchema, AnyTable } from "../../schema/create";
3
- import type { CompiledMutation, UOWExecutor, ValidIndexName } from "../../query/unit-of-work";
4
- import { createDrizzleUOWCompiler, type DrizzleCompiledQuery } from "./drizzle-uow-compiler";
5
- import { executeDrizzleRetrievalPhase, executeDrizzleMutationPhase } from "./drizzle-uow-executor";
6
- import { UnitOfWork } from "../../query/unit-of-work";
7
- import { parseDrizzle, type DrizzleResult, type TableNameMapper, type DBType } from "./shared";
8
- import { createDrizzleUOWDecoder } from "./drizzle-uow-decoder";
9
- import type { ConnectionPool } from "../../shared/connection-pool";
10
- import type { TableToUpdateValues } from "../../query/query";
1
+ import type { SimpleQueryInterface, TableToUpdateValues } from "../../query/simple-query-interface";
2
+ import type { AnySchema, AnyTable, FragnoId } from "../../schema/create";
3
+ import type {
4
+ CompiledMutation,
5
+ UOWCompiler,
6
+ UOWDecoder,
7
+ UOWExecutor,
8
+ ValidIndexName,
9
+ } from "../../query/unit-of-work/unit-of-work";
10
+ import { UnitOfWork } from "../../query/unit-of-work/unit-of-work";
11
11
  import type { CursorResult } from "../../query/cursor";
12
+ import type { CompiledQuery } from "../../sql-driver/sql-driver";
12
13
 
13
14
  /**
14
- * Configuration options for creating a Drizzle Unit of Work
15
+ * Configuration options for creating a Unit of Work with generic SQL
15
16
  */
16
- export interface DrizzleUOWConfig {
17
+ export interface UnitOfWorkConfig {
17
18
  /**
18
19
  * Optional callback to receive compiled SQL queries for logging/debugging
19
20
  * This callback is invoked for each query as it's compiled
20
21
  */
21
- onQuery?: (query: DrizzleCompiledQuery) => void;
22
+ onQuery?: (query: CompiledQuery) => void;
22
23
  /**
23
24
  * If true, the query will not be executed and the query will be returned. Not respected for UOWs
24
25
  * since those have to be manually executed.
@@ -27,10 +28,52 @@ export interface DrizzleUOWConfig {
27
28
  }
28
29
 
29
30
  /**
30
- * Special builder for updateMany operations that captures configuration
31
+ * Factory interface for creating Unit of Work instances
31
32
  */
33
+ export interface UnitOfWorkFactory {
34
+ /**
35
+ * UOW compiler for compiling operations to SQL
36
+ */
37
+ compiler: UOWCompiler<CompiledQuery>;
38
+ /**
39
+ * UOW executor for running compiled queries
40
+ */
41
+ executor: UOWExecutor<CompiledQuery, unknown>;
42
+ /**
43
+ * UOW decoder for transforming raw results
44
+ */
45
+ decoder: UOWDecoder<unknown>;
46
+ /**
47
+ * Optional UOW configuration
48
+ */
49
+ uowConfig?: UnitOfWorkConfig;
50
+ /**
51
+ * Optional WeakMap for schema-to-namespace lookups
52
+ */
53
+ schemaNamespaceMap?: WeakMap<AnySchema, string>;
54
+ }
55
+
56
+ /**
57
+ * Type guard to check if a query is a CompiledMutation
58
+ */
59
+ function isCompiledMutation(query: unknown): query is CompiledMutation<CompiledQuery> {
60
+ return (
61
+ query !== null &&
62
+ typeof query === "object" &&
63
+ "expectedAffectedRows" in query &&
64
+ "query" in query
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Type guard to check if a record has an id field
70
+ */
71
+ function hasIdField(record: unknown): record is { id: string | FragnoId } {
72
+ return record !== null && typeof record === "object" && "id" in record;
73
+ }
74
+
32
75
  class UpdateManySpecialBuilder<TTable extends AnyTable> {
33
- #indexName?: string;
76
+ #indexName?: ValidIndexName<TTable>;
34
77
  #condition?: unknown;
35
78
  #setValues?: TableToUpdateValues<TTable>;
36
79
 
@@ -38,7 +81,7 @@ class UpdateManySpecialBuilder<TTable extends AnyTable> {
38
81
  indexName: TIndexName,
39
82
  condition?: unknown,
40
83
  ): this {
41
- this.#indexName = indexName as string;
84
+ this.#indexName = indexName;
42
85
  this.#condition = condition;
43
86
  return this;
44
87
  }
@@ -58,98 +101,56 @@ class UpdateManySpecialBuilder<TTable extends AnyTable> {
58
101
  }
59
102
 
60
103
  /**
61
- * Creates a Drizzle-based query engine for the given schema.
104
+ * Creates a generic SQL-based query engine for the given schema using a UnitOfWorkFactory.
62
105
  *
63
- * This is the main entry point for creating a database query interface using Drizzle.
106
+ * This is the main entry point for creating a database query interface using a Unit of Work compiler.
64
107
  * It uses a compiler-based architecture where queries are compiled to SQL and then executed,
65
108
  * enabling features like SQL snapshot testing.
66
109
  *
67
110
  * @param schema - The database schema definition
68
- * @param pool - Connection pool for acquiring database connections
69
- * @param provider - SQL provider (sqlite, mysql, postgresql)
70
- * @param mapper - Optional table name mapper for namespace prefixing
71
- * @param uowConfig - Optional UOW configuration
72
- * @param schemaNamespaceMap - Optional WeakMap for schema-to-namespace lookups
73
- * @returns An AbstractQuery instance for performing database operations
111
+ * @param factory - Factory containing compiler, executor, decoder, and optional configuration
112
+ * @returns An SimpleQueryInterface instance for performing database operations
74
113
  *
75
114
  * @example
76
115
  * ```ts
77
- * const pool = createSimpleConnectionPool(drizzle);
78
- * const queryEngine = fromDrizzle(mySchema, pool, 'postgresql');
116
+ * const operationCompiler = new GenericSQLUOWOperationCompiler(driverConfig);
117
+ * const factory: UnitOfWorkFactory = {
118
+ * compiler: createUOWCompilerFromOperationCompiler(operationCompiler),
119
+ * executor: createExecutor(sqlDriver),
120
+ * decoder: createKyselyUOWDecoder(driverConfig.databaseType),
121
+ * };
122
+ * const queryEngine = fromUnitOfWorkCompiler(mySchema, factory);
79
123
  *
80
- * const uow = queryEngine.createUnitOfWork('myOperation');
124
+ * const users = await queryEngine.find('users', (b) =>
125
+ * b.whereIndex('age').where((eb) => eb('age', '>', 18))
126
+ * );
81
127
  * ```
82
128
  */
83
- export function fromDrizzle<T extends AnySchema>(
129
+ export function fromUnitOfWorkCompiler<T extends AnySchema>(
84
130
  schema: T,
85
- pool: ConnectionPool<DBType>,
86
- provider: "sqlite" | "mysql" | "postgresql",
87
- mapper?: TableNameMapper,
88
- uowConfig?: DrizzleUOWConfig,
89
- schemaNamespaceMap?: WeakMap<AnySchema, string>,
90
- ): AbstractQuery<T, DrizzleUOWConfig> {
91
- function createUOW(opts: { name?: string; config?: DrizzleUOWConfig }) {
92
- const uowCompiler = createDrizzleUOWCompiler(pool, provider, mapper);
93
-
94
- const executor: UOWExecutor<DrizzleCompiledQuery, DrizzleResult> = {
95
- async executeRetrievalPhase(retrievalBatch: DrizzleCompiledQuery[]) {
96
- // In dryRun mode, skip execution and return empty results
97
- if (opts.config?.dryRun) {
98
- return retrievalBatch.map(() => ({
99
- rows: [],
100
- affectedRows: 0,
101
- }));
102
- }
103
-
104
- const conn = await pool.connect();
105
- try {
106
- const db = parseDrizzle(conn.db)[0];
107
- return await executeDrizzleRetrievalPhase(db, retrievalBatch, provider);
108
- } finally {
109
- await conn.release();
110
- }
111
- },
112
- async executeMutationPhase(mutationBatch: CompiledMutation<DrizzleCompiledQuery>[]) {
113
- // In dryRun mode, skip execution and return success with mock internal IDs
114
- if (opts.config?.dryRun) {
115
- return {
116
- success: true,
117
- createdInternalIds: mutationBatch.map(() => null),
118
- };
119
- }
120
-
121
- const conn = await pool.connect();
122
- try {
123
- const db = parseDrizzle(conn.db)[0];
124
- return await executeDrizzleMutationPhase(db, mutationBatch, provider);
125
- } finally {
126
- await conn.release();
127
- }
128
- },
129
- };
130
-
131
- const decoder = createDrizzleUOWDecoder(provider);
131
+ factory: UnitOfWorkFactory,
132
+ ): SimpleQueryInterface<T, UnitOfWorkConfig> {
133
+ const { compiler, executor, decoder, uowConfig, schemaNamespaceMap } = factory;
132
134
 
135
+ function createUOW(opts: { name?: string; config?: UnitOfWorkConfig }) {
133
136
  const { onQuery, ...restUowConfig } = opts.config ?? {};
134
137
 
135
138
  return new UnitOfWork(
136
- uowCompiler,
139
+ compiler,
137
140
  executor,
138
141
  decoder,
139
142
  opts.name,
140
143
  {
141
144
  ...restUowConfig,
142
- onQuery: (query) => {
143
- // Handle both CompiledQuery and CompiledMutation structures
144
- // Retrieval operations return DrizzleCompiledQuery directly: { sql, params }
145
- // Mutation operations return CompiledMutation: { query: DrizzleCompiledQuery, expectedAffectedRows }
146
- const actualQuery =
147
- query && typeof query === "object" && "query" in query
148
- ? (query as CompiledMutation<DrizzleCompiledQuery>).query
149
- : (query as DrizzleCompiledQuery);
150
-
151
- opts.config?.onQuery?.(actualQuery);
152
- },
145
+ onQuery: onQuery
146
+ ? (query) => {
147
+ // Extract the actual query from CompiledMutation if needed
148
+ const actualQuery = isCompiledMutation(query)
149
+ ? query.query
150
+ : (query as CompiledQuery);
151
+ onQuery(actualQuery);
152
+ }
153
+ : undefined,
153
154
  },
154
155
  schemaNamespaceMap,
155
156
  ).forSchema(schema);
@@ -157,18 +158,16 @@ export function fromDrizzle<T extends AnySchema>(
157
158
 
158
159
  return {
159
160
  async find(tableName, builderFn) {
160
- // Safe: builderFn returns a FindBuilder (or void), which matches UnitOfWork signature
161
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
162
- const uow = createUOW({ config: uowConfig }).find(tableName, builderFn as any);
163
- const [result] = await uow.executeRetrieve();
164
- return result;
161
+ const uow = createUOW({ config: uowConfig });
162
+ uow.find(tableName, builderFn);
163
+ const [result]: unknown[][] = await uow.executeRetrieve();
164
+ return result ?? [];
165
165
  },
166
166
 
167
167
  async findWithCursor(tableName, builderFn) {
168
- // Safe: builderFn returns a FindBuilder, which matches UnitOfWork signature
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
- const uow = createUOW({ config: uowConfig }).findWithCursor(tableName, builderFn as any);
168
+ const uow = createUOW({ config: uowConfig }).findWithCursor(tableName, builderFn);
171
169
  const [result] = await uow.executeRetrieve();
170
+ // Result from findWithCursor is always a CursorResult - the UOW decoder handles the conversion
172
171
  return result as CursorResult<unknown>;
173
172
  },
174
173
 
@@ -245,12 +244,13 @@ export function fromDrizzle<T extends AnySchema>(
245
244
 
246
245
  const findUow = createUOW({ config: uowConfig });
247
246
  findUow.find(tableName, (b) => {
248
- if (condition) {
249
- // Safe: condition is captured from whereIndex call with proper typing
247
+ // Condition might be null or undefined, only pass if defined and not null
248
+ if (condition !== undefined && condition !== null) {
249
+ // TypeScript can't infer the complex condition type from the builder
250
250
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
251
- return b.whereIndex(indexName as ValidIndexName<typeof table>, condition as any);
251
+ return b.whereIndex(indexName, condition as any);
252
252
  }
253
- return b.whereIndex(indexName as ValidIndexName<typeof table>);
253
+ return b.whereIndex(indexName);
254
254
  });
255
255
  const [records]: unknown[][] = await findUow.executeRetrieve();
256
256
 
@@ -259,8 +259,11 @@ export function fromDrizzle<T extends AnySchema>(
259
259
  }
260
260
 
261
261
  const updateUow = createUOW({ config: uowConfig });
262
- for (const record of records as Array<{ id: unknown }>) {
263
- updateUow.update(tableName, record.id as string, (b) => b.set(setValues));
262
+ for (const record of records) {
263
+ if (!hasIdField(record)) {
264
+ throw new Error("Record missing id field");
265
+ }
266
+ updateUow.update(tableName, record.id, (b) => b.set(setValues));
264
267
  }
265
268
  const { success } = await updateUow.executeMutations();
266
269
  if (!success) {
@@ -287,8 +290,11 @@ export function fromDrizzle<T extends AnySchema>(
287
290
  }
288
291
 
289
292
  const deleteUow = createUOW({ config: uowConfig });
290
- for (const record of records as Array<{ id: unknown }>) {
291
- deleteUow.delete(tableName, record.id as string);
293
+ for (const record of records) {
294
+ if (!hasIdField(record)) {
295
+ throw new Error("Record missing id field");
296
+ }
297
+ deleteUow.delete(tableName, record.id);
292
298
  }
293
299
  const { success } = await deleteUow.executeMutations();
294
300
  if (!success) {
@@ -305,5 +311,5 @@ export function fromDrizzle<T extends AnySchema>(
305
311
  },
306
312
  });
307
313
  },
308
- } as AbstractQuery<T, DrizzleUOWConfig>;
314
+ } as SimpleQueryInterface<T, UnitOfWorkConfig>;
309
315
  }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Sanitizes a namespace for use in database table names and TypeScript exports.
3
+ * Converts dashes to underscores to ensure compatibility with SQL identifiers
4
+ * and Drizzle's relational query system.
5
+ *
6
+ * @example
7
+ * sanitizeNamespace("my-fragment") // => "my_fragment"
8
+ */
9
+ export function sanitizeNamespace(namespace: string): string {
10
+ return namespace.replace(/-/g, "_");
11
+ }
12
+
13
+ /**
14
+ * Maps logical table names (used by fragment authors) to physical table names (with namespace suffix)
15
+ */
16
+ export interface TableNameMapper {
17
+ toPhysical(logicalName: string): string;
18
+ toLogical(physicalName: string): string;
19
+ }
20
+
21
+ /**
22
+ * Creates a table name mapper for a given namespace.
23
+ * Physical names have format: {logicalName}_{namespace} (or {logicalName}_{sanitizedNamespace} if sanitize is true)
24
+ *
25
+ * @param namespace - The namespace to use for table name prefixing
26
+ * @param sanitize - Whether to sanitize the namespace by converting dashes to underscores (default: false)
27
+ * @returns A table name mapper with toPhysical and toLogical methods
28
+ *
29
+ * @example
30
+ * const mapper = createTableNameMapper("my-fragment");
31
+ * mapper.toPhysical("users") // => "users_my-fragment"
32
+ *
33
+ * @example
34
+ * const mapper = createTableNameMapper("my-fragment", true);
35
+ * mapper.toPhysical("users") // => "users_my_fragment"
36
+ * mapper.toLogical("users_my_fragment") // => "users"
37
+ */
38
+ export function createTableNameMapper(namespace: string, sanitize = false): TableNameMapper {
39
+ const processedNamespace = sanitize ? sanitizeNamespace(namespace) : namespace;
40
+
41
+ return {
42
+ toPhysical: (logicalName: string) => `${logicalName}_${processedNamespace}`,
43
+ toLogical: (physicalName: string) => {
44
+ if (physicalName.endsWith(`_${processedNamespace}`)) {
45
+ return physicalName.slice(0, -(processedNamespace.length + 1));
46
+ }
47
+ return physicalName;
48
+ },
49
+ };
50
+ }