@fragno-dev/db 0.2.1 → 0.3.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 (362) hide show
  1. package/.turbo/turbo-build.log +206 -140
  2. package/CHANGELOG.md +67 -0
  3. package/README.md +30 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  19. package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  21. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  31. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +38 -28
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  41. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  42. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  43. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  44. package/dist/adapters/generic-sql/uow-decoder.js +7 -3
  45. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  46. package/dist/adapters/generic-sql/uow-encoder.js +28 -8
  47. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  48. package/dist/adapters/in-memory/condition-evaluator.js +131 -0
  49. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  50. package/dist/adapters/in-memory/errors.d.ts +13 -0
  51. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  52. package/dist/adapters/in-memory/errors.js +23 -0
  53. package/dist/adapters/in-memory/errors.js.map +1 -0
  54. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  55. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  56. package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
  57. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  58. package/dist/adapters/in-memory/in-memory-uow.js +648 -0
  59. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  60. package/dist/adapters/in-memory/index.d.ts +4 -0
  61. package/dist/adapters/in-memory/index.js +4 -0
  62. package/dist/adapters/in-memory/options.d.ts +28 -0
  63. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  64. package/dist/adapters/in-memory/options.js +61 -0
  65. package/dist/adapters/in-memory/options.js.map +1 -0
  66. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  67. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  68. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  69. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  70. package/dist/adapters/in-memory/store.js +71 -0
  71. package/dist/adapters/in-memory/store.js.map +1 -0
  72. package/dist/adapters/in-memory/value-comparison.js +28 -0
  73. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  74. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  75. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  76. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  77. package/dist/adapters/sql/index.d.ts +5 -0
  78. package/dist/adapters/sql/index.js +4 -0
  79. package/dist/db-fragment-definition-builder.d.ts +45 -96
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +121 -99
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
  84. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  85. package/dist/dispatchers/cloudflare-do/index.js +63 -0
  86. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  87. package/dist/dispatchers/node/index.d.ts +17 -0
  88. package/dist/dispatchers/node/index.d.ts.map +1 -0
  89. package/dist/dispatchers/node/index.js +59 -0
  90. package/dist/dispatchers/node/index.js.map +1 -0
  91. package/dist/fragments/internal-fragment.d.ts +172 -9
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +193 -74
  94. package/dist/fragments/internal-fragment.js.map +1 -1
  95. package/dist/fragments/internal-fragment.routes.js +29 -0
  96. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  97. package/dist/fragments/internal-fragment.schema.d.ts +9 -0
  98. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  99. package/dist/fragments/internal-fragment.schema.js +22 -0
  100. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  101. package/dist/hooks/durable-hooks-processor.d.ts +14 -0
  102. package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
  103. package/dist/hooks/durable-hooks-processor.js +32 -0
  104. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  105. package/dist/hooks/hooks.d.ts +47 -4
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +106 -39
  108. package/dist/hooks/hooks.js.map +1 -1
  109. package/dist/migration-engine/auto-from-schema.js +14 -11
  110. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  111. package/dist/migration-engine/generation-engine.d.ts +16 -10
  112. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  113. package/dist/migration-engine/generation-engine.js +72 -33
  114. package/dist/migration-engine/generation-engine.js.map +1 -1
  115. package/dist/migration-engine/shared.js.map +1 -1
  116. package/dist/mod.d.ts +17 -10
  117. package/dist/mod.d.ts.map +1 -1
  118. package/dist/mod.js +14 -8
  119. package/dist/mod.js.map +1 -1
  120. package/dist/naming/sql-naming.d.ts +19 -0
  121. package/dist/naming/sql-naming.d.ts.map +1 -0
  122. package/dist/naming/sql-naming.js +116 -0
  123. package/dist/naming/sql-naming.js.map +1 -0
  124. package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
  125. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
  126. package/dist/outbox/outbox-builder.js +156 -0
  127. package/dist/outbox/outbox-builder.js.map +1 -0
  128. package/dist/outbox/outbox.d.ts +52 -0
  129. package/dist/outbox/outbox.d.ts.map +1 -0
  130. package/dist/outbox/outbox.js +37 -0
  131. package/dist/outbox/outbox.js.map +1 -0
  132. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
  133. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
  134. package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
  135. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  136. package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
  137. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
  138. package/dist/packages/fragno/dist/api/route.js +14 -1
  139. package/dist/packages/fragno/dist/api/route.js.map +1 -1
  140. package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
  141. package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
  142. package/dist/query/column-defaults.js +20 -4
  143. package/dist/query/column-defaults.js.map +1 -1
  144. package/dist/query/cursor.d.ts +3 -1
  145. package/dist/query/cursor.d.ts.map +1 -1
  146. package/dist/query/cursor.js +45 -14
  147. package/dist/query/cursor.js.map +1 -1
  148. package/dist/query/db-now.d.ts +8 -0
  149. package/dist/query/db-now.d.ts.map +1 -0
  150. package/dist/query/db-now.js +7 -0
  151. package/dist/query/db-now.js.map +1 -0
  152. package/dist/query/serialize/create-sql-serializer.js +3 -2
  153. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  154. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  155. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  156. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  157. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  158. package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
  159. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  160. package/dist/query/serialize/sql-serializer.js +2 -2
  161. package/dist/query/serialize/sql-serializer.js.map +1 -1
  162. package/dist/query/simple-query-interface.d.ts +6 -1
  163. package/dist/query/simple-query-interface.d.ts.map +1 -1
  164. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +351 -100
  165. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  166. package/dist/query/unit-of-work/execute-unit-of-work.js +440 -267
  167. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  168. package/dist/query/unit-of-work/unit-of-work.d.ts +67 -22
  169. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  170. package/dist/query/unit-of-work/unit-of-work.js +110 -13
  171. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  172. package/dist/query/value-decoding.js +8 -5
  173. package/dist/query/value-decoding.js.map +1 -1
  174. package/dist/query/value-encoding.js +29 -9
  175. package/dist/query/value-encoding.js.map +1 -1
  176. package/dist/schema/create.d.ts +40 -14
  177. package/dist/schema/create.d.ts.map +1 -1
  178. package/dist/schema/create.js +82 -42
  179. package/dist/schema/create.js.map +1 -1
  180. package/dist/schema/generate-id.d.ts +20 -0
  181. package/dist/schema/generate-id.d.ts.map +1 -0
  182. package/dist/schema/generate-id.js +28 -0
  183. package/dist/schema/generate-id.js.map +1 -0
  184. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  185. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  186. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  187. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  188. package/dist/schema/validator.d.ts +10 -0
  189. package/dist/schema/validator.d.ts.map +1 -0
  190. package/dist/schema/validator.js +123 -0
  191. package/dist/schema/validator.js.map +1 -0
  192. package/dist/schema-output/drizzle.d.ts +30 -0
  193. package/dist/schema-output/drizzle.d.ts.map +1 -0
  194. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  195. package/dist/schema-output/drizzle.js.map +1 -0
  196. package/dist/schema-output/prisma.d.ts +17 -0
  197. package/dist/schema-output/prisma.d.ts.map +1 -0
  198. package/dist/schema-output/prisma.js +296 -0
  199. package/dist/schema-output/prisma.js.map +1 -0
  200. package/dist/util/default-database-adapter.js +61 -0
  201. package/dist/util/default-database-adapter.js.map +1 -0
  202. package/dist/with-database.d.ts +1 -1
  203. package/dist/with-database.d.ts.map +1 -1
  204. package/dist/with-database.js +12 -3
  205. package/dist/with-database.js.map +1 -1
  206. package/package.json +43 -28
  207. package/src/adapters/adapters.ts +30 -24
  208. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  209. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  210. package/src/adapters/drizzle/test-utils.ts +12 -8
  211. package/src/adapters/generic-sql/driver-config.ts +38 -0
  212. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  213. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  214. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  215. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  216. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  217. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  218. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  219. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  220. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  221. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  222. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  223. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  224. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  225. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  226. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  227. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  228. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  229. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  230. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  231. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  232. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  233. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  234. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  235. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  236. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  237. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  238. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  239. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  240. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +49 -35
  241. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +48 -32
  242. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  243. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  244. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  245. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  246. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  247. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  248. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  249. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  250. package/src/adapters/in-memory/errors.ts +20 -0
  251. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  252. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  253. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  254. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  255. package/src/adapters/in-memory/index.ts +3 -0
  256. package/src/adapters/in-memory/options.test.ts +41 -0
  257. package/src/adapters/in-memory/options.ts +87 -0
  258. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  259. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  260. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  261. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  262. package/src/adapters/in-memory/store.test.ts +68 -0
  263. package/src/adapters/in-memory/store.ts +145 -0
  264. package/src/adapters/in-memory/value-comparison.ts +53 -0
  265. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  266. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  267. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  268. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  269. package/src/adapters/sql/index.ts +12 -0
  270. package/src/db-fragment-definition-builder.test.ts +88 -54
  271. package/src/db-fragment-definition-builder.ts +201 -322
  272. package/src/db-fragment-instantiator.test.ts +169 -101
  273. package/src/db-fragment-integration.test.ts +301 -149
  274. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  275. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  276. package/src/dispatchers/node/index.test.ts +91 -0
  277. package/src/dispatchers/node/index.ts +87 -0
  278. package/src/fragments/internal-fragment.routes.ts +42 -0
  279. package/src/fragments/internal-fragment.schema.ts +51 -0
  280. package/src/fragments/internal-fragment.test.ts +730 -274
  281. package/src/fragments/internal-fragment.ts +447 -154
  282. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  283. package/src/hooks/durable-hooks-processor.ts +67 -0
  284. package/src/hooks/hooks.test.ts +411 -259
  285. package/src/hooks/hooks.ts +265 -66
  286. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  287. package/src/migration-engine/auto-from-schema.ts +5 -2
  288. package/src/migration-engine/create.test.ts +2 -2
  289. package/src/migration-engine/generation-engine.test.ts +229 -104
  290. package/src/migration-engine/generation-engine.ts +94 -64
  291. package/src/migration-engine/shared.ts +1 -0
  292. package/src/mod.ts +78 -30
  293. package/src/naming/sql-naming.ts +180 -0
  294. package/src/outbox/outbox-builder.ts +241 -0
  295. package/src/outbox/outbox.test.ts +253 -0
  296. package/src/outbox/outbox.ts +137 -0
  297. package/src/query/column-defaults.ts +41 -3
  298. package/src/query/condition-builder.test.ts +3 -3
  299. package/src/query/cursor.test.ts +116 -18
  300. package/src/query/cursor.ts +75 -26
  301. package/src/query/db-now.ts +6 -0
  302. package/src/query/query-type.test.ts +2 -2
  303. package/src/query/serialize/create-sql-serializer.ts +7 -2
  304. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  305. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  306. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  307. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  308. package/src/query/serialize/sql-serializer.ts +4 -4
  309. package/src/query/simple-query-interface.ts +5 -0
  310. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1512 -1458
  311. package/src/query/unit-of-work/execute-unit-of-work.ts +1708 -596
  312. package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
  313. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +32 -32
  314. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  315. package/src/query/unit-of-work/unit-of-work.test.ts +231 -36
  316. package/src/query/unit-of-work/unit-of-work.ts +229 -31
  317. package/src/query/value-decoding.test.ts +13 -2
  318. package/src/query/value-decoding.ts +17 -4
  319. package/src/query/value-encoding.test.ts +85 -2
  320. package/src/query/value-encoding.ts +56 -6
  321. package/src/schema/create.test.ts +129 -42
  322. package/src/schema/create.ts +187 -47
  323. package/src/schema/generate-id.test.ts +57 -0
  324. package/src/schema/generate-id.ts +38 -0
  325. package/src/schema/serialize.test.ts +14 -2
  326. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  327. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  328. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  329. package/src/schema/validator.test.ts +197 -0
  330. package/src/schema/validator.ts +231 -0
  331. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  332. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  333. package/src/schema-output/prisma.test.ts +536 -0
  334. package/src/schema-output/prisma.ts +573 -0
  335. package/src/util/default-database-adapter.ts +106 -0
  336. package/src/with-database.ts +22 -3
  337. package/tsdown.config.ts +6 -4
  338. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  339. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  341. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  342. package/dist/adapters/drizzle/generate.d.ts +0 -30
  343. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  344. package/dist/adapters/drizzle/generate.js.map +0 -1
  345. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  346. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  347. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  348. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  349. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  350. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  351. package/dist/adapters/shared/table-name-mapper.js +0 -43
  352. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  353. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  354. package/dist/schema-generator/schema-generator.d.ts +0 -15
  355. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  356. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  357. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  358. package/src/adapters/shared/table-name-mapper.ts +0 -50
  359. package/src/schema-generator/schema-generator.ts +0 -12
  360. package/src/shared/config.ts +0 -10
  361. package/src/shared/connection-pool.ts +0 -24
  362. package/src/shared/prisma.ts +0 -45
