@fragno-dev/db 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -0,0 +1,744 @@
1
+ import { Kysely, PostgresDialect } from "kysely";
2
+ import { beforeAll, describe, expect, it } from "vitest";
3
+ import { column, idColumn, referenceColumn, schema } from "../../../schema/create";
4
+ import { fullSQLName, buildWhere, processReferenceSubqueries } from "./where-builder";
5
+ import { ReferenceSubquery } from "../../../query/value-encoding";
6
+ import { BetterSQLite3DriverConfig, NodePostgresDriverConfig } from "../driver-config";
7
+
8
+ describe("where-builder", () => {
9
+ const testSchema = schema((s) => {
10
+ return s
11
+ .addTable("users", (t) => {
12
+ return t
13
+ .addColumn("id", idColumn())
14
+ .addColumn("name", column("string"))
15
+ .addColumn("email", column("string"))
16
+ .addColumn("age", column("integer").nullable())
17
+ .addColumn("isActive", column("bool"))
18
+ .addColumn("createdAt", column("timestamp"));
19
+ })
20
+ .addTable("posts", (t) => {
21
+ return t
22
+ .addColumn("id", idColumn())
23
+ .addColumn("title", column("string"))
24
+ .addColumn("content", column("string"))
25
+ .addColumn("userId", referenceColumn())
26
+ .addColumn("viewCount", column("integer").defaultTo(0))
27
+ .addColumn("publishedAt", column("timestamp").nullable());
28
+ })
29
+ .addReference("author", {
30
+ type: "one",
31
+ from: { table: "posts", column: "userId" },
32
+ to: { table: "users", column: "id" },
33
+ });
34
+ });
35
+
36
+ const usersTable = testSchema.tables.users;
37
+ const postsTable = testSchema.tables.posts;
38
+
39
+ describe("fullSQLName", () => {
40
+ it("should return fully qualified column name", () => {
41
+ const result = fullSQLName(usersTable.columns.name);
42
+ expect(result).toBe("users.name");
43
+ });
44
+
45
+ it("should work with different tables", () => {
46
+ const result = fullSQLName(postsTable.columns.title);
47
+ expect(result).toBe("posts.title");
48
+ });
49
+
50
+ it("should work with id column", () => {
51
+ const result = fullSQLName(usersTable.columns.id);
52
+ expect(result).toBe("users.id");
53
+ });
54
+
55
+ it("should work with table name mapper", () => {
56
+ const mapper = {
57
+ toPhysical: (ormName: string) => `prefix_${ormName}`,
58
+ toLogical: (physicalName: string) => physicalName.replace("prefix_", ""),
59
+ };
60
+ const result = fullSQLName(usersTable.columns.name, mapper);
61
+ expect(result).toBe("prefix_users.name");
62
+ });
63
+ });
64
+
65
+ describe("buildWhere", () => {
66
+ // Mock expression builder for testing
67
+ const createMockEB = () => {
68
+ const mockEB = ((col: string, op: string, val: unknown) => {
69
+ return { type: "compare", col, op, val };
70
+ }) as any; // eslint-disable-line @typescript-eslint/no-explicit-any
71
+
72
+ mockEB.and = (conditions: unknown[]) => {
73
+ return { type: "and", conditions };
74
+ };
75
+
76
+ mockEB.or = (conditions: unknown[]) => {
77
+ return { type: "or", conditions };
78
+ };
79
+
80
+ mockEB.not = (condition: unknown) => {
81
+ return { type: "not", condition };
82
+ };
83
+
84
+ mockEB.ref = (name: string) => {
85
+ return { type: "ref", name };
86
+ };
87
+
88
+ mockEB.selectFrom = (tableName: string) => {
89
+ const query = {
90
+ tableName,
91
+ _select: null as string | null,
92
+ _where: null as { col: string; op: string; val: unknown } | null,
93
+ _limit: null as number | null,
94
+ select: (col: string) => {
95
+ query._select = col;
96
+ return query;
97
+ },
98
+ where: (col: string, op: string, val: unknown) => {
99
+ query._where = { col, op, val };
100
+ return query;
101
+ },
102
+ limit: (n: number) => {
103
+ query._limit = n;
104
+ return query;
105
+ },
106
+ };
107
+ return query;
108
+ };
109
+
110
+ return mockEB;
111
+ };
112
+
113
+ describe("comparison operators", () => {
114
+ it("should build simple equality comparison", () => {
115
+ const condition = {
116
+ type: "compare" as const,
117
+ a: usersTable.columns.name,
118
+ operator: "=" as const,
119
+ b: "John",
120
+ };
121
+
122
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
123
+ expect(result).toEqual({
124
+ type: "compare",
125
+ col: "users.name",
126
+ op: "=",
127
+ val: "John",
128
+ });
129
+ });
130
+
131
+ it("should build greater than comparison", () => {
132
+ const condition = {
133
+ type: "compare" as const,
134
+ a: usersTable.columns.age,
135
+ operator: ">" as const,
136
+ b: 18,
137
+ };
138
+
139
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
140
+ expect(result).toEqual({
141
+ type: "compare",
142
+ col: "users.age",
143
+ op: ">",
144
+ val: 18,
145
+ });
146
+ });
147
+
148
+ it("should build less than comparison", () => {
149
+ const condition = {
150
+ type: "compare" as const,
151
+ a: usersTable.columns.age,
152
+ operator: "<" as const,
153
+ b: 65,
154
+ };
155
+
156
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
157
+ expect(result).toEqual({
158
+ type: "compare",
159
+ col: "users.age",
160
+ op: "<",
161
+ val: 65,
162
+ });
163
+ });
164
+
165
+ it("should build not equals comparison", () => {
166
+ const condition = {
167
+ type: "compare" as const,
168
+ a: usersTable.columns.isActive,
169
+ operator: "!=" as const,
170
+ b: true,
171
+ };
172
+
173
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
174
+ expect(result).toEqual({
175
+ type: "compare",
176
+ col: "users.isActive",
177
+ op: "!=",
178
+ val: true,
179
+ });
180
+ });
181
+
182
+ it("should build greater than or equal comparison", () => {
183
+ const condition = {
184
+ type: "compare" as const,
185
+ a: usersTable.columns.age,
186
+ operator: ">=" as const,
187
+ b: 21,
188
+ };
189
+
190
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
191
+ expect(result).toEqual({
192
+ type: "compare",
193
+ col: "users.age",
194
+ op: ">=",
195
+ val: 21,
196
+ });
197
+ });
198
+
199
+ it("should build less than or equal comparison", () => {
200
+ const condition = {
201
+ type: "compare" as const,
202
+ a: usersTable.columns.age,
203
+ operator: "<=" as const,
204
+ b: 65,
205
+ };
206
+
207
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
208
+ expect(result).toEqual({
209
+ type: "compare",
210
+ col: "users.age",
211
+ op: "<=",
212
+ val: 65,
213
+ });
214
+ });
215
+ });
216
+
217
+ describe("string operators", () => {
218
+ it("should build contains operator", () => {
219
+ const condition = {
220
+ type: "compare" as const,
221
+ a: usersTable.columns.name,
222
+ operator: "contains" as const,
223
+ b: "john",
224
+ };
225
+
226
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
227
+ expect(result).toEqual({
228
+ type: "compare",
229
+ col: "users.name",
230
+ op: "like",
231
+ val: "%john%",
232
+ });
233
+ });
234
+
235
+ it("should build not contains operator", () => {
236
+ const condition = {
237
+ type: "compare" as const,
238
+ a: usersTable.columns.name,
239
+ operator: "not contains" as const,
240
+ b: "admin",
241
+ };
242
+
243
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
244
+ expect(result).toEqual({
245
+ type: "compare",
246
+ col: "users.name",
247
+ op: "not like",
248
+ val: "%admin%",
249
+ });
250
+ });
251
+
252
+ it("should build starts with operator", () => {
253
+ const condition = {
254
+ type: "compare" as const,
255
+ a: usersTable.columns.email,
256
+ operator: "starts with" as const,
257
+ b: "admin",
258
+ };
259
+
260
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
261
+ expect(result).toEqual({
262
+ type: "compare",
263
+ col: "users.email",
264
+ op: "like",
265
+ val: "admin%",
266
+ });
267
+ });
268
+
269
+ it("should build not starts with operator", () => {
270
+ const condition = {
271
+ type: "compare" as const,
272
+ a: usersTable.columns.email,
273
+ operator: "not starts with" as const,
274
+ b: "test",
275
+ };
276
+
277
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
278
+ expect(result).toEqual({
279
+ type: "compare",
280
+ col: "users.email",
281
+ op: "not like",
282
+ val: "test%",
283
+ });
284
+ });
285
+
286
+ it("should build ends with operator", () => {
287
+ const condition = {
288
+ type: "compare" as const,
289
+ a: usersTable.columns.email,
290
+ operator: "ends with" as const,
291
+ b: "@example.com",
292
+ };
293
+
294
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
295
+ expect(result).toEqual({
296
+ type: "compare",
297
+ col: "users.email",
298
+ op: "like",
299
+ val: "%@example.com",
300
+ });
301
+ });
302
+
303
+ it("should build not ends with operator", () => {
304
+ const condition = {
305
+ type: "compare" as const,
306
+ a: usersTable.columns.email,
307
+ operator: "not ends with" as const,
308
+ b: "@spam.com",
309
+ };
310
+
311
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
312
+ expect(result).toEqual({
313
+ type: "compare",
314
+ col: "users.email",
315
+ op: "not like",
316
+ val: "%@spam.com",
317
+ });
318
+ });
319
+ });
320
+
321
+ describe("column to column comparison", () => {
322
+ it("should compare two columns", () => {
323
+ const condition = {
324
+ type: "compare" as const,
325
+ a: usersTable.columns.name,
326
+ operator: "=" as const,
327
+ b: usersTable.columns.email,
328
+ };
329
+
330
+ const eb = createMockEB();
331
+ const result = buildWhere(condition, eb, new NodePostgresDriverConfig());
332
+ expect(result).toEqual({
333
+ type: "compare",
334
+ col: "users.name",
335
+ op: "=",
336
+ val: { type: "ref", name: "users.email" },
337
+ });
338
+ });
339
+
340
+ it("should compare columns with string operators", () => {
341
+ const condition = {
342
+ type: "compare" as const,
343
+ a: usersTable.columns.name,
344
+ operator: "contains" as const,
345
+ b: usersTable.columns.email,
346
+ };
347
+
348
+ const eb = createMockEB();
349
+ const result = buildWhere(condition, eb, new NodePostgresDriverConfig());
350
+ // When comparing columns, the value should be wrapped with concat
351
+ expect(result).toHaveProperty("type", "compare");
352
+ expect(result).toHaveProperty("col", "users.name");
353
+ expect(result).toHaveProperty("op", "like");
354
+ });
355
+ });
356
+
357
+ describe("logical operators", () => {
358
+ it("should build AND condition", () => {
359
+ const condition = {
360
+ type: "and" as const,
361
+ items: [
362
+ {
363
+ type: "compare" as const,
364
+ a: usersTable.columns.age,
365
+ operator: ">" as const,
366
+ b: 18,
367
+ },
368
+ {
369
+ type: "compare" as const,
370
+ a: usersTable.columns.isActive,
371
+ operator: "=" as const,
372
+ b: true,
373
+ },
374
+ ],
375
+ };
376
+
377
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
378
+ expect(result).toEqual({
379
+ type: "and",
380
+ conditions: [
381
+ { type: "compare", col: "users.age", op: ">", val: 18 },
382
+ { type: "compare", col: "users.isActive", op: "=", val: true },
383
+ ],
384
+ });
385
+ });
386
+
387
+ it("should build OR condition", () => {
388
+ const condition = {
389
+ type: "or" as const,
390
+ items: [
391
+ {
392
+ type: "compare" as const,
393
+ a: usersTable.columns.name,
394
+ operator: "=" as const,
395
+ b: "John",
396
+ },
397
+ {
398
+ type: "compare" as const,
399
+ a: usersTable.columns.name,
400
+ operator: "=" as const,
401
+ b: "Jane",
402
+ },
403
+ ],
404
+ };
405
+
406
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
407
+ expect(result).toEqual({
408
+ type: "or",
409
+ conditions: [
410
+ { type: "compare", col: "users.name", op: "=", val: "John" },
411
+ { type: "compare", col: "users.name", op: "=", val: "Jane" },
412
+ ],
413
+ });
414
+ });
415
+
416
+ it("should build NOT condition", () => {
417
+ const condition = {
418
+ type: "not" as const,
419
+ item: {
420
+ type: "compare" as const,
421
+ a: usersTable.columns.isActive,
422
+ operator: "=" as const,
423
+ b: false,
424
+ },
425
+ };
426
+
427
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
428
+ expect(result).toEqual({
429
+ type: "not",
430
+ condition: { type: "compare", col: "users.isActive", op: "=", val: false },
431
+ });
432
+ });
433
+
434
+ it("should build nested conditions", () => {
435
+ const condition = {
436
+ type: "and" as const,
437
+ items: [
438
+ {
439
+ type: "compare" as const,
440
+ a: usersTable.columns.isActive,
441
+ operator: "=" as const,
442
+ b: true,
443
+ },
444
+ {
445
+ type: "or" as const,
446
+ items: [
447
+ {
448
+ type: "compare" as const,
449
+ a: usersTable.columns.age,
450
+ operator: ">" as const,
451
+ b: 18,
452
+ },
453
+ {
454
+ type: "compare" as const,
455
+ a: usersTable.columns.age,
456
+ operator: "<" as const,
457
+ b: 65,
458
+ },
459
+ ],
460
+ },
461
+ ],
462
+ };
463
+
464
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
465
+ expect(result).toHaveProperty("type", "and");
466
+ expect(result).toHaveProperty("conditions");
467
+ const conditions = (result as unknown as { conditions: unknown[] }).conditions;
468
+ expect(conditions).toHaveLength(2);
469
+ expect(conditions[0]).toHaveProperty("type", "compare");
470
+ expect(conditions[1]).toHaveProperty("type", "or");
471
+ });
472
+
473
+ it("should build deeply nested conditions", () => {
474
+ const condition = {
475
+ type: "and" as const,
476
+ items: [
477
+ {
478
+ type: "compare" as const,
479
+ a: usersTable.columns.isActive,
480
+ operator: "=" as const,
481
+ b: true,
482
+ },
483
+ {
484
+ type: "or" as const,
485
+ items: [
486
+ {
487
+ type: "and" as const,
488
+ items: [
489
+ {
490
+ type: "compare" as const,
491
+ a: usersTable.columns.age,
492
+ operator: ">=" as const,
493
+ b: 18,
494
+ },
495
+ {
496
+ type: "compare" as const,
497
+ a: usersTable.columns.age,
498
+ operator: "<=" as const,
499
+ b: 30,
500
+ },
501
+ ],
502
+ },
503
+ {
504
+ type: "compare" as const,
505
+ a: usersTable.columns.age,
506
+ operator: ">" as const,
507
+ b: 65,
508
+ },
509
+ ],
510
+ },
511
+ ],
512
+ };
513
+
514
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
515
+ expect(result).toHaveProperty("type", "and");
516
+ expect(result).toHaveProperty("conditions");
517
+ });
518
+ });
519
+
520
+ describe("reference column handling", () => {
521
+ it("should generate subquery for string reference in where clause", () => {
522
+ const condition = {
523
+ type: "compare" as const,
524
+ a: postsTable.columns.userId,
525
+ operator: "=" as const,
526
+ b: "user-external-id-123",
527
+ };
528
+
529
+ const eb = createMockEB();
530
+ const result = buildWhere(
531
+ condition,
532
+ eb,
533
+ new NodePostgresDriverConfig(),
534
+ undefined,
535
+ postsTable,
536
+ );
537
+
538
+ // Should generate a subquery
539
+ expect(result).toHaveProperty("type", "compare");
540
+ expect(result).toHaveProperty("col", "posts.userId");
541
+ expect(result).toHaveProperty("op", "=");
542
+ // The value should be a subquery object
543
+ const val = (result as unknown as { val: unknown }).val as Record<string, unknown>;
544
+ expect(val).toHaveProperty("tableName", "users");
545
+ expect(val).toHaveProperty("_select", "_internalId");
546
+ expect(val).toHaveProperty("_where");
547
+ expect(val["_where"]).toEqual({ col: "id", op: "=", val: "user-external-id-123" });
548
+ expect(val).toHaveProperty("_limit", 1);
549
+ });
550
+
551
+ it("should not generate subquery for bigint reference", () => {
552
+ const condition = {
553
+ type: "compare" as const,
554
+ a: postsTable.columns.userId,
555
+ operator: "=" as const,
556
+ b: 12345n,
557
+ };
558
+
559
+ const result = buildWhere(
560
+ condition,
561
+ createMockEB(),
562
+ new NodePostgresDriverConfig(),
563
+ undefined,
564
+ postsTable,
565
+ );
566
+
567
+ // Should not generate a subquery for bigint
568
+ expect(result).toEqual({
569
+ type: "compare",
570
+ col: "posts.userId",
571
+ op: "=",
572
+ val: 12345n,
573
+ });
574
+ });
575
+
576
+ it("should generate subquery with table name mapper", () => {
577
+ const mapper = {
578
+ toPhysical: (ormName: string) => `prefix_${ormName}`,
579
+ toLogical: (physicalName: string) => physicalName.replace("prefix_", ""),
580
+ };
581
+
582
+ const condition = {
583
+ type: "compare" as const,
584
+ a: postsTable.columns.userId,
585
+ operator: "=" as const,
586
+ b: "user-id-456",
587
+ };
588
+
589
+ const eb = createMockEB();
590
+ const result = buildWhere(
591
+ condition,
592
+ eb,
593
+ new NodePostgresDriverConfig(),
594
+ mapper,
595
+ postsTable,
596
+ );
597
+
598
+ // Should use the mapped table name in subquery
599
+ const val = (result as unknown as { val: Record<string, unknown> }).val;
600
+ expect(val).toHaveProperty("tableName", "prefix_users");
601
+ });
602
+ });
603
+
604
+ describe("database-specific serialization", () => {
605
+ it("should serialize boolean for postgresql", () => {
606
+ const condition = {
607
+ type: "compare" as const,
608
+ a: usersTable.columns.isActive,
609
+ operator: "=" as const,
610
+ b: true,
611
+ };
612
+
613
+ const result = buildWhere(condition, createMockEB(), new NodePostgresDriverConfig());
614
+ expect(result).toHaveProperty("val", true);
615
+ });
616
+
617
+ it("should serialize boolean for sqlite", () => {
618
+ const condition = {
619
+ type: "compare" as const,
620
+ a: usersTable.columns.isActive,
621
+ operator: "=" as const,
622
+ b: false,
623
+ };
624
+
625
+ const result = buildWhere(condition, createMockEB(), new BetterSQLite3DriverConfig());
626
+ // SQLite might serialize booleans differently
627
+ expect(result).toHaveProperty("op", "=");
628
+ });
629
+ });
630
+ });
631
+
632
+ describe("processReferenceSubqueries", () => {
633
+ let kysely: Kysely<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
634
+
635
+ beforeAll(async () => {
636
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Fake Postgres connection information
637
+ kysely = new Kysely({ dialect: new PostgresDialect({} as any) });
638
+ });
639
+
640
+ it("should process single reference subquery", () => {
641
+ const values = {
642
+ title: "My Post",
643
+ content: "Post content",
644
+ userId: new ReferenceSubquery(usersTable, "user-abc-123"),
645
+ };
646
+
647
+ const processed = processReferenceSubqueries(values, kysely);
648
+
649
+ expect(processed["title"]).toBe("My Post");
650
+ expect(processed["content"]).toBe("Post content");
651
+ expect(processed["userId"]).toBeDefined();
652
+ // The userId should now be a Kysely subquery
653
+ expect(processed["userId"]).toHaveProperty("compile");
654
+ });
655
+
656
+ it("should process multiple reference subqueries", () => {
657
+ const values = {
658
+ ref1: new ReferenceSubquery(usersTable, "user-1"),
659
+ ref2: new ReferenceSubquery(usersTable, "user-2"),
660
+ regularValue: "test",
661
+ };
662
+
663
+ const processed = processReferenceSubqueries(values, kysely);
664
+
665
+ expect(processed["ref1"]).toHaveProperty("compile");
666
+ expect(processed["ref2"]).toHaveProperty("compile");
667
+ expect(processed["regularValue"]).toBe("test");
668
+ });
669
+
670
+ it("should not modify non-reference values", () => {
671
+ const values = {
672
+ string: "test",
673
+ number: 42,
674
+ boolean: true,
675
+ null: null,
676
+ undefined: undefined,
677
+ object: { nested: "value" },
678
+ };
679
+
680
+ const processed = processReferenceSubqueries(values, kysely);
681
+
682
+ expect(processed).toEqual(values);
683
+ });
684
+
685
+ it("should use table name mapper when provided", () => {
686
+ const mapper = {
687
+ toPhysical: (ormName: string) => `prefix_${ormName}`,
688
+ toLogical: (physicalName: string) => physicalName.replace("prefix_", ""),
689
+ };
690
+
691
+ const values = {
692
+ userId: new ReferenceSubquery(usersTable, "user-123"),
693
+ };
694
+
695
+ const processed = processReferenceSubqueries(values, kysely, mapper);
696
+
697
+ // Compile the subquery to check it uses the mapped table name
698
+ const subquery = processed["userId"] as unknown as { compile: () => { sql: string } };
699
+ expect(subquery).toHaveProperty("compile");
700
+ const compiled = subquery.compile();
701
+ expect(compiled.sql).toContain("prefix_users");
702
+ });
703
+
704
+ it("should handle empty values object", () => {
705
+ const values = {};
706
+
707
+ const processed = processReferenceSubqueries(values, kysely);
708
+
709
+ expect(processed).toEqual({});
710
+ });
711
+
712
+ it("should generate correct subquery SQL", () => {
713
+ const values = {
714
+ userId: new ReferenceSubquery(usersTable, "external-id-789"),
715
+ };
716
+
717
+ const processed = processReferenceSubqueries(values, kysely);
718
+
719
+ const subquery = processed["userId"] as unknown as {
720
+ compile: () => { sql: string; parameters: unknown[] };
721
+ };
722
+ const compiled = subquery.compile();
723
+
724
+ // Should select _internalId where id = externalId
725
+ expect(compiled.sql).toContain("_internalId");
726
+ expect(compiled.sql).toContain("users");
727
+ expect(compiled.sql).toContain("id");
728
+ expect(compiled.parameters).toContain("external-id-789");
729
+ });
730
+
731
+ it("should respect limit of 1 in generated subquery", () => {
732
+ const values = {
733
+ userId: new ReferenceSubquery(usersTable, "user-id"),
734
+ };
735
+
736
+ const processed = processReferenceSubqueries(values, kysely);
737
+
738
+ const subquery = processed["userId"] as unknown as { compile: () => { sql: string } };
739
+ const compiled = subquery.compile();
740
+
741
+ expect(compiled.sql).toContain("limit");
742
+ });
743
+ });
744
+ });