@fragno-dev/db 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -1,19 +1,17 @@
1
- import { drizzle } from "drizzle-orm/pglite";
1
+ import { PGlite } from "@electric-sql/pglite";
2
+ import { KyselyPGlite } from "kysely-pglite";
2
3
  import { DrizzleAdapter } from "./drizzle-adapter";
3
- import { assert, beforeAll, describe, expect, expectTypeOf, it } from "vitest";
4
+ import { beforeAll, describe, expect, expectTypeOf, it } from "vitest";
4
5
  import { column, idColumn, referenceColumn, schema } from "../../schema/create";
5
- import type { DBType } from "./shared";
6
- import { createRequire } from "node:module";
7
6
  import { Cursor } from "../../query/cursor";
8
- import type { DrizzleCompiledQuery } from "./drizzle-uow-compiler";
9
- import { writeAndLoadSchema } from "./test-utils";
10
-
11
- // Import drizzle-kit for migrations
12
- const require = createRequire(import.meta.url);
13
- const { generateDrizzleJson, generateMigration } =
14
- require("drizzle-kit/api") as typeof import("drizzle-kit/api");
7
+ import { PGLiteDriverConfig } from "../generic-sql/driver-config";
8
+ import type { CompiledQuery } from "../../sql-driver/sql-driver";
9
+ import { internalSchema } from "../../fragments/internal-fragment";
15
10
 
