@fragno-dev/db 0.1.14 → 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 (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -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 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  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 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  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} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  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 +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  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 +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  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/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -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,118 +101,73 @@ 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
- schema,
137
- uowCompiler,
139
+ compiler,
138
140
  executor,
139
141
  decoder,
140
142
  opts.name,
141
143
  {
142
144
  ...restUowConfig,
143
- onQuery: (query) => {
144
- // Handle both CompiledQuery and CompiledMutation structures
145
- // Retrieval operations return DrizzleCompiledQuery directly: { sql, params }
146
- // Mutation operations return CompiledMutation: { query: DrizzleCompiledQuery, expectedAffectedRows }
147
- const actualQuery =
148
- query && typeof query === "object" && "query" in query
149
- ? (query as CompiledMutation<DrizzleCompiledQuery>).query
150
- : (query as DrizzleCompiledQuery);
151
-
152
- opts.config?.onQuery?.(actualQuery);
153
- },
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,
154
154
  },
155
155
  schemaNamespaceMap,
156
- );
156
+ ).forSchema(schema);
157
157
  }
158
158
 
159
159
  return {
160
160
  async find(tableName, builderFn) {
161
- // Safe: builderFn returns a FindBuilder (or void), which matches UnitOfWork signature
162
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
- const uow = createUOW({ config: uowConfig }).find(tableName, builderFn as any);
164
- const [result] = await uow.executeRetrieve();
165
- return result;
161
+ const uow = createUOW({ config: uowConfig });
162
+ uow.find(tableName, builderFn);
163
+ const [result]: unknown[][] = await uow.executeRetrieve();
164
+ return result ?? [];
166
165
  },
167
166
 
168
167
  async findWithCursor(tableName, builderFn) {
169
- // Safe: builderFn returns a FindBuilder, which matches UnitOfWork signature
170
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
171
- const uow = createUOW({ config: uowConfig }).findWithCursor(tableName, builderFn as any);
168
+ const uow = createUOW({ config: uowConfig }).findWithCursor(tableName, builderFn);
172
169
  const [result] = await uow.executeRetrieve();
170
+ // Result from findWithCursor is always a CursorResult - the UOW decoder handles the conversion
173
171
  return result as CursorResult<unknown>;
174
172
  },
175
173
 
@@ -246,12 +244,13 @@ export function fromDrizzle<T extends AnySchema>(
246
244
 
247
245
  const findUow = createUOW({ config: uowConfig });
248
246
  findUow.find(tableName, (b) => {
249
- if (condition) {
250
- // 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
251
250
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
252
- return b.whereIndex(indexName as ValidIndexName<typeof table>, condition as any);
251
+ return b.whereIndex(indexName, condition as any);
253
252
  }
254
- return b.whereIndex(indexName as ValidIndexName<typeof table>);
253
+ return b.whereIndex(indexName);
255
254
  });
256
255
  const [records]: unknown[][] = await findUow.executeRetrieve();
257
256
 
@@ -260,8 +259,11 @@ export function fromDrizzle<T extends AnySchema>(
260
259
  }
261
260
 
262
261
  const updateUow = createUOW({ config: uowConfig });
263
- for (const record of records as Array<{ id: unknown }>) {
264
- 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));
265
267
  }
266
268
  const { success } = await updateUow.executeMutations();
267
269
  if (!success) {
@@ -288,8 +290,11 @@ export function fromDrizzle<T extends AnySchema>(
288
290
  }
289
291
 
290
292
  const deleteUow = createUOW({ config: uowConfig });
291
- for (const record of records as Array<{ id: unknown }>) {
292
- 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);
293
298
  }
294
299
  const { success } = await deleteUow.executeMutations();
295
300
  if (!success) {
@@ -306,5 +311,5 @@ export function fromDrizzle<T extends AnySchema>(
306
311
  },
307
312
  });
308
313
  },
