@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,794 +0,0 @@
1
- import { describe, it, assert, expect } from "vitest";
2
- import { column, idColumn, referenceColumn, schema } from "../../schema/create";
3
- import { UnitOfWork, type UOWDecoder } from "../../query/unit-of-work";
4
- import { createKyselyUOWCompiler } from "./kysely-uow-compiler";
5
-
6
- describe("kysely-uow-joins", () => {
7
- const userSchema = schema((s) => {
8
- return (
9
- s
10
- .addTable("users", (t) => {
11
- return t
12
- .addColumn("id", idColumn())
13
- .addColumn("name", column("string"))
14
- .addColumn("email", column("string"))
15
- .addColumn("invitedBy", referenceColumn())
16
- .createIndex("idx_name", ["name"])
17
- .createIndex("idx_id", ["id"]);
18
- })
19
- .addTable("posts", (t) => {
20
- return t
21
- .addColumn("id", idColumn())
22
- .addColumn("title", column("string"))
23
- .addColumn("content", column("string"))
24
- .addColumn("userId", referenceColumn())
25
- .addColumn("publishedAt", column("timestamp"))
26
- .createIndex("idx_title", ["title"])
27
- .createIndex("idx_id", ["id"]);
28
- })
29
- .addTable("tags", (t) => {
30
- return t
31
- .addColumn("id", idColumn())
32
- .addColumn("name", column("string"))
33
- .createIndex("idx_id", ["id"]);
34
- })
35
- .addTable("post_tags", (t) => {
36
- return t
37
- .addColumn("id", idColumn())
38
- .addColumn("postId", referenceColumn())
39
- .addColumn("tagId", referenceColumn())
40
- .createIndex("idx_post", ["postId"])
41
- .createIndex("idx_tag", ["tagId"]);
42
- })
43
- .addTable("comments", (t) => {
44
- return t
45
- .addColumn("id", idColumn())
46
- .addColumn("content", column("string"))
47
- .addColumn("postId", referenceColumn())
48
- .addColumn("authorId", referenceColumn())
49
- .createIndex("idx_post", ["postId"])
50
- .createIndex("idx_author", ["authorId"]);
51
- })
52
- // Basic one-to-many relationships
53
- .addReference("author", {
54
- type: "one",
55
- from: { table: "posts", column: "userId" },
56
- to: { table: "users", column: "id" },
57
- })
58
- .addReference("inviter", {
59
- type: "one",
60
- from: { table: "users", column: "invitedBy" },
61
- to: { table: "users", column: "id" },
62
- })
63
- .addReference("post", {
64
- type: "one",
65
- from: { table: "comments", column: "postId" },
66
- to: { table: "posts", column: "id" },
67
- })
68
- .addReference("author", {
69
- type: "one",
70
- from: { table: "comments", column: "authorId" },
71
- to: { table: "users", column: "id" },
72
- })
73
- // Many-to-many relationships
74
- .addReference("post", {
75
- type: "one",
76
- from: { table: "post_tags", column: "postId" },
77
- to: { table: "posts", column: "id" },
78
- })
79
- .addReference("tag", {
80
- type: "one",
81
- from: { table: "post_tags", column: "tagId" },
82
- to: { table: "tags", column: "id" },
83
- })
84
- );
85
- });
86
-
87
- // Helper to create UnitOfWork for testing
88
- function createTestUOW(name?: string) {
89
- const mockCompiler = createKyselyUOWCompiler("postgresql");
90
- const mockExecutor = {
91
- executeRetrievalPhase: async () => [],
92
- executeMutationPhase: async () => ({ success: true, createdInternalIds: [] }),
93
- };
94
- const mockDecoder: UOWDecoder = (rawResults, operations) => {
95
- if (rawResults.length !== operations.length) {
96
- throw new Error("rawResults and ops must have the same length");
97
- }
98
- return rawResults;
99
- };
100
- return new UnitOfWork(mockCompiler, mockExecutor, mockDecoder, name).forSchema(userSchema);
101
- }
102
-
103
- describe("postgresql", () => {
104
- it("should compile select with join condition comparing columns", () => {
105
- const uow = createTestUOW();
106
- uow.find("posts", (b) =>
107
- b
108
- .whereIndex("primary")
109
- .select(["id", "userId"])
110
- .join((jb) => jb.author()),
111
- );
112
-
113
- const compiler = createKyselyUOWCompiler("postgresql");
114
- const compiled = uow.compile(compiler);
115
-
116
- expect(compiled.retrievalBatch).toHaveLength(1);
117
- const query = compiled.retrievalBatch[0];
118
- assert(query);
119
- expect(query.sql).toMatchInlineSnapshot(
120
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."email" as "author:email", "author"."invitedBy" as "author:invitedBy", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."userId" as "userId", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
121
- );
122
- });
123
-
124
- it("should compile join with specific column selection", () => {
125
- const uow = createTestUOW();
126
- uow.find("posts", (b) =>
127
- b
128
- .whereIndex("primary")
129
- .select(["id", "title"])
130
- .join((jb) => jb.author((ab) => ab.select(["name", "email"]))),
131
- );
132
-
133
- const compiler = createKyselyUOWCompiler("postgresql");
134
- const compiled = uow.compile(compiler);
135
-
136
- expect(compiled.retrievalBatch).toHaveLength(1);
137
- const query = compiled.retrievalBatch[0];
138
- assert(query);
139
- expect(query.sql).toMatchInlineSnapshot(
140
- `"select "author"."name" as "author:name", "author"."email" as "author:email", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
141
- );
142
- });
143
-
144
- it("should compile join with WHERE conditions on joined table", () => {
145
- const uow = createTestUOW();
146
- uow.find("posts", (b) =>
147
- b
148
- .whereIndex("primary")
149
- .select(["id", "title"])
150
- .join((jb) =>
151
- jb.author((ab) =>
152
- ab.select(["name"]).whereIndex("idx_name", (eb) => eb("name", "contains", "john")),
153
- ),
154
- ),
155
- );
156
-
157
- const compiler = createKyselyUOWCompiler("postgresql");
158
- const compiled = uow.compile(compiler);
159
-
160
- expect(compiled.retrievalBatch).toHaveLength(1);
161
- const query = compiled.retrievalBatch[0];
162
- assert(query);
163
- expect(query.sql).toMatchInlineSnapshot(
164
- `"select "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on ("posts"."userId" = "author"."_internalId" and "users"."name" like $1)"`,
165
- );
166
- });
167
-
168
- it("should compile self-referencing join", () => {
169
- const uow = createTestUOW();
170
- uow.find("users", (b) =>
171
- b
172
- .whereIndex("primary")
173
- .select(["id", "name"])
174
- .join((jb) => jb.inviter((ib) => ib.select(["name"]))),
175
- );
176
-
177
- const compiler = createKyselyUOWCompiler("postgresql");
178
- const compiled = uow.compile(compiler);
179
-
180
- expect(compiled.retrievalBatch).toHaveLength(1);
181
- const query = compiled.retrievalBatch[0];
182
- assert(query);
183
- expect(query.sql).toMatchInlineSnapshot(
184
- `"select "inviter"."name" as "inviter:name", "inviter"."_internalId" as "inviter:_internalId", "inviter"."_version" as "inviter:_version", "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" left join "users" as "inviter" on "users"."invitedBy" = "inviter"."_internalId""`,
185
- );
186
- });
187
-
188
- it("should compile multiple joins in single query", () => {
189
- const uow = createTestUOW();
190
- uow.find("comments", (b) =>
191
- b
192
- .whereIndex("primary")
193
- .select(["id", "content"])
194
- .join((jb) => jb.post((pb) => pb.select(["title"])).author((ab) => ab.select(["name"]))),
195
- );
196
-
197
- const compiler = createKyselyUOWCompiler("postgresql");
198
- const compiled = uow.compile(compiler);
199
-
200
- expect(compiled.retrievalBatch).toHaveLength(1);
201
- const query = compiled.retrievalBatch[0];
202
- assert(query);
203
- expect(query.sql).toMatchInlineSnapshot(
204
- `"select "post"."title" as "post:title", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "comments"."id" as "id", "comments"."content" as "content", "comments"."_internalId" as "_internalId", "comments"."_version" as "_version" from "comments" left join "posts" as "post" on "comments"."postId" = "post"."_internalId" left join "users" as "author" on "comments"."authorId" = "author"."_internalId""`,
205
- );
206
- });
207
-
208
- it("should compile many-to-many join through junction table", () => {
209
- const uow = createTestUOW();
210
- uow.find("post_tags", (b) =>
211
- b
212
- .whereIndex("primary")
213
- .select(["id"])
214
- .join((jb) => jb.post((pb) => pb.select(["title"])).tag((tb) => tb.select(["name"]))),
215
- );
216
-
217
- const compiler = createKyselyUOWCompiler("postgresql");
218
- const compiled = uow.compile(compiler);
219
-
220
- expect(compiled.retrievalBatch).toHaveLength(1);
221
- const query = compiled.retrievalBatch[0];
222
- assert(query);
223
- expect(query.sql).toMatchInlineSnapshot(
224
- `"select "post"."title" as "post:title", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "tag"."name" as "tag:name", "tag"."_internalId" as "tag:_internalId", "tag"."_version" as "tag:_version", "post_tags"."id" as "id", "post_tags"."_internalId" as "_internalId", "post_tags"."_version" as "_version" from "post_tags" left join "posts" as "post" on "post_tags"."postId" = "post"."_internalId" left join "tags" as "tag" on "post_tags"."tagId" = "tag"."_internalId""`,
225
- );
226
- });
227
-
228
- it("should compile complex join with multiple WHERE conditions", () => {
229
- const uow = createTestUOW();
230
- uow.find("posts", (b) =>
231
- b
232
- .whereIndex("primary")
233
- .select(["id", "title"])
234
- .join((jb) =>
235
- jb.author((ab) =>
236
- ab.select(["name"]).whereIndex("idx_name", (eb) =>
237
- eb.and(
238
- eb("name", "contains", "john"),
239
- // @ts-expect-error - email is not indexed
240
- eb("email", "ends with", "@example.com"),
241
- ),
242
- ),
243
- ),
244
- ),
245
- );
246
-
247
- const compiler = createKyselyUOWCompiler("postgresql");
248
- const compiled = uow.compile(compiler);
249
-
250
- expect(compiled.retrievalBatch).toHaveLength(1);
251
- const query = compiled.retrievalBatch[0];
252
- assert(query);
253
- expect(query.sql).toMatchInlineSnapshot(
254
- `"select "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on ("posts"."userId" = "author"."_internalId" and ("users"."name" like $1 and "users"."email" like $2))"`,
255
- );
256
- });
257
-
258
- it("should compile join with ordering on joined table - LIMITATION: orderBy applied but may have limited effect", () => {
259
- const uow = createTestUOW();
260
- uow.find("posts", (b) =>
261
- b
262
- .whereIndex("primary")
263
- .select(["id", "title"])
264
- .join((jb) => jb.author((ab) => ab.select(["name"]).orderByIndex("idx_name", "asc"))),
265
- );
266
-
267
- const compiler = createKyselyUOWCompiler("postgresql");
268
- const compiled = uow.compile(compiler);
269
-
270
- expect(compiled.retrievalBatch).toHaveLength(1);
271
- const query = compiled.retrievalBatch[0];
272
- assert(query);
273
- // LIMITATION: orderBy on join options is applied but has limited effect in SQL JOINs
274
- expect(query.sql).toMatchInlineSnapshot(
275
- `"select "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
276
- );
277
- });
278
-
279
- it("should compile join with pageSize on joined table - LIMITATION: pageSize applied but may have limited effect", () => {
280
- const uow = createTestUOW();
281
- uow.find("posts", (b) =>
282
- b
283
- .whereIndex("primary")
284
- .select(["id", "title"])
285
- .join((jb) => jb.author((ab) => ab.select(["name"]).pageSize(1))),
286
- );
287
-
288
- const compiler = createKyselyUOWCompiler("postgresql");
289
- const compiled = uow.compile(compiler);
290
-
291
- expect(compiled.retrievalBatch).toHaveLength(1);
292
- const query = compiled.retrievalBatch[0];
293
- assert(query);
294
- // LIMITATION: pageSize on join options is applied but has limited effect in SQL JOINs
295
- expect(query.sql).toMatchInlineSnapshot(
296
- `"select "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
297
- );
298
- });
299
-
300
- // Tests for nested joins - SUPPORTED in UOW API
301
- it("should support nested joins (join on joined table) - IMPLEMENTED in UOW API", () => {
302
- const uow = createTestUOW();
303
- uow.find("posts", (b) =>
304
- b
305
- .whereIndex("primary")
306
- .select(["id", "title"])
307
- .join((jb) =>
308
- jb.author((ab) =>
309
- ab
310
- .select(["name"])
311
- .join((authorJoin) => authorJoin["inviter"]((ib) => ib.select(["name"]))),
312
- ),
313
- ),
314
- );
315
-
316
- const compiler = createKyselyUOWCompiler("postgresql");
317
- const compiled = uow.compile(compiler);
318
-
319
- expect(compiled.retrievalBatch).toHaveLength(1);
320
- const query = compiled.retrievalBatch[0];
321
- assert(query);
322
- // EXPECTED SQL: Should include both the author join AND the inviter join
323
- expect(query.sql).toMatchInlineSnapshot(
324
- `"select "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "author_inviter"."name" as "author:inviter:name", "author_inviter"."_internalId" as "author:inviter:_internalId", "author_inviter"."_version" as "author:inviter:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId" left join "users" as "author_inviter" on "author"."invitedBy" = "author_inviter"."_internalId""`,
325
- );
326
- });
327
- });
328
-
329
- describe("id column selection in joins", () => {
330
- it("should properly transform id columns in joined tables to FragnoId objects", () => {
331
- const uow = createTestUOW();
332
- uow.find("posts", (b) =>
333
- b
334
- .whereIndex("primary")
335
- .select(["id", "title"])
336
- .join((jb) => jb.author((ab) => ab.select(["id", "name"]))),
337
- );
338
-
339
- const compiler = createKyselyUOWCompiler("postgresql");
340
- const compiled = uow.compile(compiler);
341
-
342
- expect(compiled.retrievalBatch).toHaveLength(1);
343
- const query = compiled.retrievalBatch[0];
344
- assert(query);
345
- expect(query.sql).toContain('"author"."id"');
346
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
347
- expect(query.sql).toContain('"author"."_version" as "author:_version"');
348
- expect(query.sql).toMatchInlineSnapshot(
349
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
350
- );
351
- });
352
-
353
- it("should select id columns from main table and joined table", () => {
354
- const uow = createTestUOW();
355
- uow.find("posts", (b) =>
356
- b
357
- .whereIndex("primary")
358
- .select(["id", "title"])
359
- .join((jb) => jb.author((ab) => ab.select(["id", "name"]))),
360
- );
361
-
362
- const compiler = createKyselyUOWCompiler("postgresql");
363
- const compiled = uow.compile(compiler);
364
-
365
- expect(compiled.retrievalBatch).toHaveLength(1);
366
- const query = compiled.retrievalBatch[0];
367
- assert(query);
368
- // Both main table id and joined table id should be in the query
369
- expect(query.sql).toContain('"posts"."id"');
370
- expect(query.sql).toContain('"author"."id"');
371
- // When id is selected from joined table, its _internalId is also included
372
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
373
- expect(query.sql).toMatchInlineSnapshot(
374
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
375
- );
376
- });
377
-
378
- it("should handle id-only selection in join", () => {
379
- const uow = createTestUOW();
380
- uow.find("posts", (b) =>
381
- b
382
- .whereIndex("primary")
383
- .select(["id"])
384
- .join((jb) => jb.author((ab) => ab.select(["id"]))),
385
- );
386
-
387
- const compiler = createKyselyUOWCompiler("postgresql");
388
- const compiled = uow.compile(compiler);
389
-
390
- expect(compiled.retrievalBatch).toHaveLength(1);
391
- const query = compiled.retrievalBatch[0];
392
- assert(query);
393
- // When only id is selected, _internalId is still included for joined table
394
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
395
- expect(query.sql).toMatchInlineSnapshot(
396
- `"select "author"."id" as "author:id", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
397
- );
398
- });
399
-
400
- it("should include _internalId for both main and joined table when id is selected", () => {
401
- const uow = createTestUOW();
402
- uow.find("posts", (b) =>
403
- b
404
- .whereIndex("primary")
405
- .select(["id", "title"])
406
- .join((jb) => jb.author((ab) => ab.select(["id", "name"]))),
407
- );
408
-
409
- const compiler = createKyselyUOWCompiler("postgresql");
410
- const compiled = uow.compile(compiler);
411
-
412
- expect(compiled.retrievalBatch).toHaveLength(1);
413
- const query = compiled.retrievalBatch[0];
414
- assert(query);
415
- // Both tables should have their _internalId included when id is selected
416
- expect(query.sql).toContain('"posts"."_internalId"');
417
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
418
- expect(query.sql).toMatchInlineSnapshot(
419
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
420
- );
421
- });
422
-
423
- it("should not include _internalId when id is not selected", () => {
424
- const uow = createTestUOW();
425
- uow.find("posts", (b) =>
426
- b
427
- .whereIndex("primary")
428
- .select(["title"])
429
- .join((jb) => jb.author((ab) => ab.select(["name"]))),
430
- );
431
-
432
- const compiler = createKyselyUOWCompiler("postgresql");
433
- const compiled = uow.compile(compiler);
434
-
435
- expect(compiled.retrievalBatch).toHaveLength(1);
436
- const query = compiled.retrievalBatch[0];
437
- assert(query);
438
- // Hidden columns (_internalId, _version) are always included for internal use
439
- expect(query.sql).toContain('"posts"."_internalId" as "_internalId"');
440
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
441
- expect(query.sql).toContain('"posts"."_version" as "_version"');
442
- expect(query.sql).toContain('"author"."_version" as "author:_version"');
443
- expect(query.sql).toMatchInlineSnapshot(
444
- `"select "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
445
- );
446
- });
447
-
448
- it("should handle select true with joins - includes all columns including id", () => {
449
- const uow = createTestUOW();
450
- uow.find("posts", (b) => b.whereIndex("primary").join((jb) => jb.author()));
451
-
452
- const compiler = createKyselyUOWCompiler("postgresql");
453
- const compiled = uow.compile(compiler);
454
-
455
- expect(compiled.retrievalBatch).toHaveLength(1);
456
- const query = compiled.retrievalBatch[0];
457
- assert(query);
458
- expect(query.sql).toContain('"posts"."id"');
459
- expect(query.sql).toContain('"author"."id"');
460
- expect(query.sql).toContain('"posts"."_internalId"');
461
- expect(query.sql).toContain('"author"."_internalId"');
462
- expect(query.sql).toMatchInlineSnapshot(
463
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."email" as "author:email", "author"."invitedBy" as "author:invitedBy", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."content" as "content", "posts"."userId" as "userId", "posts"."publishedAt" as "publishedAt", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
464
- );
465
- });
466
-
467
- it("should handle id column in where clause on joined table", () => {
468
- const uow = createTestUOW();
469
- uow.find("posts", (b) =>
470
- b
471
- .whereIndex("primary")
472
- .select(["id", "title"])
473
- .join((jb) =>
474
- jb.author((ab) =>
475
- ab.select(["id", "name"]).whereIndex("idx_id", (eb) => eb("id", "=", "user-123")),
476
- ),
477
- ),
478
- );
479
-
480
- const compiler = createKyselyUOWCompiler("postgresql");
481
- const compiled = uow.compile(compiler);
482
-
483
- expect(compiled.retrievalBatch).toHaveLength(1);
484
- const query = compiled.retrievalBatch[0];
485
- assert(query);
486
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
487
- expect(query.sql).toMatchInlineSnapshot(
488
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on ("posts"."userId" = "author"."_internalId" and "users"."id" = $1)"`,
489
- );
490
- });
491
-
492
- it("should handle multiple joins with different id selections", () => {
493
- const uow = createTestUOW();
494
- uow.find("comments", (b) =>
495
- b
496
- .whereIndex("primary")
497
- .select(["id", "content"])
498
- .join((jb) =>
499
- jb.post((pb) => pb.select(["id", "title"])).author((ab) => ab.select(["name"])),
500
- ),
501
- );
502
-
503
- const compiler = createKyselyUOWCompiler("postgresql");
504
- const compiled = uow.compile(compiler);
505
-
506
- expect(compiled.retrievalBatch).toHaveLength(1);
507
- const query = compiled.retrievalBatch[0];
508
- assert(query);
509
- expect(query.sql).toContain('"comments"."id"');
510
- expect(query.sql).toContain('"post"."id"');
511
- expect(query.sql).not.toContain('"author"."id"');
512
- // Hidden columns are always included regardless of ID selection
513
- expect(query.sql).toContain('"post"."_internalId" as "post:_internalId"');
514
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
515
- expect(query.sql).toContain('"post"."_version" as "post:_version"');
516
- expect(query.sql).toContain('"author"."_version" as "author:_version"');
517
- expect(query.sql).toMatchInlineSnapshot(
518
- `"select "post"."id" as "post:id", "post"."title" as "post:title", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "comments"."id" as "id", "comments"."content" as "content", "comments"."_internalId" as "_internalId", "comments"."_version" as "_version" from "comments" left join "posts" as "post" on "comments"."postId" = "post"."_internalId" left join "users" as "author" on "comments"."authorId" = "author"."_internalId""`,
519
- );
520
- });
521
- });
522
-
523
- describe("custom-named id columns in joins", () => {
524
- // Schema with custom id column names
525
- const customIdSchema = schema((s) => {
526
- return s
527
- .addTable("products", (t) => {
528
- return t
529
- .addColumn("productId", idColumn())
530
- .addColumn("name", column("string"))
531
- .addColumn("price", column("integer"))
532
- .createIndex("idx_product_id", ["productId"]);
533
- })
534
- .addTable("categories", (t) => {
535
- return t
536
- .addColumn("categoryId", idColumn())
537
- .addColumn("categoryName", column("string"))
538
- .createIndex("idx_category_id", ["categoryId"]);
539
- })
540
- .addTable("product_categories", (t) => {
541
- return t
542
- .addColumn("id", idColumn())
543
- .addColumn("prodRef", referenceColumn())
544
- .addColumn("catRef", referenceColumn())
545
- .createIndex("idx_prod", ["prodRef"])
546
- .createIndex("idx_cat", ["catRef"]);
547
- })
548
- .addReference("product", {
549
- type: "one",
550
- from: { table: "product_categories", column: "prodRef" },
551
- to: { table: "products", column: "productId" },
552
- })
553
- .addReference("category", {
554
- type: "one",
555
- from: { table: "product_categories", column: "catRef" },
556
- to: { table: "categories", column: "categoryId" },
557
- });
558
- });
559
-
560
- function createCustomIdTestUOW() {
561
- const mockCompiler = createKyselyUOWCompiler("postgresql");
562
- const mockExecutor = {
563
- executeRetrievalPhase: async () => [],
564
- executeMutationPhase: async () => ({ success: true, createdInternalIds: [] }),
565
- };
566
- const mockDecoder: UOWDecoder = (rawResults, operations) => {
567
- if (rawResults.length !== operations.length) {
568
- throw new Error("rawResults and ops must have the same length");
569
- }
570
- return rawResults;
571
- };
572
- return new UnitOfWork(mockCompiler, mockExecutor, mockDecoder).forSchema(customIdSchema);
573
- }
574
-
575
- it("should compile join with custom id column names", () => {
576
- const uow = createCustomIdTestUOW();
577
- uow.find("product_categories", (b) =>
578
- b
579
- .whereIndex("primary")
580
- .select(["id"])
581
- .join((jb) =>
582
- jb
583
- .product((pb) => pb.select(["productId", "name"]))
584
- .category((cb) => cb.select(["categoryId", "categoryName"])),
585
- ),
586
- );
587
-
588
- const compiler = createKyselyUOWCompiler("postgresql");
589
- const compiled = uow.compile(compiler);
590
-
591
- expect(compiled.retrievalBatch).toHaveLength(1);
592
- const query = compiled.retrievalBatch[0];
593
- assert(query);
594
- expect(query.sql).toContain('"product"."productId"');
595
- expect(query.sql).toContain('"category"."categoryId"');
596
- // Custom id columns also get their _internalId included
597
- expect(query.sql).toContain('"product"."_internalId" as "product:_internalId"');
598
- expect(query.sql).toContain('"category"."_internalId" as "category:_internalId"');
599
- // Join conditions ALWAYS use _internalId (not custom column names) for performance
600
- expect(query.sql).toContain('"product_categories"."prodRef" = "product"."_internalId"');
601
- expect(query.sql).toContain('"product_categories"."catRef" = "category"."_internalId"');
602
- expect(query.sql).toMatchInlineSnapshot(
603
- `"select "product"."productId" as "product:productId", "product"."name" as "product:name", "product"."_internalId" as "product:_internalId", "product"."_version" as "product:_version", "category"."categoryId" as "category:categoryId", "category"."categoryName" as "category:categoryName", "category"."_internalId" as "category:_internalId", "category"."_version" as "category:_version", "product_categories"."id" as "id", "product_categories"."_internalId" as "_internalId", "product_categories"."_version" as "_version" from "product_categories" left join "products" as "product" on "product_categories"."prodRef" = "product"."_internalId" left join "categories" as "category" on "product_categories"."catRef" = "category"."_internalId""`,
604
- );
605
- });
606
-
607
- it("should handle custom id in join where clause", () => {
608
- const uow = createCustomIdTestUOW();
609
- uow.find("product_categories", (b) =>
610
- b
611
- .whereIndex("primary")
612
- .select(["id"])
613
- .join((jb) =>
614
- jb.product((pb) =>
615
- pb
616
- .select(["productId", "name"])
617
- .whereIndex("idx_product_id", (eb) => eb("productId", "=", "prod-456")),
618
- ),
619
- ),
620
- );
621
-
622
- const compiler = createKyselyUOWCompiler("postgresql");
623
- const compiled = uow.compile(compiler);
624
-
625
- expect(compiled.retrievalBatch).toHaveLength(1);
626
- const query = compiled.retrievalBatch[0];
627
- assert(query);
628
- expect(query.sql).toContain('"products"."productId" = $1');
629
- expect(query.sql).toContain('"product"."_internalId" as "product:_internalId"');
630
- // Join condition ALWAYS uses _internalId for performance
631
- expect(query.sql).toContain('"product_categories"."prodRef" = "product"."_internalId"');
632
- expect(query.sql).toMatchInlineSnapshot(
633
- `"select "product"."productId" as "product:productId", "product"."name" as "product:name", "product"."_internalId" as "product:_internalId", "product"."_version" as "product:_version", "product_categories"."id" as "id", "product_categories"."_internalId" as "_internalId", "product_categories"."_version" as "_version" from "product_categories" left join "products" as "product" on ("product_categories"."prodRef" = "product"."_internalId" and "products"."productId" = $1)"`,
634
- );
635
- });
636
-
637
- it("should handle select true with custom id columns", () => {
638
- const uow = createCustomIdTestUOW();
639
- uow.find("product_categories", (b) => b.whereIndex("primary").join((jb) => jb.product()));
640
-
641
- const compiler = createKyselyUOWCompiler("postgresql");
642
- const compiled = uow.compile(compiler);
643
-
644
- expect(compiled.retrievalBatch).toHaveLength(1);
645
- const query = compiled.retrievalBatch[0];
646
- assert(query);
647
- expect(query.sql).toContain('"product"."productId"');
648
- expect(query.sql).toContain('"product_categories"."id"');
649
- // With select true, _internalId IS now included when table has an id column
650
- expect(query.sql).toContain('"product"."_internalId" as "product:_internalId"');
651
- // Join condition ALWAYS uses _internalId for performance
652
- expect(query.sql).toContain('"product_categories"."prodRef" = "product"."_internalId"');
653
- expect(query.sql).toMatchInlineSnapshot(
654
- `"select "product"."productId" as "product:productId", "product"."name" as "product:name", "product"."price" as "product:price", "product"."_internalId" as "product:_internalId", "product"."_version" as "product:_version", "product_categories"."id" as "id", "product_categories"."prodRef" as "prodRef", "product_categories"."catRef" as "catRef", "product_categories"."_internalId" as "_internalId", "product_categories"."_version" as "_version" from "product_categories" left join "products" as "product" on "product_categories"."prodRef" = "product"."_internalId""`,
655
- );
656
- });
657
-
658
- it("should join tables with different custom id names", () => {
659
- const uow = createCustomIdTestUOW();
660
- uow.find("product_categories", (b) =>
661
- b
662
- .whereIndex("primary")
663
- .select(["id"])
664
- .join((jb) =>
665
- jb
666
- .product((pb) => pb.select(["productId"]))
667
- .category((cb) => cb.select(["categoryId"])),
668
- ),
669
- );
670
-
671
- const compiler = createKyselyUOWCompiler("postgresql");
672
- const compiled = uow.compile(compiler);
673
-
674
- expect(compiled.retrievalBatch).toHaveLength(1);
675
- const query = compiled.retrievalBatch[0];
676
- assert(query);
677
- expect(query.sql).toContain('"product"."productId"');
678
- expect(query.sql).toContain('"category"."categoryId"');
679
- expect(query.sql).not.toContain('"product"."id"'); // Should not have 'id', only 'productId'
680
- expect(query.sql).not.toContain('"category"."id"'); // Should not have 'id', only 'categoryId'
681
- // _internalId included for both since custom id columns are selected
682
- expect(query.sql).toContain('"product"."_internalId" as "product:_internalId"');
683
- expect(query.sql).toContain('"category"."_internalId" as "category:_internalId"');
684
- // Join conditions ALWAYS use _internalId for performance
685
- expect(query.sql).toContain('"product_categories"."prodRef" = "product"."_internalId"');
686
- expect(query.sql).toContain('"product_categories"."catRef" = "category"."_internalId"');
687
- expect(query.sql).toMatchInlineSnapshot(
688
- `"select "product"."productId" as "product:productId", "product"."_internalId" as "product:_internalId", "product"."_version" as "product:_version", "category"."categoryId" as "category:categoryId", "category"."_internalId" as "category:_internalId", "category"."_version" as "category:_version", "product_categories"."id" as "id", "product_categories"."_internalId" as "_internalId", "product_categories"."_version" as "_version" from "product_categories" left join "products" as "product" on "product_categories"."prodRef" = "product"."_internalId" left join "categories" as "category" on "product_categories"."catRef" = "category"."_internalId""`,
689
- );
690
- });
691
- });
692
-
693
- describe("special columns in joins - _internalId aliasing", () => {
694
- it("should properly alias _internalId for joined tables", () => {
695
- const uow = createTestUOW();
696
- uow.find("posts", (b) =>
697
- b
698
- .whereIndex("primary")
699
- .select(["id"])
700
- .join((jb) => jb.author((ab) => ab.select(["id"]))),
701
- );
702
-
703
- const compiler = createKyselyUOWCompiler("postgresql");
704
- const compiled = uow.compile(compiler);
705
-
706
- expect(compiled.retrievalBatch).toHaveLength(1);
707
- const query = compiled.retrievalBatch[0];
708
- assert(query);
709
- // Main table _internalId should be aliased as "_internalId"
710
- expect(query.sql).toContain('"posts"."_internalId" as "_internalId"');
711
- // Joined table _internalId should be aliased as "relation:_internalId" when id is selected
712
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
713
- expect(query.sql).toMatchInlineSnapshot(
714
- `"select "author"."id" as "author:id", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
715
- );
716
- });
717
-
718
- it("should handle _internalId in join conditions", () => {
719
- const uow = createTestUOW();
720
- uow.find("posts", (b) =>
721
- b
722
- .whereIndex("primary")
723
- .select(["id", "title"])
724
- .join((jb) => jb.author((ab) => ab.select(["id", "name"]))),
725
- );
726
-
727
- const compiler = createKyselyUOWCompiler("postgresql");
728
- const compiled = uow.compile(compiler);
729
-
730
- expect(compiled.retrievalBatch).toHaveLength(1);
731
- const query = compiled.retrievalBatch[0];
732
- assert(query);
733
- // Join condition should use _internalId
734
- expect(query.sql).toContain('"posts"."userId" = "author"."_internalId"');
735
- // Joined table _internalId is included when id is selected
736
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
737
- expect(query.sql).toMatchInlineSnapshot(
738
- `"select "author"."id" as "author:id", "author"."name" as "author:name", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "posts"."id" as "id", "posts"."title" as "title", "posts"."_internalId" as "_internalId", "posts"."_version" as "_version" from "posts" left join "users" as "author" on "posts"."userId" = "author"."_internalId""`,
739
- );
740
- });
741
-
742
- it("should handle multiple joins with _internalId tracking", () => {
743
- const uow = createTestUOW();
744
- uow.find("comments", (b) =>
745
- b
746
- .whereIndex("primary")
747
- .select(["id"])
748
- .join((jb) => jb.post((pb) => pb.select(["id"])).author((ab) => ab.select(["id"]))),
749
- );
750
-
751
- const compiler = createKyselyUOWCompiler("postgresql");
752
- const compiled = uow.compile(compiler);
753
-
754
- expect(compiled.retrievalBatch).toHaveLength(1);
755
- const query = compiled.retrievalBatch[0];
756
- assert(query);
757
- // All _internalId should be properly aliased
758
- expect(query.sql).toContain('"comments"."_internalId" as "_internalId"');
759
- // Joined tables with id selected also get _internalId
760
- expect(query.sql).toContain('"post"."_internalId" as "post:_internalId"');
761
- expect(query.sql).toContain('"author"."_internalId" as "author:_internalId"');
762
- // Join should use _internalId for connection
763
- expect(query.sql).toContain('"comments"."postId" = "post"."_internalId"');
764
- expect(query.sql).toContain('"comments"."authorId" = "author"."_internalId"');
765
- expect(query.sql).toMatchInlineSnapshot(
766
- `"select "post"."id" as "post:id", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "author"."id" as "author:id", "author"."_internalId" as "author:_internalId", "author"."_version" as "author:_version", "comments"."id" as "id", "comments"."_internalId" as "_internalId", "comments"."_version" as "_version" from "comments" left join "posts" as "post" on "comments"."postId" = "post"."_internalId" left join "users" as "author" on "comments"."authorId" = "author"."_internalId""`,
767
- );
768
- });
769
-
770
- it("should handle self-referencing join with _internalId", () => {
771
- const uow = createTestUOW();
772
- uow.find("users", (b) =>
773
- b
774
- .whereIndex("primary")
775
- .select(["id", "name"])
776
- .join((jb) => jb.inviter((ib) => ib.select(["id", "name"]))),
777
- );
778
-
779
- const compiler = createKyselyUOWCompiler("postgresql");
780
- const compiled = uow.compile(compiler);
781
-
782
- expect(compiled.retrievalBatch).toHaveLength(1);
783
- const query = compiled.retrievalBatch[0];
784
- assert(query);
785
- expect(query.sql).toContain('"users"."invitedBy" = "inviter"."_internalId"');
786
- expect(query.sql).toContain('"users"."_internalId" as "_internalId"');
787
- // Self-join with id selected also includes _internalId for joined instance
788
- expect(query.sql).toContain('"inviter"."_internalId" as "inviter:_internalId"');
789
- expect(query.sql).toMatchInlineSnapshot(
790
- `"select "inviter"."id" as "inviter:id", "inviter"."name" as "inviter:name", "inviter"."_internalId" as "inviter:_internalId", "inviter"."_version" as "inviter:_version", "users"."id" as "id", "users"."name" as "name", "users"."_internalId" as "_internalId", "users"."_version" as "_version" from "users" left join "users" as "inviter" on "users"."invitedBy" = "inviter"."_internalId""`,
791
- );
792
- });
793
- });
794
- });