16
11
  describe("DrizzleAdapter PGLite", () => {
12
+ let pgliteDatabase: PGlite;
13
+ let adapter: DrizzleAdapter;
14
+
17
15
  const testSchema = schema((s) => {
18
16
  return s
19
17
  .addTable("users", (t) => {
@@ -75,43 +73,54 @@ describe("DrizzleAdapter PGLite", () => {
75
73
  });
76
74
  });
77
75
 
78
- let adapter: DrizzleAdapter;
79
- let db: DBType;
76
+ const schema2 = schema((s) => {
77
+ return s
78
+ .addTable("products", (t) => {
79
+ return t
80
+ .addColumn("id", idColumn())
81
+ .addColumn("name", column("string"))
82
+ .addColumn("price", column("integer"))
83
+ .createIndex("name_idx", ["name"]);
84
+ })
85
+ .addTable("orders", (t) => {
86
+ return t
87
+ .addColumn("id", idColumn())
88
+ .addColumn("product_id", referenceColumn())
89
+ .addColumn("quantity", column("integer"))
90
+ .addColumn("user_id", referenceColumn())
91
+ .createIndex("orders_user_idx", ["user_id"])
92
+ .createIndex("orders_product_idx", ["product_id"]);
93
+ });
94
+ });
80
95
 
81
96
  beforeAll(async () => {
82
- // Write schema to file and dynamically import it
83
- const { schemaModule, cleanup } = await writeAndLoadSchema(
84
- "drizzle-adapter-pglite",
85
- testSchema,
86
- "postgresql",
87
- "namespace",
88
- );
97
+ pgliteDatabase = new PGlite();
89
98
 
90
- // Create Drizzle instance with PGLite (in-memory Postgres)
91
- db = drizzle({
92
- schema: schemaModule,
93
- }) as unknown as DBType;
99
+ const { dialect } = new KyselyPGlite(pgliteDatabase);
94
100
 
95
- // Generate and run migrations
96
- const migrationStatements = await generateMigration(
97
- generateDrizzleJson({}), // Empty schema (starting state)
98
- generateDrizzleJson(schemaModule), // Target schema
99
- );
101
+ adapter = new DrizzleAdapter({
102
+ dialect,
103
+ driverConfig: new PGLiteDriverConfig(),
104
+ });
100
105
 
101
- // Execute migration SQL
102
- for (const statement of migrationStatements) {
103
- await db.execute(statement);
106
+ // Create settings table first (needed for version tracking)
107
+ {
108
+ const migrations = adapter.prepareMigrations(internalSchema, "");
109
+ await migrations.executeWithDriver(adapter.driver, 0);
104
110
  }
105
111
 
106
- adapter = new DrizzleAdapter({
107
- db: () => db,
108
- provider: "postgresql",
109
- });
112
+ {
113
+ const migrations = adapter.prepareMigrations(testSchema, "namespace");
114
+ await migrations.executeWithDriver(adapter.driver, 0);
115
+ }
110
116
 
111
- expect(await adapter.isConnectionHealthy()).toBe(true);
117
+ {
118
+ const migrations = adapter.prepareMigrations(schema2, "namespace2");
119
+ await migrations.executeWithDriver(adapter.driver, 0);
120
+ }
112
121
 
113
122
  return async () => {
114
- await cleanup();
123
+ await adapter.close();
115
124
  };
116
125
  }, 12000);
117
126
 
@@ -277,7 +286,7 @@ describe("DrizzleAdapter PGLite", () => {
277
286
 
278
287
  it("should support joins", async () => {
279
288
  const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
280
- const queries: DrizzleCompiledQuery[] = [];
289
+ const queries: CompiledQuery[] = [];
281
290
 
282
291
  const createUow = queryEngine.createUnitOfWork("create-users");
283
292
  createUow.create("users", { name: "Email User", age: 20 });
@@ -312,23 +321,23 @@ describe("DrizzleAdapter PGLite", () => {
312
321
 
313
322
  const [query] = queries;
314
323
  expect(query.sql).toMatchInlineSnapshot(
315
- `"select "emails_namespace"."id", "emails_namespace"."user_id", "emails_namespace"."email", "emails_namespace"."is_primary", "emails_namespace"."_internalId", "emails_namespace"."_version", "emails_namespace_user"."data" as "user" from "emails_namespace" "emails_namespace" left join lateral (select json_build_array("emails_namespace_user"."name", "emails_namespace_user"."id", "emails_namespace_user"."age", "emails_namespace_user"."_internalId", "emails_namespace_user"."_version") as "data" from (select * from "users_namespace" "emails_namespace_user" where "emails_namespace_user"."_internalId" = "emails_namespace"."user_id" limit $1) "emails_namespace_user") "emails_namespace_user" on true"`,
324
+ `"select "user"."name" as "user:name", "user"."id" as "user:id", "user"."age" as "user:age", "user"."_internalId" as "user:_internalId", "user"."_version" as "user:_version", "emails_namespace"."id" as "id", "emails_namespace"."user_id" as "user_id", "emails_namespace"."email" as "email", "emails_namespace"."is_primary" as "is_primary", "emails_namespace"."_internalId" as "_internalId", "emails_namespace"."_version" as "_version" from "emails_namespace" left join "users_namespace" as "user" on "emails_namespace"."user_id" = "user"."_internalId""`,
316
325
  );
317
326
 
318
327
  expect(email).toMatchObject({
319
328
  id: expect.objectContaining({
320
329
  externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
321
- internalId: expect.any(Number),
330
+ internalId: expect.any(BigInt),
322
331
  }),
323
332
  user_id: expect.objectContaining({
324
- internalId: expect.any(Number),
333
+ internalId: expect.any(BigInt),
325
334
  }),
326
335
  email: "test@example.com",
327
336
  is_primary: true,
328
337
  user: {
329
338
  id: expect.objectContaining({
330
339
  externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
331
- internalId: expect.any(Number),
340
+ internalId: expect.any(BigInt),
332
341
  }),
333
342
  name: existingUser.name,
334
343
  age: existingUser.age,
@@ -390,7 +399,7 @@ describe("DrizzleAdapter PGLite", () => {
390
399
 
391
400
  it("should support complex nested joins (comments -> post -> author)", async () => {
392
401
  const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
393
- const queries: DrizzleCompiledQuery[] = [];
402
+ const queries: CompiledQuery[] = [];
394
403
 
395
404
  // Create a user (author)
396
405
  const createAuthorUow = queryEngine.createUnitOfWork("create-author");
@@ -463,7 +472,7 @@ describe("DrizzleAdapter PGLite", () => {
463
472
  expect(comment).toMatchObject({
464
473
  id: expect.objectContaining({
465
474
  externalId: expect.stringMatching(/^[a-z0-9]{20,}$/),
466
- internalId: expect.any(Number),
475
+ internalId: expect.any(BigInt),
467
476
  }),
468
477
  text: "Great post!",
469
478
  // Post join (first level)
@@ -493,129 +502,10 @@ describe("DrizzleAdapter PGLite", () => {
493
502
 
494
503
  const [query] = queries;
495
504
  expect(query.sql).toMatchInlineSnapshot(
496
- `"select "comments_namespace"."id", "comments_namespace"."post_id", "comments_namespace"."user_id", "comments_namespace"."text", "comments_namespace"."_internalId", "comments_namespace"."_version", "comments_namespace_post"."data" as "post", "comments_namespace_commenter"."data" as "commenter" from "comments_namespace" "comments_namespace" left join lateral (select json_build_array("comments_namespace_post"."id", "comments_namespace_post"."title", "comments_namespace_post"."content", "comments_namespace_post"."_internalId", "comments_namespace_post"."_version", "comments_namespace_post_author"."data") as "data" from (select * from "posts_namespace" "comments_namespace_post" where "comments_namespace_post"."_internalId" = "comments_namespace"."post_id" order by "comments_namespace_post"."id" desc limit $1) "comments_namespace_post" left join lateral (select json_build_array("comments_namespace_post_author"."id", "comments_namespace_post_author"."name", "comments_namespace_post_author"."age", "comments_namespace_post_author"."_internalId", "comments_namespace_post_author"."_version") as "data" from (select * from "users_namespace" "comments_namespace_post_author" where "comments_namespace_post_author"."_internalId" = "comments_namespace_post"."user_id" order by "comments_namespace_post_author"."name" asc limit $2) "comments_namespace_post_author") "comments_namespace_post_author" on true) "comments_namespace_post" on true left join lateral (select json_build_array("comments_namespace_commenter"."id", "comments_namespace_commenter"."name", "comments_namespace_commenter"."_internalId", "comments_namespace_commenter"."_version") as "data" from (select * from "users_namespace" "comments_namespace_commenter" where "comments_namespace_commenter"."_internalId" = "comments_namespace"."user_id" limit $3) "comments_namespace_commenter") "comments_namespace_commenter" on true"`,
505
+ `"select "post"."id" as "post:id", "post"."title" as "post:title", "post"."content" as "post:content", "post"."_internalId" as "post:_internalId", "post"."_version" as "post:_version", "post_author"."id" as "post:author:id", "post_author"."name" as "post:author:name", "post_author"."age" as "post:author:age", "post_author"."_internalId" as "post:author:_internalId", "post_author"."_version" as "post:author:_version", "commenter"."id" as "commenter:id", "commenter"."name" as "commenter:name", "commenter"."_internalId" as "commenter:_internalId", "commenter"."_version" as "commenter:_version", "comments_namespace"."id" as "id", "comments_namespace"."post_id" as "post_id", "comments_namespace"."user_id" as "user_id", "comments_namespace"."text" as "text", "comments_namespace"."_internalId" as "_internalId", "comments_namespace"."_version" as "_version" from "comments_namespace" left join "posts_namespace" as "post" on "comments_namespace"."post_id" = "post"."_internalId" left join "users_namespace" as "post_author" on "post"."user_id" = "post_author"."_internalId" left join "users_namespace" as "commenter" on "comments_namespace"."user_id" = "commenter"."_internalId""`,
497
506
  );
498
507
  });
499
508
 
500
- it("should support joins with convenience aliases when relations are also aliased", async () => {
501
- // This test demonstrates the solution: include BOTH table aliases AND relations aliases
502
- // in the same schema object. This works around Drizzle's relation resolution bug.
503
- //
504
- // The bug: When Drizzle processes a relational query with `.join()`, it looks up
505
- // tableConfig.relations[relationKey]. If the tableConfig comes from an alias that
506
- // doesn't have matching relations, it returns undefined and crashes.
507
- //
508
- // The fix: For each table alias (e.g., `user`), also add a relations alias
509
- // (e.g., `userRelations`) pointing to the same relations object.
510
-
511
- const authSchema = schema((s) => {
512
- return s
513
- .addTable("user", (t) => {
514
- return t
515
- .addColumn("id", idColumn())
516
- .addColumn("email", column("string"))
517
- .addColumn("passwordHash", column("string"));
518
- })
519
- .addTable("session", (t) => {
520
- return t
521
- .addColumn("id", idColumn())
522
- .addColumn("userId", referenceColumn())
523
- .addColumn("expiresAt", column("timestamp"));
524
- })
525
- .addReference("sessionOwner", {
526
- from: { table: "session", column: "userId" },
527
- to: { table: "user", column: "id" },
528
- type: "one",
529
- });
530
- });
531
-
532
- // Generate schema with BOTH table aliases AND relations aliases
533
- const { schemaModule, cleanup } = await writeAndLoadSchema(
534
- "drizzle-adapter-with-relations-aliases",
535
- authSchema,
536
- "postgresql",
537
- "test-namespace",
538
- );
539
-
540
- // The schema now includes:
541
- // - user_test_namespace + user_test_namespaceRelations (physical)
542
- // - user + userRelations (aliases that point to the same objects)
543
- const schemaWithAliases = {
544
- ...schemaModule.test_namespace_schema,
545
- };
546
-
547
- // Create Drizzle instance
548
- const db = drizzle({
549
- schema: schemaWithAliases,
550
- }) as unknown as DBType;
551
-
552
- // Generate and run migrations
553
- const require = createRequire(import.meta.url);
554
- const { generateDrizzleJson, generateMigration } =
555
- require("drizzle-kit/api") as typeof import("drizzle-kit/api");
556
-
557
- const migrationStatements = await generateMigration(
558
- generateDrizzleJson({}),
559
- generateDrizzleJson(schemaModule),
560
- );
561
-
562
- for (const statement of migrationStatements) {
563
- await db.execute(statement);
564
- }
565
-
566
- const adapter = new DrizzleAdapter({
567
- db: async () => db,
568
- provider: "postgresql",
569
- });
570
-
571
- await adapter.isConnectionHealthy();
572
- const queryEngine = adapter.createQueryEngine(authSchema, "test-namespace");
573
-
574
- // Create a user
575
- const createUserUow = queryEngine.createUnitOfWork("create-user");
576
- createUserUow.create("user", {
577
- email: "test@example.com",
578
- passwordHash: "hash",
579
- });
580
- await createUserUow.executeMutations();
581
-
582
- // Create a session
583
- const [[user]] = await queryEngine.createUnitOfWork("get-user").find("user").executeRetrieve();
584
-
585
- const createSessionUow = queryEngine.createUnitOfWork("create-session");
586
- createSessionUow.create("session", {
587
- userId: user.id,
588
- expiresAt: new Date("2025-12-31"),
589
- });
590
- await createSessionUow.executeMutations();
591
-
592
- // Get session
593
- const [[session]] = await queryEngine
594
- .createUnitOfWork("get-session")
595
- .find("session")
596
- .executeRetrieve();
597
-
598
- // Find session with join - this works now!
599
- // The key is that when Drizzle looks up the session's relations,
600
- // it finds BOTH `sessionOwner` (from session_test_namespaceRelations)
601
- // AND the same relations via `sessionRelations` (the alias)
602
- const [[sessionWithUser]] = await queryEngine
603
- .createUnitOfWork("find-session-with-join")
604
- .find("session", (b) =>
605
- b
606
- .whereIndex("primary", (eb) => eb("id", "=", session.id.valueOf()))
607
- .join((j) => j.sessionOwner((b) => b.select(["id", "email"]))),
608
- )
609
- .executeRetrieve();
610
-
611
- // Verify the join worked
612
- expect(sessionWithUser).toBeDefined();
613
- expect(sessionWithUser.sessionOwner).toBeDefined();
614
- expect(sessionWithUser.sessionOwner?.email).toBe("test@example.com");
615
-
616
- await cleanup();
617
- });
618
-
619
509
  it("should handle timestamps and timezones correctly", async () => {
620
510
  const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
621
511
 
@@ -673,7 +563,7 @@ describe("DrizzleAdapter PGLite", () => {
673
563
 
674
564
  it("should create user and post in same transaction using returned ID", async () => {
675
565
  const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
676
- const queries: DrizzleCompiledQuery[] = [];
566
+ const queries: CompiledQuery[] = [];
677
567
 
678
568
  // Create UOW and create both user and post in same transaction
679
569
  const uow = queryEngine.createUnitOfWork("create-user-and-post", {
@@ -723,15 +613,16 @@ describe("DrizzleAdapter PGLite", () => {
723
613
 
724
614
  const [insertUserQuery, insertPostQuery] = queries;
725
615
  expect(insertUserQuery.sql).toMatchInlineSnapshot(
726
- `"insert into "users_namespace" ("id", "name", "age", "_internalId", "_version") values ($1, $2, $3, default, default)"`,
616
+ `"insert into "users_namespace" ("id", "name", "age") values ($1, $2, $3) returning "users_namespace"."id" as "id", "users_namespace"."name" as "name", "users_namespace"."age" as "age", "users_namespace"."_internalId" as "_internalId", "users_namespace"."_version" as "_version""`,
727
617
  );
728
- expect(insertUserQuery.params).toEqual([userId.externalId, "UOW Test User", 35]);
618
+ expect(insertUserQuery.parameters).toEqual([userId.externalId, "UOW Test User", 35]);
729
619
  expect(insertPostQuery.sql).toMatchInlineSnapshot(
730
- `"insert into "posts_namespace" ("id", "user_id", "title", "content", "created_at", "_internalId", "_version") values ($1, (select "_internalId" from "users_namespace" where "id" = $2 limit 1), $3, $4, default, default, default)"`,
620
+ `"insert into "posts_namespace" ("id", "user_id", "title", "content") values ($1, (select "_internalId" from "users_namespace" where "id" = $2 limit $3), $4, $5) returning "posts_namespace"."id" as "id", "posts_namespace"."user_id" as "user_id", "posts_namespace"."title" as "title", "posts_namespace"."content" as "content", "posts_namespace"."created_at" as "created_at", "posts_namespace"."_internalId" as "_internalId", "posts_namespace"."_version" as "_version""`,
731
621
  );
732
- expect(insertPostQuery.params).toEqual([
622
+ expect(insertPostQuery.parameters).toEqual([
733
623
  postId.externalId,
734
624
  userId.externalId,
625
+ 1,
735
626
  "UOW Test Post",
736
627
  "This post was created in the same transaction as the user",
737
628
  ]);
@@ -740,46 +631,61 @@ describe("DrizzleAdapter PGLite", () => {
740
631
  it("should support cursor-based pagination with findWithCursor()", async () => {
741
632
  const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
742
633
 
743
- // Create multiple users for pagination testing
744
- for (let i = 1; i <= 25; i++) {
634
+ // Create exactly 15 users for precise pagination testing
635
+ const prefix = "CursorPagTest";
636
+
637
+ for (let i = 1; i <= 15; i++) {
745
638
  await queryEngine.create("users", {
746
- name: `Cursor User ${i.toString().padStart(2, "0")}`,
639
+ name: `${prefix} ${i.toString().padStart(2, "0")}`,
747
640
  age: 20 + i,
748
641
  });
749
642
  }
750
643
 
751
- // Fetch first page with cursor
644
+ // Fetch first page with cursor (pageSize=10, total=15 items)
752
645
  const firstPage = await queryEngine.findWithCursor("users", (b) =>
753
- b.whereIndex("name_idx").orderByIndex("name_idx", "asc").pageSize(10),
646
+ b
647
+ .whereIndex("name_idx", (eb) => eb("name", "starts with", prefix))
648
+ .orderByIndex("name_idx", "asc")
649
+ .pageSize(10),
754
650
  );
755
651
 
756
- // Check structure
652
+ // Check structure and hasNextPage
757
653
  expect(firstPage).toHaveProperty("items");
758
654
  expect(firstPage).toHaveProperty("cursor");
655
+ expect(firstPage).toHaveProperty("hasNextPage");
759
656
  expect(Array.isArray(firstPage.items)).toBe(true);
760
- expect(firstPage.items.length).toBeGreaterThan(0);
761
- expect(firstPage.items.length).toBeLessThanOrEqual(10);
762
-
763
- assert(firstPage.cursor instanceof Cursor);
764
657
  expect(firstPage.items).toHaveLength(10);
658
+ expect(firstPage.hasNextPage).toBe(true);
765
659
  expect(firstPage.cursor).toBeInstanceOf(Cursor);
766
660
 
767
- // Fetch second page using cursor
661
+ // Fetch second page using cursor (last page with 5 remaining items)
768
662
  const secondPage = await queryEngine.findWithCursor("users", (b) =>
769
663
  b
770
- .whereIndex("name_idx")
664
+ .whereIndex("name_idx", (eb) => eb("name", "starts with", prefix))
771
665
  .after(firstPage.cursor!)
772
666
  .orderByIndex("name_idx", "asc")
773
667
  .pageSize(10),
774
668
  );
775
669
 
776
- expect(secondPage.items.length).toBeGreaterThan(0);
777
- expect(secondPage.items.length).toBeLessThanOrEqual(10);
670
+ expect(secondPage.items).toHaveLength(5);
671
+ expect(secondPage.hasNextPage).toBe(false);
672
+ expect(secondPage.cursor).toBeUndefined();
778
673
 
779
674
  // Verify no overlap - first item of second page should come after last item of first page
780
675
  const firstPageLastName = firstPage.items[firstPage.items.length - 1].name;
781
676
  const secondPageFirstName = secondPage.items[0].name;
782
677
  expect(secondPageFirstName > firstPageLastName).toBe(true);
678
+
679
+ // Test empty results
680
+ const emptyPage = await queryEngine.findWithCursor("users", (b) =>
681
+ b
682
+ .whereIndex("name_idx", (eb) => eb("name", "starts with", "NonExistentPrefix"))
683
+ .orderByIndex("name_idx", "asc")
684
+ .pageSize(10),
685
+ );
686
+ expect(emptyPage.items).toHaveLength(0);
687
+ expect(emptyPage.hasNextPage).toBe(false);
688
+ expect(emptyPage.cursor).toBeUndefined();
783
689
  });
784
690
 
785
691
  it("should support findWithCursor() in Unit of Work", async () => {
@@ -794,11 +700,60 @@ describe("DrizzleAdapter PGLite", () => {
794
700
 
795
701
  const [result] = await uow.executeRetrieve();
796
702
 
797
- // Verify result structure
703
+ // Verify result structure including hasNextPage
798
704
  expect(result).toHaveProperty("items");
799
705
  expect(result).toHaveProperty("cursor");
706
+ expect(result).toHaveProperty("hasNextPage");
800
707
  expect(Array.isArray(result.items)).toBe(true);
801
708
  expect(result.items).toHaveLength(5);
709
+ expect(typeof result.hasNextPage).toBe("boolean");
802
710
  expect(result.cursor).toBeInstanceOf(Cursor);
803
711
  });
712
+
713
+ it("should fail check() when version changes", async () => {
714
+ const queryEngine = adapter.createQueryEngine(testSchema, "namespace");
715
+
716
+ // Create a user
717
+ const createUserUow = queryEngine.createUnitOfWork("create-user-for-version-conflict");
718
+ createUserUow.create("users", {
719
+ name: "Version Conflict User",
720
+ age: 40,
721
+ });
722
+ await createUserUow.executeMutations();
723
+
724
+ // Get the user
725
+ const [[user]] = await queryEngine
726
+ .createUnitOfWork("get-user-for-version-conflict")
727
+ .find("users", (b) =>
728
+ b.whereIndex("name_idx", (eb) => eb("name", "=", "Version Conflict User")),
729
+ )
730
+ .executeRetrieve();
731
+
732
+ // Update the user to increment their version
733
+ const updateUow = queryEngine.createUnitOfWork("update-user-version");
734
+ updateUow.update("users", user.id, (b) => b.set({ age: 41 }));
735
+ await updateUow.executeMutations();
736
+
737
+ // Try to check with the old version (should fail)
738
+ const uow = queryEngine.createUnitOfWork("check-stale-version");
739
+ uow.check("users", user.id); // This has version 0, but the user now has version 1
740
+ uow.create("posts", {
741
+ user_id: user.id,
742
+ title: "Should Not Be Created",
743
+ content: "Content",
744
+ created_at: new Date(),
745
+ });
746
+
747
+ const { success } = await uow.executeMutations();
748
+ expect(success).toBe(false);
749
+
750
+ // Verify the post was NOT created
751
+ const [posts] = await queryEngine
752
+ .createUnitOfWork("get-posts-for-version-conflict")
753
+ .find("posts", (b) => b.whereIndex("posts_user_idx", (eb) => eb("user_id", "=", user.id)))
754
+ .executeRetrieve();
755
+
756
+ const conflictPosts = posts.filter((p) => p.title === "Should Not Be Created");
757
+ expect(conflictPosts).toHaveLength(0);
758
+ });
804
759
  });