309
- } as AbstractQuery<T, DrizzleUOWConfig>;
314
+ } as SimpleQueryInterface<T, UnitOfWorkConfig>;
310
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
+ }
@@ -0,0 +1,211 @@
1
+ import type { AnyColumn, AnySchema, AnyTable, FragnoId } from "../../schema/create";
2
+ import type { Condition } from "../../query/condition-builder";
3
+ import type {
4
+ CompiledMutation,
5
+ RetrievalOperation,
6
+ MutationOperation,
7
+ UOWCompiler,
8
+ } from "../../query/unit-of-work/unit-of-work";
9
+ import { Cursor } from "../../query/cursor";
10
+ import type { DriverConfig } from "../generic-sql/driver-config";
11
+ import { createTableNameMapper, type TableNameMapper } from "./table-name-mapper";
12
+
13
+ /**
14
+ * Options for compiling a find operation with cursor pagination
15
+ */
16
+ export interface FindCompilationOptions {
17
+ /** Index columns used for ordering */
18
+ indexColumns: AnyColumn[];
19
+ /** Order direction for the index */
20
+ orderDirection: "asc" | "desc";
21
+ /** User-provided where condition */
22
+ userWhere: Condition | boolean | undefined;
23
+ /** Cursor string or Cursor object for pagination (after) */
24
+ after?: string | Cursor;
25
+ /** Cursor string or Cursor object for pagination (before) */
26
+ before?: string | Cursor;
27
+ /** Page size for pagination */
28
+ pageSize?: number;
29
+ /** Whether this is a high-level cursor API call (affects limit calculation) */
30
+ withCursor?: boolean;
31
+ /** Driver config for cursor serialization */
32
+ driverConfig: DriverConfig;
33
+ }
34
+
35
+ /**
36
+ * Result of cursor condition building
37
+ */
38
+ export interface CursorConditionResult {
39
+ /** The combined where condition (user where + cursor condition) */
40
+ where: Condition | undefined;
41
+ /** The effective limit to use (may be pageSize + 1 for cursor detection) */
42
+ limit: number | undefined;
43
+ }
44
+
45
+ /**
46
+ * Abstract base class for Unit of Work operation compilers
47
+ *
48
+ * This class provides a structure and utilities for implementing UOW compilers
49
+ * for different ORM/query builders (Kysely, Drizzle, etc.).
50
+ *
51
+ * Subclasses must implement the abstract methods for each operation type,
52
+ * and can use the provided utility methods for common tasks.
53
+ *
54
+ * @template TCompiledQuery - The type of compiled query for the target ORM
55
+ */
56
+ export abstract class UOWOperationCompiler<TCompiledQuery> {
57
+ #driverConfig: DriverConfig;
58
+ #mapperFactory?: (namespace: string | undefined) => TableNameMapper | undefined;
59
+
60
+ constructor(
61
+ driverConfig: DriverConfig,
62
+ mapperFactory?: (namespace: string | undefined) => TableNameMapper | undefined,
63
+ ) {
64
+ this.#driverConfig = driverConfig;
65
+ this.#mapperFactory = mapperFactory;
66
+ }
67
+
68
+ protected get driverConfig(): DriverConfig {
69
+ return this.#driverConfig;
70
+ }
71
+
72
+ protected get mapperFactory():
73
+ | ((namespace: string | undefined) => TableNameMapper | undefined)
74
+ | undefined {
75
+ return this.#mapperFactory;
76
+ }
77
+
78
+ abstract compileCount(
79
+ op: RetrievalOperation<AnySchema> & { type: "count" },
80
+ ): TCompiledQuery | null;
81
+
82
+ abstract compileFind(op: RetrievalOperation<AnySchema> & { type: "find" }): TCompiledQuery | null;
83
+
84
+ /**
85
+ * Compile a create operation
86
+ */
87
+ abstract compileCreate(
88
+ op: MutationOperation<AnySchema> & { type: "create" },
89
+ ): CompiledMutation<TCompiledQuery> | null;
90
+
91
+ abstract compileUpdate(
92
+ op: MutationOperation<AnySchema> & { type: "update" },
93
+ ): CompiledMutation<TCompiledQuery> | null;
94
+
95
+ abstract compileDelete(
96
+ op: MutationOperation<AnySchema> & { type: "delete" },
97
+ ): CompiledMutation<TCompiledQuery> | null;
98
+
99
+ abstract compileCheck(
100
+ op: MutationOperation<AnySchema> & { type: "check" },
101
+ ): CompiledMutation<TCompiledQuery> | null;
102
+
103
+ // ==================== Utility Methods ====================
104
+
105
+ /**
106
+ * Get the mapper for a specific operation based on its namespace
107
+ */
108
+ protected getMapperForOperation(namespace: string | undefined): TableNameMapper | undefined {
109
+ return this.#mapperFactory
110
+ ? this.#mapperFactory(namespace)
111
+ : namespace
112
+ ? createTableNameMapper(namespace)
113
+ : undefined;
114
+ }
115
+
116
+ /**
117
+ * Get a table from a schema by name
118
+ * @throws Error if table is not found
119
+ */
120
+ protected getTable(schema: AnySchema, tableName: string): AnyTable {
121
+ const table = schema.tables[tableName];
122
+ if (!table) {
123
+ throw new Error(`Invalid table name ${tableName}.`);
124
+ }
125
+ return table;
126
+ }
127
+
128
+ /**
129
+ * Get the version to check for a given ID and checkVersion flag
130
+ * @returns The version to check or undefined if no check is required
131
+ * @throws Error if the ID is a string and checkVersion is true
132
+ */
133
+ protected getVersionToCheck(id: FragnoId | string, checkVersion: boolean): number | undefined {
134
+ if (!checkVersion) {
135
+ return undefined;
136
+ }
137
+
138
+ if (typeof id === "string") {
139
+ throw new Error(
140
+ `Cannot use checkVersion with a string ID. Version checking requires a FragnoId with version information.`,
141
+ );
142
+ }
143
+
144
+ return id.version;
145
+ }
146
+
147
+ /**
148
+ * Extract external ID from FragnoId or string
149
+ */
150
+ protected getExternalId(id: FragnoId | string): string {
151
+ return typeof id === "string" ? id : id.externalId;
152
+ }
153
+
154
+ /**
155
+ * Get the physical table name for an operation, applying namespace mapping if needed
156
+ */
157
+ protected getPhysicalTableName(logicalName: string, namespace: string | undefined): string {
158
+ const mapper = this.getMapperForOperation(namespace);
159
+ return mapper ? mapper.toPhysical(logicalName) : logicalName;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Creates a UOWCompiler from a UOWOperationCompiler by dispatching operations
165
+ * to the appropriate specific compilation methods based on operation type.
166
+ *
167
+ * @template TCompiledQuery - The type of compiled query for the target ORM
168
+ * @param operationCompiler - The operation compiler to wrap
169
+ * @returns A UOWCompiler instance that delegates to the operation compiler
170
+ */
171
+ export function createUOWCompilerFromOperationCompiler<TCompiledQuery>(
172
+ operationCompiler: UOWOperationCompiler<TCompiledQuery>,
173
+ ): UOWCompiler<TCompiledQuery> {
174
+ return {
175
+ compileRetrievalOperation(op: RetrievalOperation<AnySchema>): TCompiledQuery | null {
176
+ switch (op.type) {
177
+ case "count":
178
+ return operationCompiler.compileCount(op);
179
+ case "find":
180
+ return operationCompiler.compileFind(op);
181
+ default: {
182
+ const exhaustiveCheck: never = op;
183
+ throw new Error(
184
+ `Unknown retrieval operation type: ${(exhaustiveCheck as RetrievalOperation<AnySchema>).type}`,
185
+ );
186
+ }
187
+ }
188
+ },
189
+
190
+ compileMutationOperation(
191
+ op: MutationOperation<AnySchema>,
192
+ ): CompiledMutation<TCompiledQuery> | null {
193
+ switch (op.type) {
194
+ case "create":
195
+ return operationCompiler.compileCreate(op);
196
+ case "update":
197
+ return operationCompiler.compileUpdate(op);
198
+ case "delete":
199
+ return operationCompiler.compileDelete(op);
200
+ case "check":
201
+ return operationCompiler.compileCheck(op);
202
+ default: {
203
+ const exhaustiveCheck: never = op;
204
+ throw new Error(
205
+ `Unknown mutation operation type: ${(exhaustiveCheck as MutationOperation<AnySchema>).type}`,
206
+ );
207
+ }
208
+ }
209
+ },
210
+ };
211
+ }