@@ -12,9 +12,10 @@ import type {
12
12
  ColumnOperation,
13
13
  MigrationOperation,
14
14
  } from "../../../migration-engine/shared";
15
- import { SETTINGS_TABLE_NAME } from "../../../fragments/internal-fragment";
16
- import type { TableNameMapper } from "../../shared/table-name-mapper";
17
- import type { SupportedDatabase } from "../driver-config";
15
+ import { SETTINGS_TABLE_NAME } from "../../../fragments/internal-fragment.schema";
16
+ import type { NamingResolver } from "../../../naming/sql-naming";
17
+ import type { DriverConfig, SupportedDatabase } from "../driver-config";
18
+ import type { SQLiteStorageMode } from "../sqlite-storage";
18
19
  import { createSQLTypeMapper } from "../../../schema/type-conversion/create-sql-type-mapper";
19
20
 
20
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -38,11 +39,18 @@ export abstract class SQLGenerator {
38
39
  protected readonly db: KyselyAny;
39
40
  protected readonly database: SupportedDatabase;
40
41
  protected readonly typeMapper: ReturnType<typeof createSQLTypeMapper>;
41
-
42
- constructor(db: KyselyAny, database: SupportedDatabase) {
42
+ protected readonly driverConfig?: DriverConfig;
43
+
44
+ constructor(
45
+ db: KyselyAny,
46
+ database: SupportedDatabase,
47
+ driverConfig?: DriverConfig,
48
+ sqliteStorageMode?: SQLiteStorageMode,
49
+ ) {
43
50
  this.db = db;
44
51
  this.database = database;
45
- this.typeMapper = createSQLTypeMapper(database);
52
+ this.typeMapper = createSQLTypeMapper(database, sqliteStorageMode);
53
+ this.driverConfig = driverConfig;
46
54
  }
47
55
 
48
56
  /**
@@ -102,12 +110,17 @@ export abstract class SQLGenerator {
102
110
  * Compile migration operations to SQL statements.
103
111
  * This is the main entry point for SQL generation.
104
112
  */
105
- compile(operations: MigrationOperation[], mapper?: TableNameMapper): CompiledQuery[] {
113
+ compile(operations: MigrationOperation[], resolver?: NamingResolver): CompiledQuery[] {
106
114
  const preprocessed = this.preprocess(operations);
107
115
  const queries: CompiledQuery[] = [];
108
116
 
117
+ const schemaName = resolver?.getSchemaName();
118
+ if (schemaName && this.database === "postgresql") {
119
+ queries.push(sql`CREATE SCHEMA IF NOT EXISTS ${sql.id(schemaName)}`.compile(this.db));
120
+ }
121
+
109
122
  for (const operation of preprocessed) {
110
- const compiled = this.compileOperation(operation, mapper);
123
+ const compiled = this.compileOperation(operation, resolver);
111
124
  if (Array.isArray(compiled)) {
112
125
  queries.push(...compiled);
113
126
  } else {
@@ -123,25 +136,25 @@ export abstract class SQLGenerator {
123
136
  */
124
137
  protected compileOperation(
125
138
  operation: MigrationOperation,
126
- mapper?: TableNameMapper,
139
+ resolver?: NamingResolver,
127
140
  ): CompiledQuery | CompiledQuery[] {
128
141
  switch (operation.type) {
129
142
  case "create-table":
130
- return this.compileCreateTable(operation, mapper);
143
+ return this.compileCreateTable(operation, resolver);
131
144
  case "rename-table":
132
- return this.compileRenameTable(operation, mapper);
145
+ return this.compileRenameTable(operation, resolver);
133
146
  case "alter-table":
134
- return this.compileAlterTable(operation, mapper);
147
+ return this.compileAlterTable(operation, resolver);
135
148
  case "drop-table":
136
- return this.compileDropTable(operation, mapper);
149
+ return this.compileDropTable(operation, resolver);
137
150
  case "add-foreign-key":
138
- return this.compileAddForeignKey(operation, mapper);
151
+ return this.compileAddForeignKey(operation, resolver);
139
152
  case "drop-foreign-key":
140
- return this.compileDropForeignKey(operation, mapper);
153
+ return this.compileDropForeignKey(operation, resolver);
141
154
  case "add-index":
142
- return this.compileAddIndex(operation, mapper);
155
+ return this.compileAddIndex(operation, resolver);
143
156
  case "drop-index":
144
- return this.compileDropIndex(operation, mapper);
157
+ return this.compileDropIndex(operation, resolver);
145
158
  case "custom":
146
159
  return this.compileCustom(operation);
147
160
  }
@@ -153,19 +166,20 @@ export abstract class SQLGenerator {
153
166
  */
154
167
  protected compileCreateTable(
155
168
  operation: Extract<MigrationOperation, { type: "create-table" }>,
156
- mapper?: TableNameMapper,
169
+ resolver?: NamingResolver,
157
170
  ): CompiledQuery {
158
- const tableName = this.getTableName(operation.name, mapper);
159
- let builder: CreateTableBuilderAny = this.db.schema.createTable(tableName);
171
+ const tableName = this.getTableName(operation.name, resolver);
172
+ let builder: CreateTableBuilderAny = this.getSchemaBuilder(resolver).createTable(tableName);
160
173
 
161
174
  for (const col of operation.columns) {
162
- builder = builder.addColumn(col.name, sql.raw(this.getDBType(col)), (b) =>
175
+ const columnName = this.getColumnName(col.name, operation.name, resolver);
176
+ builder = builder.addColumn(columnName, sql.raw(this.getDBType(col)), (b) =>
163
177
  this.buildColumn(col, b),
164
178
  );
165
179
  }
166
180
 
167
181
  // Allow subclasses to add inline foreign keys
168
- builder = this.addInlineForeignKeys(builder, operation, mapper);
182
+ builder = this.addInlineForeignKeys(builder, operation, resolver);
169
183
 
170
184
  return builder.compile();
171
185
  }
@@ -177,7 +191,7 @@ export abstract class SQLGenerator {
177
191
  protected addInlineForeignKeys(
178
192
  builder: CreateTableBuilderAny,
179
193
  _operation: Extract<MigrationOperation, { type: "create-table" }>,
180
- _mapper?: TableNameMapper,
194
+ _resolver?: NamingResolver,
181
195
  ): CreateTableBuilderAny {
182
196
  return builder;
183
197
  }
@@ -187,11 +201,11 @@ export abstract class SQLGenerator {
187
201
  */
188
202
  protected compileRenameTable(
189
203
  operation: Extract<MigrationOperation, { type: "rename-table" }>,
190
- mapper?: TableNameMapper,
204
+ resolver?: NamingResolver,
191
205
  ): CompiledQuery {
192
- return this.db.schema
193
- .alterTable(this.getTableName(operation.from, mapper))
194
- .renameTo(this.getTableName(operation.to, mapper))
206
+ return this.getSchemaBuilder(resolver)
207
+ .alterTable(this.getTableName(operation.from, resolver))
208
+ .renameTo(this.getTableName(operation.to, resolver))
195
209
  .compile();
196
210
  }
197
211
 
@@ -200,13 +214,13 @@ export abstract class SQLGenerator {
200
214
  */
201
215
  protected compileAlterTable(
202
216
  operation: Extract<MigrationOperation, { type: "alter-table" }>,
203
- mapper?: TableNameMapper,
217
+ resolver?: NamingResolver,
204
218
  ): CompiledQuery[] {
205
219
  const queries: CompiledQuery[] = [];
206
- const tableName = this.getTableName(operation.name, mapper);
220
+ const tableName = this.getTableName(operation.name, resolver);
207
221
 
208
222
  for (const columnOp of operation.value) {
209
- const compiled = this.compileColumnOperation(tableName, columnOp);
223
+ const compiled = this.compileColumnOperation(tableName, operation.name, columnOp, resolver);
210
224
  if (Array.isArray(compiled)) {
211
225
  queries.push(...compiled);
212
226
  } else {
@@ -223,26 +237,39 @@ export abstract class SQLGenerator {
223
237
  */
224
238
  protected compileColumnOperation(
225
239
  tableName: string,
240
+ logicalTableName: string,
226
241
  operation: ColumnOperation,
242
+ resolver?: NamingResolver,
227
243
  ): CompiledQuery | CompiledQuery[] {
228
- const alter = () => this.db.schema.alterTable(tableName);
244
+ const alter = () => this.getSchemaBuilder(resolver).alterTable(tableName);
229
245
 
230
246
  switch (operation.type) {
231
247
  case "rename-column":
232
- return alter().renameColumn(operation.from, operation.to).compile();
248
+ return alter()
249
+ .renameColumn(
250
+ this.getColumnName(operation.from, logicalTableName, resolver),
251
+ this.getColumnName(operation.to, logicalTableName, resolver),
252
+ )
253
+ .compile();
233
254
 
234
255
  case "drop-column":
235
- return alter().dropColumn(operation.name).compile();
256
+ return alter()
257
+ .dropColumn(this.getColumnName(operation.name, logicalTableName, resolver))
258
+ .compile();
236
259
 
237
260
  case "create-column": {
238
261
  const col = operation.value;
239
262
  return alter()
240
- .addColumn(col.name, sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b))
263
+ .addColumn(
264
+ this.getColumnName(col.name, logicalTableName, resolver),
265
+ sql.raw(this.getDBType(col)),
266
+ (b) => this.buildColumn(col, b),
267
+ )
241
268
  .compile();
242
269
  }
243
270
 
244
271
  case "update-column":
245
- return this.compileUpdateColumn(tableName, operation);
272
+ return this.compileUpdateColumn(tableName, logicalTableName, operation, resolver);
246
273
  }
247
274
  }
248
275
 
@@ -252,7 +279,9 @@ export abstract class SQLGenerator {
252
279
  */
253
280
  protected abstract compileUpdateColumn(
254
281
  tableName: string,
282
+ logicalTableName: string,
255
283
  operation: Extract<ColumnOperation, { type: "update-column" }>,
284
+ resolver?: NamingResolver,
256
285
  ): CompiledQuery | CompiledQuery[];
257
286
 
258
287
  /**
@@ -260,9 +289,11 @@ export abstract class SQLGenerator {
260
289
  */
261
290
  protected compileDropTable(
262
291
  operation: Extract<MigrationOperation, { type: "drop-table" }>,
263
- mapper?: TableNameMapper,
292
+ resolver?: NamingResolver,
264
293
  ): CompiledQuery {
265
- return this.db.schema.dropTable(this.getTableName(operation.name, mapper)).compile();
294
+ return this.getSchemaBuilder(resolver)
295
+ .dropTable(this.getTableName(operation.name, resolver))
296
+ .compile();
266
297
  }
267
298
 
268
299
  /**
@@ -271,16 +302,18 @@ export abstract class SQLGenerator {
271
302
  */
272
303
  protected compileAddForeignKey(
273
304
  operation: Extract<MigrationOperation, { type: "add-foreign-key" }>,
274
- mapper?: TableNameMapper,
305
+ resolver?: NamingResolver,
275
306
  ): CompiledQuery {
276
307
  const { table, value } = operation;
277
- return this.db.schema
278
- .alterTable(this.getTableName(table, mapper))
308
+ return this.getSchemaBuilder(resolver)
309
+ .alterTable(this.getTableName(table, resolver))
279
310
  .addForeignKeyConstraint(
280
- value.name,
281
- value.columns,
282
- this.getTableName(value.referencedTable, mapper),
283
- value.referencedColumns,
311
+ this.getForeignKeyName(value.name, table, value.referencedTable, resolver),
312
+ value.columns.map((columnName) => this.getColumnName(columnName, table, resolver)),
313
+ this.getTableName(value.referencedTable, resolver),
314
+ value.referencedColumns.map((columnName) =>
315
+ this.getColumnName(columnName, value.referencedTable, resolver),
316
+ ),
284
317
  (b) => b.onUpdate("restrict").onDelete("restrict"),
285
318
  )
286
319
  .compile();
@@ -292,12 +325,12 @@ export abstract class SQLGenerator {
292
325
  */
293
326
  protected compileDropForeignKey(
294
327
  operation: Extract<MigrationOperation, { type: "drop-foreign-key" }>,
295
- mapper?: TableNameMapper,
328
+ resolver?: NamingResolver,
296
329
  ): CompiledQuery {
297
- const { table, name } = operation;
298
- return this.db.schema
299
- .alterTable(this.getTableName(table, mapper))
300
- .dropConstraint(name)
330
+ const { table, name, referencedTable } = operation;
331
+ return this.getSchemaBuilder(resolver)
332
+ .alterTable(this.getTableName(table, resolver))
333
+ .dropConstraint(this.getForeignKeyName(name, table, referencedTable, resolver))
301
334
  .ifExists()
302
335
  .compile();
303
336
  }
@@ -307,11 +340,22 @@ export abstract class SQLGenerator {
307
340
  */
308
341
  protected compileAddIndex(
309
342
  operation: Extract<MigrationOperation, { type: "add-index" }>,
310
- mapper?: TableNameMapper,
343
+ resolver?: NamingResolver,
311
344
  ): CompiledQuery {
312
- const tableName = this.getTableName(operation.table, mapper);
313
- const indexName = this.getIndexName(operation.name, operation.table, mapper);
314
- let builder = this.db.schema.createIndex(indexName).on(tableName).columns(operation.columns);
345
+ const tableName = this.getTableName(operation.table, resolver);
346
+ const indexName = this.getIndexName(
347
+ operation.name,
348
+ operation.table,
349
+ resolver,
350
+ operation.unique,
351
+ );
352
+ const columnNames = operation.columns.map((columnName) =>
353
+ this.getColumnName(columnName, operation.table, resolver),
354
+ );
355
+ let builder = this.getSchemaBuilder(resolver)
356
+ .createIndex(indexName)
357
+ .on(tableName)
358
+ .columns(columnNames);
315
359
 
316
360
  if (operation.unique) {
317
361
  builder = builder.unique();
@@ -325,11 +369,11 @@ export abstract class SQLGenerator {
325
369
  */
326
370
  protected compileDropIndex(
327
371
  operation: Extract<MigrationOperation, { type: "drop-index" }>,
328
- mapper?: TableNameMapper,
372
+ resolver?: NamingResolver,
329
373
  ): CompiledQuery {
330
- const tableName = this.getTableName(operation.table, mapper);
331
- const indexName = this.getIndexName(operation.name, operation.table, mapper);
332
- return this.db.schema.dropIndex(indexName).ifExists().on(tableName).compile();
374
+ const tableName = this.getTableName(operation.table, resolver);
375
+ const indexName = this.getIndexName(operation.name, operation.table, resolver);
376
+ return this.getSchemaBuilder(resolver).dropIndex(indexName).ifExists().on(tableName).compile();
333
377
  }
334
378
 
335
379
  /**
@@ -375,11 +419,11 @@ export abstract class SQLGenerator {
375
419
  * Get table name, applying namespace mapping if provided.
376
420
  * Settings table is never namespaced.
377
421
  */
378
- protected getTableName(tableName: string, mapper?: TableNameMapper): string {
422
+ protected getTableName(tableName: string, resolver?: NamingResolver): string {
379
423
  if (tableName === SETTINGS_TABLE_NAME) {
380
424
  return tableName;
381
425
  }
382
- return mapper ? mapper.toPhysical(tableName) : tableName;
426
+ return resolver ? resolver.getTableName(tableName) : tableName;
383
427
  }
384
428
 
385
429
  /**
@@ -387,14 +431,47 @@ export abstract class SQLGenerator {
387
431
  * Index names must be globally unique in most databases, so we namespace them
388
432
  * to avoid collisions when multiple fragments use the same logical index names.
389
433
  */
390
- protected getIndexName(indexName: string, tableName: string, mapper?: TableNameMapper): string {
391
- if (!mapper) {
434
+ protected getIndexName(
435
+ indexName: string,
436
+ tableName: string,
437
+ resolver?: NamingResolver,
438
+ unique?: boolean,
439
+ ): string {
440
+ if (!resolver) {
392
441
  return indexName;
393
442
  }
394
- // Create a unique index name by including the physical table name
395
- // This ensures index names are unique across namespaces
396
- const physicalTable = mapper.toPhysical(tableName);
397
- return `${indexName}_${physicalTable}`;
443
+ return unique
444
+ ? resolver.getUniqueIndexName(indexName, tableName)
445
+ : resolver.getIndexName(indexName, tableName);
446
+ }
447
+
448
+ protected getForeignKeyName(
449
+ name: string,
450
+ tableName: string,
451
+ referencedTable: string,
452
+ resolver?: NamingResolver,
453
+ ): string {
454
+ if (!resolver) {
455
+ return name;
456
+ }
457
+ return resolver.getForeignKeyName({
458
+ logicalTable: tableName,
459
+ logicalReferencedTable: referencedTable || tableName,
460
+ referenceName: name,
461
+ });
462
+ }
463
+
464
+ protected getColumnName(
465
+ columnName: string,
466
+ tableName: string,
467
+ resolver?: NamingResolver,
468
+ ): string {
469
+ return resolver ? resolver.getColumnName(tableName, columnName) : columnName;
470
+ }
471
+
472
+ protected getSchemaBuilder(resolver?: NamingResolver) {
473
+ const schemaName = resolver?.getSchemaName();
474
+ return schemaName ? this.db.schema.withSchema(schemaName) : this.db.schema;
398
475
  }
399
476
 
400
477
  /**
@@ -1,5 +1,6 @@
1
1
  import type { DriverConfig } from "../driver-config";
2
- import type { TableNameMapper } from "../../shared/table-name-mapper";
2
+ import type { NamingResolver } from "../../../naming/sql-naming";
3
+ import type { SQLiteStorageMode } from "../sqlite-storage";
3
4
  import { SQLQueryCompiler, type AnyKysely } from "./sql-query-compiler";
4
5
  import { PostgreSQLQueryCompiler } from "./dialect/postgres";
5
6
  import { MySQLQueryCompiler } from "./dialect/mysql";
@@ -13,21 +14,23 @@ import { SQLiteQueryCompiler } from "./dialect/sqlite";
13
14
  *
14
15
  * @param db - Kysely database instance
15
16
  * @param driverConfig - Driver configuration with database type and capabilities
16
- * @param mapper - Optional table name mapper for namespace prefixing
17
+ * @param sqliteStorageMode - Optional SQLite storage mode override
18
+ * @param resolver - Optional naming resolver for namespace prefixing
17
19
  * @returns Dialect-specific SQLQueryCompiler instance
18
20
  */
19
21
  export function createSQLQueryCompiler(
20
22
  db: AnyKysely,
21
23
  driverConfig: DriverConfig,
22
- mapper?: TableNameMapper,
24
+ sqliteStorageMode?: SQLiteStorageMode,
25
+ resolver?: NamingResolver,
23
26
  ): SQLQueryCompiler {
24
27
  switch (driverConfig.databaseType) {
25
28
  case "postgresql":
26
- return new PostgreSQLQueryCompiler(db, driverConfig, mapper);
29
+ return new PostgreSQLQueryCompiler(db, driverConfig, sqliteStorageMode, resolver);
27
30
  case "mysql":
28
- return new MySQLQueryCompiler(db, driverConfig, mapper);
31
+ return new MySQLQueryCompiler(db, driverConfig, sqliteStorageMode, resolver);
29
32
  case "sqlite":
30
- return new SQLiteQueryCompiler(db, driverConfig, mapper);
33
+ return new SQLiteQueryCompiler(db, driverConfig, sqliteStorageMode, resolver);
31
34
  default: {
32
35
  const exhaustiveCheck: never = driverConfig.databaseType;
33
36
  throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
@@ -0,0 +1,271 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { column, idColumn, schema } from "../../../schema/create";
3
+ import { Cursor } from "../../../query/cursor";
4
+ import type { Condition } from "../../../query/condition-builder";
5
+ import { NodePostgresDriverConfig } from "../driver-config";
6
+ import { buildCursorCondition } from "./cursor-utils";
7
+
8
+ const testSchema = schema("workflow", (s) => {
9
+ return s.addTable("workflow_step", (t) => {
10
+ return t
11
+ .addColumn("id", idColumn())
12
+ .addColumn("workflowName", column("string"))
13
+ .addColumn("instanceId", column("string"))
14
+ .addColumn("runNumber", column("integer"))
15
+ .addColumn("createdAt", column("timestamp"));
16
+ });
17
+ });
18
+
19
+ const table = testSchema.tables.workflow_step;
20
+ const indexColumns = [
21
+ table.columns.workflowName,
22
+ table.columns.instanceId,
23
+ table.columns.runNumber,
24
+ table.columns.createdAt,
25
+ ];
26
+
27
+ type NormalizedCondition =
28
+ | { type: "compare"; column: string; operator: string; value: unknown }
29
+ | { type: "and" | "or"; items: NormalizedCondition[] }
30
+ | { type: "not"; item: NormalizedCondition };
31
+
32
+ const normalizeCondition = (condition?: Condition): NormalizedCondition | null => {
33
+ if (!condition) {
34
+ return null;
35
+ }
36
+
37
+ switch (condition.type) {
38
+ case "compare":
39
+ return {
40
+ type: "compare",
41
+ column: condition.a.name,
42
+ operator: condition.operator,
43
+ value: condition.b,
44
+ };
45
+ case "and":
46
+ case "or":
47
+ return {
48
+ type: condition.type,
49
+ items: condition.items.map((item) => normalizeCondition(item) as NormalizedCondition),
50
+ };
51
+ case "not":
52
+ return {
53
+ type: "not",
54
+ item: normalizeCondition(condition.item) as NormalizedCondition,
55
+ };
56
+ default: {
57
+ const exhaustiveCheck: never = condition;
58
+ throw new Error(`Unsupported condition type: ${JSON.stringify(exhaustiveCheck)}`);
59
+ }
60
+ }
61
+ };
62
+
63
+ describe("buildCursorCondition", () => {
64
+ it("builds lexicographic conditions for composite asc cursors", () => {
65
+ const createdAt = new Date("2024-01-01T00:00:00.000Z");
66
+ const cursor = new Cursor({
67
+ indexName: "idx_workflow_step_history_createdAt",
68
+ orderDirection: "asc",
69
+ pageSize: 10,
70
+ indexValues: {
71
+ workflowName: "wf",
72
+ instanceId: "inst",
73
+ runNumber: 2,
74
+ createdAt,
75
+ },
76
+ });
77
+
78
+ const condition = buildCursorCondition(
79
+ cursor,
80
+ indexColumns,
81
+ "asc",
82
+ true,
83
+ new NodePostgresDriverConfig(),
84
+ );
85
+
86
+ expect(normalizeCondition(condition)).toEqual({
87
+ type: "or",
88
+ items: [
89
+ {
90
+ type: "compare",
91
+ column: "workflowName",
92
+ operator: ">",
93
+ value: "wf",
94
+ },
95
+ {
96
+ type: "and",
97
+ items: [
98
+ {
99
+ type: "compare",
100
+ column: "workflowName",
101
+ operator: "=",
102
+ value: "wf",
103
+ },
104
+ {
105
+ type: "compare",
106
+ column: "instanceId",
107
+ operator: ">",
108
+ value: "inst",
109
+ },
110
+ ],
111
+ },
112
+ {
113
+ type: "and",
114
+ items: [
115
+ {
116
+ type: "compare",
117
+ column: "workflowName",
118
+ operator: "=",
119
+ value: "wf",
120
+ },
121
+ {
122
+ type: "compare",
123
+ column: "instanceId",
124
+ operator: "=",
125
+ value: "inst",
126
+ },
127
+ {
128
+ type: "compare",
129
+ column: "runNumber",
130
+ operator: ">",
131
+ value: 2,
132
+ },
133
+ ],
134
+ },
135
+ {
136
+ type: "and",
137
+ items: [
138
+ {
139
+ type: "compare",
140
+ column: "workflowName",
141
+ operator: "=",
142
+ value: "wf",
143
+ },
144
+ {
145
+ type: "compare",
146
+ column: "instanceId",
147
+ operator: "=",
148
+ value: "inst",
149
+ },
150
+ {
151
+ type: "compare",
152
+ column: "runNumber",
153
+ operator: "=",
154
+ value: 2,
155
+ },
156
+ {
157
+ type: "compare",
158
+ column: "createdAt",
159
+ operator: ">",
160
+ value: createdAt,
161
+ },
162
+ ],
163
+ },
164
+ ],
165
+ });
166
+ });
167
+
168
+ it("builds lexicographic conditions for composite desc cursors", () => {
169
+ const createdAt = new Date("2024-01-01T00:00:00.000Z");
170
+ const cursor = new Cursor({
171
+ indexName: "idx_workflow_step_history_createdAt",
172
+ orderDirection: "desc",
173
+ pageSize: 10,
174
+ indexValues: {
175
+ workflowName: "wf",
176
+ instanceId: "inst",
177
+ runNumber: 2,
178
+ createdAt,
179
+ },
180
+ });
181
+
182
+ const condition = buildCursorCondition(
183
+ cursor,
184
+ indexColumns,
185
+ "desc",
186
+ true,
187
+ new NodePostgresDriverConfig(),
188
+ );
189
+
190
+ expect(normalizeCondition(condition)).toEqual({
191
+ type: "or",
192
+ items: [
193
+ {
194
+ type: "compare",
195
+ column: "workflowName",
196
+ operator: "<",
197
+ value: "wf",
198
+ },
199
+ {
200
+ type: "and",
201
+ items: [
202
+ {
203
+ type: "compare",
204
+ column: "workflowName",
205
+ operator: "=",
206
+ value: "wf",
207
+ },
208
+ {
209
+ type: "compare",
210
+ column: "instanceId",
211
+ operator: "<",
212
+ value: "inst",
213
+ },
214
+ ],
215
+ },
216
+ {
217
+ type: "and",
218
+ items: [
219
+ {
220
+ type: "compare",
221
+ column: "workflowName",
222
+ operator: "=",
223
+ value: "wf",
224
+ },
225
+ {
226
+ type: "compare",
227
+ column: "instanceId",
228
+ operator: "=",
229
+ value: "inst",
230
+ },
231
+ {
232
+ type: "compare",
233
+ column: "runNumber",
234
+ operator: "<",
235
+ value: 2,
236
+ },
237
+ ],
238
+ },
239
+ {
240
+ type: "and",
241
+ items: [
242
+ {
243
+ type: "compare",
244
+ column: "workflowName",
245
+ operator: "=",
246
+ value: "wf",
247
+ },
248
+ {
249
+ type: "compare",
250
+ column: "instanceId",
251
+ operator: "=",
252
+ value: "inst",
253
+ },
254
+ {
255
+ type: "compare",
256
+ column: "runNumber",
257
+ operator: "=",
258
+ value: 2,
259
+ },
260
+ {
261
+ type: "compare",
262
+ column: "createdAt",
263
+ operator: "<",
264
+ value: createdAt,
265
+ },
266
+ ],
267
+ },
268
+ ],
269
+ });
270
+ });
271
+ });