@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
@@ -0,0 +1,314 @@
1
+ import { UOWOperationCompiler } from "../../shared/uow-operation-compiler";
2
+ import type { CompiledQuery } from "kysely";
3
+ import type { DriverConfig } from "../driver-config";
4
+ import type { TableNameMapper } from "../../shared/table-name-mapper";
5
+ import type {
6
+ RetrievalOperation,
7
+ MutationOperation,
8
+ CompiledMutation,
9
+ } from "../../../query/unit-of-work/unit-of-work";
10
+ import type { AnyColumn, AnySchema } from "../../../schema/create";
11
+ import { buildCondition } from "../../../query/condition-builder";
12
+ import { createSQLQueryCompiler } from "./create-sql-query-compiler";
13
+ import { SQLQueryCompiler } from "./sql-query-compiler";
14
+ import { buildCursorCondition } from "./cursor-utils";
15
+ import type { Condition } from "../../../query/condition-builder";
16
+ import { buildFindOptions } from "../../../query/orm/orm";
17
+ import type { AnySelectClause } from "../../../query/simple-query-interface";
18
+ import { createColdKysely } from "../migration/cold-kysely";
19
+
20
+ /**
21
+ * Generic SQL UOW Operation Compiler.
22
+ *
23
+ * Uses SQLQueryCompiler for dialect-specific SQL generation while handling
24
+ * high-level business logic like cursor pagination, version checking, and index resolution.
25
+ */
26
+ export class GenericSQLUOWOperationCompiler extends UOWOperationCompiler<CompiledQuery> {
27
+ constructor(
28
+ driverConfig: DriverConfig,
29
+ mapperFactory?: (namespace: string | undefined) => TableNameMapper | undefined,
30
+ ) {
31
+ super(driverConfig, mapperFactory);
32
+ }
33
+
34
+ /**
35
+ * Get SQL compiler for a specific namespace
36
+ */
37
+ private getSQLCompiler(namespace: string | undefined): SQLQueryCompiler {
38
+ const mapper = this.getMapperForOperation(namespace);
39
+ const kysely = createColdKysely(this.driverConfig.databaseType);
40
+ return createSQLQueryCompiler(kysely, this.driverConfig, mapper);
41
+ }
42
+
43
+ override compileCount(
44
+ op: RetrievalOperation<AnySchema> & { type: "count" },
45
+ ): CompiledQuery | null {
46
+ const sqlCompiler = this.getSQLCompiler(op.namespace);
47
+
48
+ // Build where condition
49
+ let conditions = op.options.where
50
+ ? buildCondition(op.table.columns, op.options.where)
51
+ : undefined;
52
+
53
+ if (conditions === true) {
54
+ conditions = undefined;
55
+ }
56
+ if (conditions === false) {
57
+ return null;
58
+ }
59
+
60
+ return sqlCompiler.compileCount(op.table, { where: conditions });
61
+ }
62
+
63
+ override compileFind(op: RetrievalOperation<AnySchema> & { type: "find" }): CompiledQuery | null {
64
+ const sqlCompiler = this.getSQLCompiler(op.namespace);
65
+
66
+ // Extract options
67
+ const {
68
+ useIndex: _useIndex,
69
+ orderByIndex,
70
+ joins: join,
71
+ after,
72
+ before,
73
+ pageSize,
74
+ ...findManyOptions
75
+ } = op.options;
76
+
77
+ // Get index columns for ordering and cursor pagination
78
+ let indexColumns: AnyColumn[] = [];
79
+ let orderDirection: "asc" | "desc" = "asc";
80
+
81
+ if (orderByIndex) {
82
+ const index = op.table.indexes[orderByIndex.indexName];
83
+ orderDirection = orderByIndex.direction;
84
+
85
+ if (!index) {
86
+ // If _primary index doesn't exist, fall back to internal ID column
87
+ if (orderByIndex.indexName === "_primary") {
88
+ indexColumns = [op.table.getIdColumn()];
89
+ } else {
90
+ throw new Error(
91
+ `Index "${orderByIndex.indexName}" not found on table "${op.table.name}"`,
92
+ );
93
+ }
94
+ } else {
95
+ // Order by all columns in the index with the specified direction
96
+ indexColumns = index.columns;
97
+ }
98
+ }
99
+
100
+ // Convert orderByIndex to orderBy format
101
+ let orderBy: [AnyColumn, "asc" | "desc"][] | undefined;
102
+ if (indexColumns.length > 0) {
103
+ orderBy = indexColumns.map((col) => [col, orderDirection]);
104
+ }
105
+
106
+ // Handle cursor pagination - build a cursor condition
107
+ // TODO: Multi-column cursor pagination not yet supported
108
+ if ((after || before) && indexColumns.length > 1) {
109
+ throw new Error(
110
+ "Multi-column cursor pagination is not yet supported in Generic SQL implementation",
111
+ );
112
+ }
113
+ const cursorCondition = buildCursorCondition(
114
+ after || before,
115
+ indexColumns,
116
+ orderDirection,
117
+ !!after,
118
+ this.driverConfig,
119
+ );
120
+
121
+ // Combine user where clause with cursor condition
122
+ let combinedWhere: Condition | undefined;
123
+ if (findManyOptions.where) {
124
+ const whereResult = buildCondition(op.table.columns, findManyOptions.where);
125
+ if (whereResult === true) {
126
+ combinedWhere = undefined;
127
+ } else if (whereResult === false) {
128
+ return null;
129
+ } else {
130
+ combinedWhere = whereResult;
131
+ }
132
+ }
133
+
134
+ if (cursorCondition) {
135
+ if (combinedWhere) {
136
+ combinedWhere = {
137
+ type: "and",
138
+ items: [combinedWhere, cursorCondition],
139
+ };
140
+ } else {
141
+ combinedWhere = cursorCondition;
142
+ }
143
+ }
144
+
145
+ // For cursor pagination, fetch one extra item to determine if there's a next page
146
+ const effectiveLimit = pageSize && op.withCursor ? pageSize + 1 : pageSize;
147
+
148
+ // When we have joins, use the query builder directly
149
+ if (join && join.length > 0) {
150
+ return sqlCompiler.compileFindMany(op.table, {
151
+ select: (findManyOptions.select ?? true) as AnySelectClause,
152
+ where: combinedWhere,
153
+ orderBy,
154
+ limit: effectiveLimit,
155
+ join,
156
+ });
157
+ }
158
+
159
+ // Otherwise, use buildFindOptions to process the query options
160
+ const compiledOptions = buildFindOptions(op.table, {
161
+ ...findManyOptions,
162
+ where: combinedWhere ? () => combinedWhere! : undefined,
163
+ orderBy: orderBy?.map(([col, dir]) => [col.ormName, dir]),
164
+ limit: effectiveLimit,
165
+ });
166
+
167
+ if (compiledOptions === false) {
168
+ return null;
169
+ }
170
+
171
+ return sqlCompiler.compileFindMany(op.table, compiledOptions);
172
+ }
173
+
174
+ override compileCreate(
175
+ op: MutationOperation<AnySchema> & { type: "create" },
176
+ ): CompiledMutation<CompiledQuery> | null {
177
+ const sqlCompiler = this.getSQLCompiler(op.namespace);
178
+ const table = this.getTable(op.schema, op.table);
179
+
180
+ return {
181
+ query: sqlCompiler.compileCreate(table, op.values),
182
+ op: "create",
183
+ expectedAffectedRows: null, // creates don't need affected row checks
184
+ expectedReturnedRows: null,
185
+ };
186
+ }
187
+
188
+ override compileUpdate(
189
+ op: MutationOperation<AnySchema> & { type: "update" },
190
+ ): CompiledMutation<CompiledQuery> | null {
191
+ const sqlCompiler = this.getSQLCompiler(op.namespace);
192
+ const table = this.getTable(op.schema, op.table);
193
+ const idColumn = table.getIdColumn();
194
+ const versionColumn = table.getVersionColumn();
195
+
196
+ const externalId = this.getExternalId(op.id);
197
+ const versionToCheck = this.getVersionToCheck(op.id, op.checkVersion);
198
+
199
+ // Build WHERE clause that filters by ID and optionally by version
200
+ const conditionsResult =
201
+ versionToCheck !== undefined
202
+ ? buildCondition(table.columns, (eb) =>
203
+ eb.and(
204
+ eb(idColumn.ormName, "=", externalId),
205
+ eb(versionColumn.ormName, "=", versionToCheck),
206
+ ),
207
+ )
208
+ : buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
209
+
210
+ if (conditionsResult === false) {
211
+ return null;
212
+ }
213
+
214
+ const conditions: Condition | undefined =
215
+ conditionsResult === true ? undefined : conditionsResult;
216
+
217
+ // Determine if we should use RETURNING-based checking
218
+ // Use RETURNING when driver supports it but doesn't support affected rows reporting
219
+ const useReturningForCheck =
220
+ op.checkVersion &&
221
+ this.driverConfig.supportsReturning &&
222
+ !this.driverConfig.supportsRowsAffected;
223
+
224
+ const query = sqlCompiler.compileUpdate(table, {
225
+ set: op.set,
226
+ where: conditions,
227
+ returning: useReturningForCheck,
228
+ });
229
+
230
+ return {
231
+ query,
232
+ op: "update",
233
+ expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
234
+ expectedReturnedRows: useReturningForCheck ? 1 : null,
235
+ };
236
+ }
237
+
238
+ override compileDelete(
239
+ op: MutationOperation<AnySchema> & { type: "delete" },
240
+ ): CompiledMutation<CompiledQuery> | null {
241
+ const sqlCompiler = this.getSQLCompiler(op.namespace);
242
+ const table = this.getTable(op.schema, op.table);
243
+ const idColumn = table.getIdColumn();
244
+ const versionColumn = table.getVersionColumn();
245
+
246
+ const externalId = this.getExternalId(op.id);
247
+ const versionToCheck = this.getVersionToCheck(op.id, op.checkVersion);
248
+
249
+ // Build WHERE clause that filters by ID and optionally by version
250
+ const conditionsResult =
251
+ versionToCheck !== undefined
252
+ ? buildCondition(table.columns, (eb) =>
253
+ eb.and(
254
+ eb(idColumn.ormName, "=", externalId),
255
+ eb(versionColumn.ormName, "=", versionToCheck),
256
+ ),
257
+ )
258
+ : buildCondition(table.columns, (eb) => eb(idColumn.ormName, "=", externalId));
259
+
260
+ if (conditionsResult === false) {
261
+ return null;
262
+ }
263
+
264
+ const conditions: Condition | undefined =
265
+ conditionsResult === true ? undefined : conditionsResult;
266
+
267
+ // Determine if we should use RETURNING-based checking
268
+ // Use RETURNING when driver supports it but doesn't support affected rows reporting
269
+ const useReturningForCheck =
270
+ op.checkVersion &&
271
+ this.driverConfig.supportsReturning &&
272
+ !this.driverConfig.supportsRowsAffected;
273
+
274
+ const query = sqlCompiler.compileDelete(table, {
275
+ where: conditions,
276
+ returning: useReturningForCheck,
277
+ });
278
+
279
+ return {
280
+ query,
281
+ op: "delete",
282
+ expectedAffectedRows: useReturningForCheck ? null : op.checkVersion ? 1n : null,
283
+ expectedReturnedRows: useReturningForCheck ? 1 : null,
284
+ };
285
+ }
286
+
287
+ override compileCheck(
288
+ op: MutationOperation<AnySchema> & { type: "check" },
289
+ ): CompiledMutation<CompiledQuery> {
290
+ const sqlCompiler = this.getSQLCompiler(op.namespace);
291
+ const table = this.getTable(op.schema, op.table);
292
+ const idColumn = table.getIdColumn();
293
+ const versionColumn = table.getVersionColumn();
294
+
295
+ const externalId = op.id.externalId;
296
+ const version = op.id.version;
297
+
298
+ // Build a SELECT 1 query to check if the row exists with the correct version
299
+ const condition = buildCondition(table.columns, (eb) =>
300
+ eb.and(eb(idColumn.ormName, "=", externalId), eb(versionColumn.ormName, "=", version)),
301
+ );
302
+
303
+ if (typeof condition === "boolean") {
304
+ throw new Error("Condition is a boolean, but should be a condition object.");
305
+ }
306
+
307
+ return {
308
+ query: sqlCompiler.compileCheck(table, condition),
309
+ op: "check",
310
+ expectedAffectedRows: null,
311
+ expectedReturnedRows: 1, // Check that exactly 1 row was returned
312
+ };
313
+ }
314
+ }
@@ -0,0 +1,256 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { column, idColumn, referenceColumn, schema } from "../../../schema/create";
3
+ import { mapSelect, extendSelect } from "./select-builder";
4
+
5
+ describe("select-builder", () => {
6
+ const testSchema = schema((s) => {
7
+ return s
8
+ .addTable("users", (t) => {
9
+ return t
10
+ .addColumn("id", idColumn())
11
+ .addColumn("name", column("string"))
12
+ .addColumn("email", column("string"))
13
+ .addColumn("age", column("integer").nullable())
14
+ .addColumn("isActive", column("bool"))
15
+ .addColumn("createdAt", column("timestamp"));
16
+ })
17
+ .addTable("posts", (t) => {
18
+ return t
19
+ .addColumn("id", idColumn())
20
+ .addColumn("title", column("string"))
21
+ .addColumn("content", column("string"))
22
+ .addColumn("userId", referenceColumn())
23
+ .addColumn("viewCount", column("integer").defaultTo(0))
24
+ .addColumn("publishedAt", column("timestamp").nullable());
25
+ })
26
+ .addReference("author", {
27
+ type: "one",
28
+ from: { table: "posts", column: "userId" },
29
+ to: { table: "users", column: "id" },
30
+ });
31
+ });
32
+
33
+ const usersTable = testSchema.tables.users;
34
+ const postsTable = testSchema.tables.posts;
35
+
36
+ describe("mapSelect", () => {
37
+ it("should map select clause with array of keys", () => {
38
+ const result = mapSelect(["id", "name", "email"], usersTable);
39
+ expect(result).toEqual([
40
+ "users.id as id",
41
+ "users.name as name",
42
+ "users.email as email",
43
+ "users._internalId as _internalId",
44
+ "users._version as _version",
45
+ ]);
46
+ });
47
+
48
+ it("should map select all columns when true", () => {
49
+ const result = mapSelect(true, usersTable);
50
+ expect(result).toEqual([
51
+ "users.id as id",
52
+ "users.name as name",
53
+ "users.email as email",
54
+ "users.age as age",
55
+ "users.isActive as isActive",
56
+ "users.createdAt as createdAt",
57
+ "users._internalId as _internalId",
58
+ "users._version as _version",
59
+ ]);
60
+ });
61
+
62
+ it("should map select with relation prefix", () => {
63
+ const result = mapSelect(["id", "name"], usersTable, { relation: "author" });
64
+ expect(result).toEqual([
65
+ "users.id as author:id",
66
+ "users.name as author:name",
67
+ "users._internalId as author:_internalId",
68
+ "users._version as author:_version",
69
+ ]);
70
+ });
71
+
72
+ it("should map select with custom table name", () => {
73
+ const result = mapSelect(["id", "title"], postsTable, { tableName: "p" });
74
+ expect(result).toEqual([
75
+ "p.id as id",
76
+ "p.title as title",
77
+ "p._internalId as _internalId",
78
+ "p._version as _version",
79
+ ]);
80
+ });
81
+
82
+ it("should map select with both relation and custom table name", () => {
83
+ const result = mapSelect(["id", "title"], postsTable, {
84
+ relation: "posts",
85
+ tableName: "p",
86
+ });
87
+ expect(result).toEqual([
88
+ "p.id as posts:id",
89
+ "p.title as posts:title",
90
+ "p._internalId as posts:_internalId",
91
+ "p._version as posts:_version",
92
+ ]);
93
+ });
94
+
95
+ it("should handle single column select", () => {
96
+ const result = mapSelect(["name"], usersTable);
97
+ expect(result).toEqual([
98
+ "users.name as name",
99
+ "users._internalId as _internalId",
100
+ "users._version as _version",
101
+ ]);
102
+ });
103
+
104
+ it("should skip hidden columns when explicitly selecting", () => {
105
+ // When an array is passed, hidden columns should not be included in the select
106
+ // (unless they are in the array), but they should always be added at the end
107
+ const result = mapSelect(["name", "email"], usersTable);
108
+ // Should not duplicate _internalId or _version in the main select
109
+ expect(result).toEqual([
110
+ "users.name as name",
111
+ "users.email as email",
112
+ "users._internalId as _internalId",
113
+ "users._version as _version",
114
+ ]);
115
+ });
116
+
117
+ it("should always include hidden columns", () => {
118
+ // Hidden columns (_internalId, _version) should always be included
119
+ const result = mapSelect(["name"], usersTable);
120
+ expect(result.some((col) => col.includes("_internalId"))).toBe(true);
121
+ expect(result.some((col) => col.includes("_version"))).toBe(true);
122
+ });
123
+
124
+ it("should handle empty select array", () => {
125
+ const result = mapSelect([], usersTable);
126
+ // Should still include hidden columns
127
+ expect(result).toEqual(["users._internalId as _internalId", "users._version as _version"]);
128
+ });
129
+
130
+ it("should work with different table schemas", () => {
131
+ const result = mapSelect(["id", "title", "content"], postsTable);
132
+ expect(result).toEqual([
133
+ "posts.id as id",
134
+ "posts.title as title",
135
+ "posts.content as content",
136
+ "posts._internalId as _internalId",
137
+ "posts._version as _version",
138
+ ]);
139
+ });
140
+ });
141
+
142
+ describe("extendSelect", () => {
143
+ it("should extend array select with new key", () => {
144
+ const builder = extendSelect(["name", "email"]);
145
+ builder.extend("id");
146
+ const compiled = builder.compile();
147
+
148
+ expect(compiled.result).toEqual(["name", "email", "id"]);
149
+ expect(compiled.extendedKeys).toEqual(["id"]);
150
+ });
151
+
152
+ it("should not duplicate existing keys", () => {
153
+ const builder = extendSelect(["name", "email"]);
154
+ builder.extend("name");
155
+ const compiled = builder.compile();
156
+
157
+ expect(compiled.result).toEqual(["name", "email"]);
158
+ expect(compiled.extendedKeys).toEqual([]);
159
+ });
160
+
161
+ it("should handle true select clause", () => {
162
+ const builder = extendSelect(true);
163
+ builder.extend("id");
164
+ const compiled = builder.compile();
165
+
166
+ expect(compiled.result).toBe(true);
167
+ expect(compiled.extendedKeys).toEqual([]);
168
+ });
169
+
170
+ it("should track multiple extended keys", () => {
171
+ const builder = extendSelect(["name"]);
172
+ builder.extend("id");
173
+ builder.extend("email");
174
+ builder.extend("age");
175
+ const compiled = builder.compile();
176
+
177
+ expect(compiled.result).toEqual(["name", "id", "email", "age"]);
178
+ expect(compiled.extendedKeys).toEqual(["id", "email", "age"]);
179
+ });
180
+
181
+ it("should remove extended keys from record", () => {
182
+ const builder = extendSelect(["name", "email"]);
183
+ builder.extend("id");
184
+ const compiled = builder.compile();
185
+
186
+ const record = { id: "123", name: "John", email: "john@example.com", age: 30 };
187
+ compiled.removeExtendedKeys(record);
188
+
189
+ expect(record).toEqual({ name: "John", email: "john@example.com", age: 30 });
190
+ });
191
+
192
+ it("should not remove non-extended keys", () => {
193
+ const builder = extendSelect(["name", "email", "id"]);
194
+ builder.extend("age");
195
+ const compiled = builder.compile();
196
+
197
+ const record = { id: "123", name: "John", email: "john@example.com", age: 30 };
198
+ compiled.removeExtendedKeys(record);
199
+
200
+ expect(record).toEqual({ id: "123", name: "John", email: "john@example.com" });
201
+ });
202
+
203
+ it("should handle empty extended keys", () => {
204
+ const builder = extendSelect(["name", "email"]);
205
+ const compiled = builder.compile();
206
+
207
+ const record = { name: "John", email: "john@example.com" };
208
+ compiled.removeExtendedKeys(record);
209
+
210
+ expect(record).toEqual({ name: "John", email: "john@example.com" });
211
+ });
212
+
213
+ it("should handle multiple extends with duplicates", () => {
214
+ const builder = extendSelect(["name"]);
215
+ builder.extend("id");
216
+ builder.extend("email");
217
+ builder.extend("id"); // Duplicate
218
+ const compiled = builder.compile();
219
+
220
+ // Should not duplicate 'id'
221
+ expect(compiled.result).toEqual(["name", "id", "email"]);
222
+ expect(compiled.extendedKeys).toEqual(["id", "email"]);
223
+ });
224
+
225
+ it("should return mutated record from removeExtendedKeys", () => {
226
+ const builder = extendSelect(["name"]);
227
+ builder.extend("id");
228
+ const compiled = builder.compile();
229
+
230
+ const record = { id: "123", name: "John" };
231
+ const result = compiled.removeExtendedKeys(record);
232
+
233
+ // Should return the same record (mutated)
234
+ expect(result).toBe(record);
235
+ expect(result).toEqual({ name: "John" });
236
+ });
237
+
238
+ it("should handle extending with empty original select", () => {
239
+ const builder = extendSelect([]);
240
+ builder.extend("id");
241
+ builder.extend("name");
242
+ const compiled = builder.compile();
243
+
244
+ expect(compiled.result).toEqual(["id", "name"]);
245
+ expect(compiled.extendedKeys).toEqual(["id", "name"]);
246
+ });
247
+
248
+ it("should preserve original select order", () => {
249
+ const builder = extendSelect(["email", "name"]);
250
+ builder.extend("id");
251
+ const compiled = builder.compile();
252
+
253
+ expect(compiled.result).toEqual(["email", "name", "id"]);
254
+ });
255
+ });
256
+ });
@@ -0,0 +1,137 @@
1
+ import type { AnyTable } from "../../../schema/create";
2
+ import type { AnySelectClause } from "../../../query/simple-query-interface";
3
+
4
+ /**
5
+ * Maps a select clause to SQL column names with optional aliases.
6
+ *
7
+ * Converts application-level select clauses (either array of keys or "select all")
8
+ * into SQL-compatible column selections with proper aliasing for relations.
9
+ *
10
+ * @param select - The select clause (array of keys or true for all columns)
11
+ * @param table - The table schema containing column definitions
12
+ * @param options - Optional configuration
13
+ * @param options.relation - Relation name to prefix in aliases (for joined data)
14
+ * @param options.tableName - Override the table name in the SQL (defaults to table.name)
15
+ * @returns Array of SQL select strings in the format "tableName.columnName as alias"
16
+ * @internal
17
+ */
18
+ export function mapSelect(
19
+ select: AnySelectClause,
20
+ table: AnyTable,
21
+ options: {
22
+ relation?: string;
23
+ tableName?: string;
24
+ } = {},
25
+ ): string[] {
26
+ const { relation, tableName = table.name } = options;
27
+ const out: string[] = [];
28
+ const keys = Array.isArray(select) ? select : Object.keys(table.columns);
29
+
30
+ for (const key of keys) {
31
+ const col = table.columns[key];
32
+
33
+ // Skip hidden columns when explicitly selecting
34
+ if (Array.isArray(select) && col.isHidden) {
35
+ continue;
36
+ }
37
+
38
+ // Add the column to the select list
39
+ const name = relation ? `${relation}:${key}` : key;
40
+ out.push(`${tableName}.${col.name} as ${name}`);
41
+ }
42
+
43
+ // Always include hidden columns (for FragnoId construction with internal ID and version)
44
+ for (const key in table.columns) {
45
+ const col = table.columns[key];
46
+ if (col.isHidden && !keys.includes(key)) {
47
+ const name = relation ? `${relation}:${key}` : key;
48
+ out.push(`${tableName}.${col.name} as ${name}`);
49
+ }
50
+ }
51
+
52
+ return out;
53
+ }
54
+
55
+ /**
56
+ * Result type from compiling a select clause with extensions.
57
+ * @internal
58
+ */
59
+ export interface CompiledSelect {
60
+ /**
61
+ * The final select clause to use in the query
62
+ */
63
+ result: AnySelectClause;
64
+
65
+ /**
66
+ * Keys that were added to the select clause (not originally requested)
67
+ */
68
+ extendedKeys: string[];
69
+
70
+ /**
71
+ * Removes the extended keys from a record (mutates the record).
72
+ * Used to clean up keys that were only needed for join operations.
73
+ *
74
+ * @param record - The record to remove extended keys from
75
+ * @returns The same record with extended keys removed
76
+ */
77
+ removeExtendedKeys: (record: Record<string, unknown>) => Record<string, unknown>;
78
+ }
79
+
80
+ /**
81
+ * Builder for extending a select clause with additional keys.
82
+ * @internal
83
+ */
84
+ export interface SelectBuilder {
85
+ /**
86
+ * Adds a key to the select clause if not already present.
87
+ * Tracks which keys were added for later removal.
88
+ *
89
+ * @param key - The key to add to the select clause
90
+ */
91
+ extend: (key: string) => void;
92
+
93
+ /**
94
+ * Compiles the select clause into its final form.
95
+ *
96
+ * @returns The compiled select information
97
+ */
98
+ compile: () => CompiledSelect;
99
+ }
100
+
101
+ /**
102
+ * Creates a builder that can extend a select clause with additional keys.
103
+ *
104
+ * This is useful when you need to temporarily include columns for join operations
105
+ * or other internal processing, but don't want them in the final result.
106
+ *
107
+ * @param original - The original select clause from the user
108
+ * @returns A select builder with extend() and compile() methods
109
+ * @internal
110
+ */
111
+ export function extendSelect(original: AnySelectClause): SelectBuilder {
112
+ const select = Array.isArray(original) ? new Set(original) : true;
113
+ const extendedKeys: string[] = [];
114
+
115
+ return {
116
+ extend(key) {
117
+ if (select === true || select.has(key)) {
118
+ return;
119
+ }
120
+
121
+ select.add(key);
122
+ extendedKeys.push(key);
123
+ },
124
+ compile() {
125
+ return {
126
+ result: select instanceof Set ? Array.from(select) : true,
127
+ extendedKeys,
128
+ removeExtendedKeys(record) {
129
+ for (const key of extendedKeys) {
130
+ delete record[key];
131
+ }
132
+ return record;
133
+ },
134
+ };
135
+ },
136
+ };
137
+ }