@fragno-dev/db 0.2.2 → 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 (355) hide show
  1. package/.turbo/turbo-build.log +202 -140
  2. package/CHANGELOG.md +35 -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 +39 -29
  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 +18 -7
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +116 -54
  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 +79 -2
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +150 -32
  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 +42 -1
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +72 -6
  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 +15 -8
  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.map +1 -1
  165. package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
  166. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  167. package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
  168. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  169. package/dist/query/unit-of-work/unit-of-work.js +86 -5
  170. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  171. package/dist/query/value-decoding.js +9 -6
  172. package/dist/query/value-decoding.js.map +1 -1
  173. package/dist/query/value-encoding.js +29 -9
  174. package/dist/query/value-encoding.js.map +1 -1
  175. package/dist/schema/create.d.ts +38 -14
  176. package/dist/schema/create.d.ts.map +1 -1
  177. package/dist/schema/create.js +81 -42
  178. package/dist/schema/create.js.map +1 -1
  179. package/dist/schema/generate-id.js +2 -2
  180. package/dist/schema/generate-id.js.map +1 -1
  181. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  182. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  183. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  184. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  185. package/dist/schema/validator.d.ts +10 -0
  186. package/dist/schema/validator.d.ts.map +1 -0
  187. package/dist/schema/validator.js +123 -0
  188. package/dist/schema/validator.js.map +1 -0
  189. package/dist/schema-output/drizzle.d.ts +30 -0
  190. package/dist/schema-output/drizzle.d.ts.map +1 -0
  191. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  192. package/dist/schema-output/drizzle.js.map +1 -0
  193. package/dist/schema-output/prisma.d.ts +17 -0
  194. package/dist/schema-output/prisma.d.ts.map +1 -0
  195. package/dist/schema-output/prisma.js +296 -0
  196. package/dist/schema-output/prisma.js.map +1 -0
  197. package/dist/util/default-database-adapter.js +61 -0
  198. package/dist/util/default-database-adapter.js.map +1 -0
  199. package/dist/with-database.d.ts +1 -1
  200. package/dist/with-database.d.ts.map +1 -1
  201. package/dist/with-database.js +12 -3
  202. package/dist/with-database.js.map +1 -1
  203. package/package.json +43 -28
  204. package/src/adapters/adapters.ts +30 -24
  205. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  206. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  207. package/src/adapters/drizzle/test-utils.ts +12 -8
  208. package/src/adapters/generic-sql/driver-config.ts +38 -0
  209. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  210. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  211. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  212. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  213. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  214. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  215. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  216. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  217. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  218. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  219. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  220. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  221. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  222. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  223. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  224. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  225. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  226. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  227. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  228. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  229. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  230. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  231. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  232. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  233. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  234. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  235. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  236. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  237. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
  238. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
  239. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  240. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  241. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  242. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  243. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  244. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  245. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  246. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  247. package/src/adapters/in-memory/errors.ts +20 -0
  248. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  249. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  250. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  251. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  252. package/src/adapters/in-memory/index.ts +3 -0
  253. package/src/adapters/in-memory/options.test.ts +41 -0
  254. package/src/adapters/in-memory/options.ts +87 -0
  255. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  256. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  257. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  258. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  259. package/src/adapters/in-memory/store.test.ts +68 -0
  260. package/src/adapters/in-memory/store.ts +145 -0
  261. package/src/adapters/in-memory/value-comparison.ts +53 -0
  262. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  263. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  264. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  265. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  266. package/src/adapters/sql/index.ts +12 -0
  267. package/src/db-fragment-definition-builder.test.ts +30 -12
  268. package/src/db-fragment-definition-builder.ts +142 -73
  269. package/src/db-fragment-instantiator.test.ts +105 -13
  270. package/src/db-fragment-integration.test.ts +9 -7
  271. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  272. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  273. package/src/dispatchers/node/index.test.ts +91 -0
  274. package/src/dispatchers/node/index.ts +87 -0
  275. package/src/fragments/internal-fragment.routes.ts +42 -0
  276. package/src/fragments/internal-fragment.schema.ts +51 -0
  277. package/src/fragments/internal-fragment.test.ts +458 -8
  278. package/src/fragments/internal-fragment.ts +322 -63
  279. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  280. package/src/hooks/durable-hooks-processor.ts +67 -0
  281. package/src/hooks/hooks.test.ts +165 -5
  282. package/src/hooks/hooks.ts +197 -9
  283. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  284. package/src/migration-engine/auto-from-schema.ts +5 -2
  285. package/src/migration-engine/create.test.ts +2 -2
  286. package/src/migration-engine/generation-engine.test.ts +229 -104
  287. package/src/migration-engine/generation-engine.ts +94 -64
  288. package/src/migration-engine/shared.ts +1 -0
  289. package/src/mod.ts +64 -26
  290. package/src/naming/sql-naming.ts +180 -0
  291. package/src/outbox/outbox-builder.ts +241 -0
  292. package/src/outbox/outbox.test.ts +253 -0
  293. package/src/outbox/outbox.ts +137 -0
  294. package/src/query/column-defaults.ts +41 -3
  295. package/src/query/condition-builder.test.ts +3 -3
  296. package/src/query/cursor.test.ts +116 -18
  297. package/src/query/cursor.ts +75 -26
  298. package/src/query/db-now.ts +6 -0
  299. package/src/query/query-type.test.ts +2 -2
  300. package/src/query/serialize/create-sql-serializer.ts +7 -2
  301. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  302. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  303. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  304. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  305. package/src/query/serialize/sql-serializer.ts +4 -4
  306. package/src/query/simple-query-interface.ts +5 -0
  307. package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
  308. package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
  309. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
  310. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  311. package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
  312. package/src/query/unit-of-work/unit-of-work.ts +203 -18
  313. package/src/query/value-decoding.test.ts +13 -2
  314. package/src/query/value-decoding.ts +17 -4
  315. package/src/query/value-encoding.test.ts +85 -2
  316. package/src/query/value-encoding.ts +56 -6
  317. package/src/schema/create.test.ts +129 -42
  318. package/src/schema/create.ts +185 -47
  319. package/src/schema/generate-id.test.ts +2 -2
  320. package/src/schema/generate-id.ts +2 -2
  321. package/src/schema/serialize.test.ts +14 -2
  322. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  323. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  324. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  325. package/src/schema/validator.test.ts +197 -0
  326. package/src/schema/validator.ts +231 -0
  327. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  328. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  329. package/src/schema-output/prisma.test.ts +536 -0
  330. package/src/schema-output/prisma.ts +573 -0
  331. package/src/util/default-database-adapter.ts +106 -0
  332. package/src/with-database.ts +22 -3
  333. package/tsdown.config.ts +6 -4
  334. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  335. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  337. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  338. package/dist/adapters/drizzle/generate.d.ts +0 -30
  339. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/generate.js.map +0 -1
  341. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  342. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  343. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  344. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  345. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  346. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  347. package/dist/adapters/shared/table-name-mapper.js +0 -43
  348. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  349. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  350. package/dist/schema-generator/schema-generator.d.ts +0 -15
  351. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  352. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  353. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  354. package/src/adapters/shared/table-name-mapper.ts +0 -50
  355. package/src/schema-generator/schema-generator.ts +0 -12
@@ -1 +1 @@
1
- {"version":3,"file":"generic-sql-adapter.js","names":["#schemaNamespaceMap","#contextStorage","#driver","result: QueryResult<Record<string, unknown>>"],"sources":["../../../src/adapters/generic-sql/generic-sql-adapter.ts"],"sourcesContent":["import { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\nimport {\n fragnoDatabaseAdapterNameFakeSymbol,\n fragnoDatabaseAdapterVersionFakeSymbol,\n type DatabaseAdapter,\n type DatabaseContextStorage,\n type TableNameMapper,\n} from \"../adapters\";\nimport type { CompiledQuery, Dialect, QueryResult } from \"../../sql-driver/sql-driver\";\nimport { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport { sql } from \"../../sql-driver/sql\";\nimport type { AnySchema } from \"../../schema/create\";\nimport { createTableNameMapper } from \"../shared/table-name-mapper\";\nimport type { SimpleQueryInterface } from \"../../query/simple-query-interface\";\nimport { createExecutor } from \"./generic-sql-uow-executor\";\nimport { UnitOfWorkDecoder } from \"./uow-decoder\";\nimport { createPreparedMigrations, type PreparedMigrations } from \"./migration/prepared-migrations\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { GenericSQLUOWOperationCompiler } from \"./query/generic-sql-uow-operation-compiler\";\nimport { createUOWCompilerFromOperationCompiler } from \"../shared/uow-operation-compiler\";\nimport {\n fromUnitOfWorkCompiler,\n type UnitOfWorkFactory,\n} from \"../shared/from-unit-of-work-compiler\";\n\nexport interface UnitOfWorkConfig {\n onQuery?: (query: CompiledQuery) => void;\n dryRun?: boolean;\n}\n\nexport interface GenericSQLOptions {\n dialect: Dialect;\n driverConfig: DriverConfig;\n uowConfig?: UnitOfWorkConfig;\n}\n\nexport class GenericSQLAdapter implements DatabaseAdapter<UnitOfWorkConfig> {\n readonly dialect: Dialect;\n readonly driverConfig: DriverConfig;\n readonly uowConfig?: UnitOfWorkConfig;\n\n #schemaNamespaceMap = new WeakMap<AnySchema, string>();\n #contextStorage: RequestContextStorage<DatabaseContextStorage>;\n\n #driver: SqlDriverAdapter;\n\n constructor({ dialect, driverConfig, uowConfig }: GenericSQLOptions) {\n this.dialect = dialect;\n this.driverConfig = driverConfig;\n this.uowConfig = uowConfig;\n\n this.#schemaNamespaceMap = new WeakMap<AnySchema, string>();\n this.#contextStorage = new RequestContextStorage();\n\n this.#driver = new SqlDriverAdapter(dialect);\n }\n\n get driver(): SqlDriverAdapter {\n return this.#driver;\n }\n\n get [fragnoDatabaseAdapterNameFakeSymbol](): string {\n return \"generic-sql\";\n }\n\n get [fragnoDatabaseAdapterVersionFakeSymbol](): number {\n return 0;\n }\n\n get contextStorage(): RequestContextStorage<DatabaseContextStorage> {\n return this.#contextStorage;\n }\n\n close(): Promise<void> {\n return this.#driver.destroy();\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n const result = await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect));\n return result.rows[0][\"healthy\"] === 1;\n }\n\n prepareMigrations<T extends AnySchema>(schema: T, namespace: string): PreparedMigrations {\n return createPreparedMigrations({\n schema,\n namespace,\n database: this.driverConfig.databaseType,\n mapper: namespace ? this.createTableNameMapper(namespace) : undefined,\n driver: this.#driver,\n });\n }\n\n createTableNameMapper(namespace: string): TableNameMapper {\n return createTableNameMapper(namespace, false);\n }\n\n async getSchemaVersion(namespace: string): Promise<string | undefined> {\n const key = `${namespace}.schema_version`;\n const query = sql`SELECT value FROM fragno_db_settings WHERE key = ${key};`.compile(\n this.dialect,\n );\n\n let result: QueryResult<Record<string, unknown>>;\n try {\n result = await this.#driver.executeQuery(query);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"fragno_db_settings\")) {\n return undefined;\n }\n throw error;\n }\n\n const value = result.rows[0][\"value\"];\n\n if (!value) {\n return undefined;\n }\n\n if (typeof value !== \"string\") {\n throw new Error(`Schema version for namespace ${namespace} is not a string`);\n }\n\n return value;\n }\n\n createQueryEngine<T extends AnySchema>(\n schema: T,\n namespace: string,\n ): SimpleQueryInterface<T, UnitOfWorkConfig> {\n this.#schemaNamespaceMap.set(schema, namespace);\n\n const operationCompiler = new GenericSQLUOWOperationCompiler(this.driverConfig, (ns) =>\n ns ? this.createTableNameMapper(ns) : undefined,\n );\n\n const factory: UnitOfWorkFactory = {\n compiler: createUOWCompilerFromOperationCompiler(operationCompiler),\n executor: createExecutor(this.#driver, this.driverConfig, false),\n decoder: new UnitOfWorkDecoder(this.driverConfig),\n uowConfig: this.uowConfig,\n schemaNamespaceMap: this.#schemaNamespaceMap,\n };\n\n return fromUnitOfWorkCompiler(schema, factory);\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAoCA,IAAa,oBAAb,MAA4E;CAC1E,AAAS;CACT,AAAS;CACT,AAAS;CAET,sCAAsB,IAAI,SAA4B;CACtD;CAEA;CAEA,YAAY,EAAE,SAAS,cAAc,aAAgC;AACnE,OAAK,UAAU;AACf,OAAK,eAAe;AACpB,OAAK,YAAY;AAEjB,QAAKA,qCAAsB,IAAI,SAA4B;AAC3D,QAAKC,iBAAkB,IAAI,uBAAuB;AAElD,QAAKC,SAAU,IAAI,iBAAiB,QAAQ;;CAG9C,IAAI,SAA2B;AAC7B,SAAO,MAAKA;;CAGd,KAAK,uCAA+C;AAClD,SAAO;;CAGT,KAAK,0CAAkD;AACrD,SAAO;;CAGT,IAAI,iBAAgE;AAClE,SAAO,MAAKD;;CAGd,QAAuB;AACrB,SAAO,MAAKC,OAAQ,SAAS;;CAG/B,MAAM,sBAAwC;AAE5C,UADe,MAAM,MAAKA,OAAQ,aAAa,GAAG,sBAAsB,QAAQ,KAAK,QAAQ,CAAC,EAChF,KAAK,GAAG,eAAe;;CAGvC,kBAAuC,QAAW,WAAuC;AACvF,SAAO,yBAAyB;GAC9B;GACA;GACA,UAAU,KAAK,aAAa;GAC5B,QAAQ,YAAY,KAAK,sBAAsB,UAAU,GAAG;GAC5D,QAAQ,MAAKA;GACd,CAAC;;CAGJ,sBAAsB,WAAoC;AACxD,SAAO,sBAAsB,WAAW,MAAM;;CAGhD,MAAM,iBAAiB,WAAgD;EAErE,MAAM,QAAQ,GAAG,oDADL,GAAG,UAAU,iBACgD,GAAG,QAC1E,KAAK,QACN;EAED,IAAIC;AACJ,MAAI;AACF,YAAS,MAAM,MAAKD,OAAQ,aAAa,MAAM;WACxC,OAAO;AACd,OAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,qBAAqB,CACxE;AAEF,SAAM;;EAGR,MAAM,QAAQ,OAAO,KAAK,GAAG;AAE7B,MAAI,CAAC,MACH;AAGF,MAAI,OAAO,UAAU,SACnB,OAAM,IAAI,MAAM,gCAAgC,UAAU,kBAAkB;AAG9E,SAAO;;CAGT,kBACE,QACA,WAC2C;AAC3C,QAAKF,mBAAoB,IAAI,QAAQ,UAAU;AAc/C,SAAO,uBAAuB,QARK;GACjC,UAAU,uCALc,IAAI,+BAA+B,KAAK,eAAe,OAC/E,KAAK,KAAK,sBAAsB,GAAG,GAAG,OACvC,CAGoE;GACnE,UAAU,eAAe,MAAKE,QAAS,KAAK,cAAc,MAAM;GAChE,SAAS,IAAI,kBAAkB,KAAK,aAAa;GACjD,WAAW,KAAK;GAChB,oBAAoB,MAAKF;GAC1B,CAE6C"}
1
+ {"version":3,"file":"generic-sql-adapter.js","names":["sqliteProfiles: Record<SQLiteProfile, SQLiteStorageMode>","#schemaNamespaceMap","#contextStorage","#driver","result: QueryResult<Record<string, unknown>>"],"sources":["../../../src/adapters/generic-sql/generic-sql-adapter.ts"],"sourcesContent":["import { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\nimport {\n fragnoDatabaseAdapterNameFakeSymbol,\n fragnoDatabaseAdapterVersionFakeSymbol,\n type DatabaseAdapter,\n type DatabaseContextStorage,\n type DatabaseAdapterMetadata,\n type SQLiteProfile,\n} from \"../adapters\";\nimport type { CompiledQuery, Dialect, QueryResult } from \"../../sql-driver/sql-driver\";\nimport { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport { sql } from \"../../sql-driver/sql\";\nimport type { AnyColumn, AnySchema } from \"../../schema/create\";\nimport type { SimpleQueryInterface } from \"../../query/simple-query-interface\";\nimport { createExecutor } from \"./generic-sql-uow-executor\";\nimport { UnitOfWorkDecoder } from \"./uow-decoder\";\nimport { createPreparedMigrations, type PreparedMigrations } from \"./migration/prepared-migrations\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { GenericSQLUOWOperationCompiler } from \"./query/generic-sql-uow-operation-compiler\";\nimport { createUOWCompilerFromOperationCompiler } from \"../shared/uow-operation-compiler\";\nimport {\n fromUnitOfWorkCompiler,\n type UnitOfWorkFactory,\n} from \"../shared/from-unit-of-work-compiler\";\nimport type { UOWInstrumentation } from \"../../query/unit-of-work/unit-of-work\";\nimport type { SQLiteStorageMode } from \"./sqlite-storage\";\nimport { sqliteStorageDefault, sqliteStoragePrisma } from \"./sqlite-storage\";\nimport type { OutboxConfig } from \"../../outbox/outbox\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport {\n createNamingResolver,\n type NamingResolver,\n type SqlNamingStrategy,\n} from \"../../naming/sql-naming\";\n\nexport interface UnitOfWorkConfig {\n onQuery?: (query: CompiledQuery) => void;\n dryRun?: boolean;\n instrumentation?: UOWInstrumentation;\n}\n\nexport interface SqlAdapterOptions {\n dialect: Dialect;\n driverConfig: DriverConfig;\n uowConfig?: UnitOfWorkConfig;\n outbox?: OutboxConfig;\n sqliteProfile?: SQLiteProfile;\n sqliteStorageMode?: SQLiteStorageMode;\n namingStrategy?: SqlNamingStrategy;\n}\n\nexport const sqliteProfiles: Record<SQLiteProfile, SQLiteStorageMode> = {\n default: sqliteStorageDefault,\n prisma: sqliteStoragePrisma,\n};\n\nexport class SqlAdapter implements DatabaseAdapter<UnitOfWorkConfig> {\n readonly dialect: Dialect;\n readonly driverConfig: DriverConfig;\n readonly uowConfig?: UnitOfWorkConfig;\n readonly outbox?: OutboxConfig;\n readonly sqliteStorageMode?: SQLiteStorageMode;\n readonly sqliteProfile?: SQLiteProfile;\n readonly adapterMetadata: DatabaseAdapterMetadata;\n readonly namingStrategy: SqlNamingStrategy;\n\n #schemaNamespaceMap = new WeakMap<AnySchema, string | null>();\n #contextStorage: RequestContextStorage<DatabaseContextStorage>;\n\n #driver: SqlDriverAdapter;\n\n constructor({\n dialect,\n driverConfig,\n uowConfig,\n outbox,\n sqliteProfile,\n sqliteStorageMode,\n namingStrategy,\n }: SqlAdapterOptions) {\n this.dialect = dialect;\n this.driverConfig = driverConfig;\n this.uowConfig = uowConfig;\n this.outbox = outbox;\n this.namingStrategy = namingStrategy ?? driverConfig.defaultNamingStrategy;\n const resolvedProfile = sqliteProfile ?? \"default\";\n\n if (sqliteStorageMode && sqliteProfile) {\n throw new Error(\"sqliteStorageMode cannot be used together with sqliteProfile.\");\n }\n\n this.sqliteStorageMode =\n driverConfig.databaseType === \"sqlite\"\n ? (sqliteStorageMode ?? sqliteProfiles[resolvedProfile])\n : undefined;\n this.sqliteProfile =\n driverConfig.databaseType === \"sqlite\" && !sqliteStorageMode ? resolvedProfile : undefined;\n\n this.adapterMetadata = {\n databaseType: driverConfig.databaseType,\n sqliteProfile: this.sqliteProfile,\n sqliteStorageMode: this.sqliteStorageMode,\n };\n\n this.#schemaNamespaceMap = new WeakMap<AnySchema, string | null>();\n this.#contextStorage = new RequestContextStorage();\n\n this.#driver = new SqlDriverAdapter(dialect);\n }\n\n get driver(): SqlDriverAdapter {\n return this.#driver;\n }\n\n get [fragnoDatabaseAdapterNameFakeSymbol](): string {\n return \"sql\";\n }\n\n get [fragnoDatabaseAdapterVersionFakeSymbol](): number {\n return 1;\n }\n\n get contextStorage(): RequestContextStorage<DatabaseContextStorage> {\n return this.#contextStorage;\n }\n\n close(): Promise<void> {\n return this.#driver.destroy();\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n const result = await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect));\n const healthyValue = result.rows[0]?.[\"healthy\"];\n return healthyValue === 1 || healthyValue === 1n || healthyValue === \"1\";\n }\n\n prepareMigrations<T extends AnySchema>(schema: T, namespace: string | null): PreparedMigrations {\n const resolver = createNamingResolver(schema, namespace, this.namingStrategy);\n return createPreparedMigrations({\n schema,\n namespace: namespace ?? schema.name,\n database: this.driverConfig.databaseType,\n driverConfig: this.driverConfig,\n sqliteStorageMode: this.sqliteStorageMode,\n resolver,\n driver: this.#driver,\n });\n }\n\n async getSchemaVersion(namespace: string): Promise<string | undefined> {\n const key = `${namespace}.schema_version`;\n const query = sql`SELECT value FROM fragno_db_settings WHERE key = ${key};`.compile(\n this.dialect,\n );\n\n let result: QueryResult<Record<string, unknown>>;\n try {\n result = await this.#driver.executeQuery(query);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"fragno_db_settings\")) {\n return undefined;\n }\n throw error;\n }\n\n const value = result.rows[0][\"value\"];\n\n if (!value) {\n return undefined;\n }\n\n if (typeof value !== \"string\") {\n throw new Error(`Schema version for namespace ${namespace} is not a string`);\n }\n\n return value;\n }\n\n createQueryEngine<T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ): SimpleQueryInterface<T, UnitOfWorkConfig> {\n this.#schemaNamespaceMap.set(schema, namespace);\n const resolver = createNamingResolver(schema, namespace, this.namingStrategy);\n\n const operationCompiler = new GenericSQLUOWOperationCompiler(\n this.driverConfig,\n this.sqliteStorageMode,\n (schemaForResolver, namespaceForResolver): NamingResolver =>\n createNamingResolver(schemaForResolver, namespaceForResolver, this.namingStrategy),\n );\n\n const factory: UnitOfWorkFactory = {\n compiler: createUOWCompilerFromOperationCompiler(operationCompiler),\n executor: createExecutor(this.#driver, this.driverConfig, {\n dialect: this.dialect,\n dryRun: false,\n outbox: this.outbox,\n namingStrategy: this.namingStrategy,\n }),\n decoder: new UnitOfWorkDecoder(this.driverConfig, this.sqliteStorageMode, resolver),\n uowConfig: this.uowConfig,\n schemaNamespaceMap: this.#schemaNamespaceMap,\n };\n\n const queryEngine = fromUnitOfWorkCompiler(schema, factory) as SimpleQueryInterface<\n T,\n UnitOfWorkConfig\n >;\n\n const serializer = createSQLSerializer(this.driverConfig, this.sqliteStorageMode);\n const timestampColumn = { type: \"timestamp\" } as AnyColumn;\n\n return {\n ...queryEngine,\n now: async () => {\n const result = await this.#driver.executeQuery(\n sql`SELECT CURRENT_TIMESTAMP as now`.compile(this.dialect),\n );\n const rawValue = result.rows[0]?.[\"now\"];\n if (rawValue === undefined || rawValue === null) {\n throw new Error(\"Failed to fetch database time\");\n }\n return serializer.deserialize(rawValue, timestampColumn) as Date;\n },\n };\n }\n}\n\nexport type { SQLiteStorageMode } from \"./sqlite-storage\";\nexport { sqliteStorageDefault, sqliteStoragePrisma } from \"./sqlite-storage\";\nexport type { OutboxConfig } from \"../../outbox/outbox\";\n"],"mappings":";;;;;;;;;;;;;;;AAmDA,MAAaA,iBAA2D;CACtE,SAAS;CACT,QAAQ;CACT;AAED,IAAa,aAAb,MAAqE;CACnE,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CACT,AAAS;CAET,sCAAsB,IAAI,SAAmC;CAC7D;CAEA;CAEA,YAAY,EACV,SACA,cACA,WACA,QACA,eACA,mBACA,kBACoB;AACpB,OAAK,UAAU;AACf,OAAK,eAAe;AACpB,OAAK,YAAY;AACjB,OAAK,SAAS;AACd,OAAK,iBAAiB,kBAAkB,aAAa;EACrD,MAAM,kBAAkB,iBAAiB;AAEzC,MAAI,qBAAqB,cACvB,OAAM,IAAI,MAAM,gEAAgE;AAGlF,OAAK,oBACH,aAAa,iBAAiB,WACzB,qBAAqB,eAAe,mBACrC;AACN,OAAK,gBACH,aAAa,iBAAiB,YAAY,CAAC,oBAAoB,kBAAkB;AAEnF,OAAK,kBAAkB;GACrB,cAAc,aAAa;GAC3B,eAAe,KAAK;GACpB,mBAAmB,KAAK;GACzB;AAED,QAAKC,qCAAsB,IAAI,SAAmC;AAClE,QAAKC,iBAAkB,IAAI,uBAAuB;AAElD,QAAKC,SAAU,IAAI,iBAAiB,QAAQ;;CAG9C,IAAI,SAA2B;AAC7B,SAAO,MAAKA;;CAGd,KAAK,uCAA+C;AAClD,SAAO;;CAGT,KAAK,0CAAkD;AACrD,SAAO;;CAGT,IAAI,iBAAgE;AAClE,SAAO,MAAKD;;CAGd,QAAuB;AACrB,SAAO,MAAKC,OAAQ,SAAS;;CAG/B,MAAM,sBAAwC;EAE5C,MAAM,gBADS,MAAM,MAAKA,OAAQ,aAAa,GAAG,sBAAsB,QAAQ,KAAK,QAAQ,CAAC,EAClE,KAAK,KAAK;AACtC,SAAO,iBAAiB,KAAK,iBAAiB,MAAM,iBAAiB;;CAGvE,kBAAuC,QAAW,WAA8C;EAC9F,MAAM,WAAW,qBAAqB,QAAQ,WAAW,KAAK,eAAe;AAC7E,SAAO,yBAAyB;GAC9B;GACA,WAAW,aAAa,OAAO;GAC/B,UAAU,KAAK,aAAa;GAC5B,cAAc,KAAK;GACnB,mBAAmB,KAAK;GACxB;GACA,QAAQ,MAAKA;GACd,CAAC;;CAGJ,MAAM,iBAAiB,WAAgD;EAErE,MAAM,QAAQ,GAAG,oDADL,GAAG,UAAU,iBACgD,GAAG,QAC1E,KAAK,QACN;EAED,IAAIC;AACJ,MAAI;AACF,YAAS,MAAM,MAAKD,OAAQ,aAAa,MAAM;WACxC,OAAO;AACd,OAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,qBAAqB,CACxE;AAEF,SAAM;;EAGR,MAAM,QAAQ,OAAO,KAAK,GAAG;AAE7B,MAAI,CAAC,MACH;AAGF,MAAI,OAAO,UAAU,SACnB,OAAM,IAAI,MAAM,gCAAgC,UAAU,kBAAkB;AAG9E,SAAO;;CAGT,kBACE,QACA,WAC2C;AAC3C,QAAKF,mBAAoB,IAAI,QAAQ,UAAU;EAC/C,MAAM,WAAW,qBAAqB,QAAQ,WAAW,KAAK,eAAe;EAsB7E,MAAM,cAAc,uBAAuB,QAbR;GACjC,UAAU,uCARc,IAAI,+BAC5B,KAAK,cACL,KAAK,oBACJ,mBAAmB,yBAClB,qBAAqB,mBAAmB,sBAAsB,KAAK,eAAe,CACrF,CAGoE;GACnE,UAAU,eAAe,MAAKE,QAAS,KAAK,cAAc;IACxD,SAAS,KAAK;IACd,QAAQ;IACR,QAAQ,KAAK;IACb,gBAAgB,KAAK;IACtB,CAAC;GACF,SAAS,IAAI,kBAAkB,KAAK,cAAc,KAAK,mBAAmB,SAAS;GACnF,WAAW,KAAK;GAChB,oBAAoB,MAAKF;GAC1B,CAE0D;EAK3D,MAAM,aAAa,oBAAoB,KAAK,cAAc,KAAK,kBAAkB;EACjF,MAAM,kBAAkB,EAAE,MAAM,aAAa;AAE7C,SAAO;GACL,GAAG;GACH,KAAK,YAAY;IAIf,MAAM,YAHS,MAAM,MAAKE,OAAQ,aAChC,GAAG,kCAAkC,QAAQ,KAAK,QAAQ,CAC3D,EACuB,KAAK,KAAK;AAClC,QAAI,aAAa,UAAa,aAAa,KACzC,OAAM,IAAI,MAAM,gCAAgC;AAElD,WAAO,WAAW,YAAY,UAAU,gBAAgB;;GAE3D"}
@@ -1,4 +1,12 @@
1
+ import { sql } from "../../sql-driver/sql.js";
1
2
  import { ResultInterpreter } from "./result-interpreter.js";
3
+ import { createId } from "../../id.js";
4
+ import { createColdKysely } from "./migration/cold-kysely.js";
5
+ import { SETTINGS_NAMESPACE, internalSchema } from "../../fragments/internal-fragment.schema.js";
6
+ import { encodeVersionstamp, parseOutboxVersionValue, versionstampToHex } from "../../outbox/outbox.js";
7
+ import { buildOutboxPlan, finalizeOutboxPayload } from "../../outbox/outbox-builder.js";
8
+ import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
9
+ import superjson from "superjson";
2
10
 
3
11
  //#region src/adapters/generic-sql/generic-sql-uow-executor.ts
4
12
  async function executeRetrieval(adapter, retrievalBatch) {
@@ -12,15 +20,22 @@ async function executeRetrieval(adapter, retrievalBatch) {
12
20
  });
13
21
  return retrievalResults;
14
22
  }
15
- async function executeMutation(adapter, driverConfig, mutationBatch) {
23
+ async function executeMutation(adapter, driverConfig, mutationBatch, options) {
16
24
  if (mutationBatch.length === 0) return {
17
25
  success: true,
18
26
  createdInternalIds: []
19
27
  };
20
28
  const createdInternalIds = [];
21
29
  const resultInterpreter = new ResultInterpreter(driverConfig);
30
+ const outboxEnabled = options.outbox?.enabled ?? false;
31
+ const namingStrategy = options.namingStrategy ?? driverConfig.defaultNamingStrategy;
32
+ const outboxOperations = outboxEnabled ? mutationBatch.flatMap((mutation) => mutation.operation ? [mutation.operation] : []) : [];
33
+ const outboxPlan = outboxOperations.length > 0 ? buildOutboxPlan(outboxOperations) : null;
34
+ const shouldWriteOutbox = outboxEnabled && outboxPlan !== null && outboxPlan.drafts.length > 0;
22
35
  try {
23
36
  await adapter.transaction(async (tx) => {
37
+ let outboxVersion = null;
38
+ if (shouldWriteOutbox) outboxVersion = await reserveOutboxVersion(tx, driverConfig, options.dialect);
24
39
  for (const compiledMutation of mutationBatch) {
25
40
  const result = await tx.executeQuery(compiledMutation.query);
26
41
  if (compiledMutation.op === "create") if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {
@@ -36,6 +51,21 @@ async function executeMutation(adapter, driverConfig, mutationBatch) {
36
51
  if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) throw new Error(`Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`);
37
52
  }
38
53
  }
54
+ if (shouldWriteOutbox && outboxPlan && outboxVersion !== null) {
55
+ const uowId = mutationBatch[0]?.uowId;
56
+ if (!uowId) throw new Error("Outbox mutation batch is missing uowId.");
57
+ const refMap = await resolveOutboxRefMap(tx, driverConfig, outboxPlan.lookups, namingStrategy);
58
+ const payload = finalizeOutboxPayload(outboxPlan, outboxVersion);
59
+ const payloadSerialized = superjson.serialize(payload);
60
+ const versionstamp = versionstampToHex(encodeVersionstamp(outboxVersion, 0));
61
+ await insertOutboxRow(tx, driverConfig, {
62
+ id: createId(),
63
+ versionstamp,
64
+ uowId,
65
+ payload: payloadSerialized,
66
+ refMap
67
+ });
68
+ }
39
69
  });
40
70
  return {
41
71
  success: true,
@@ -43,10 +73,13 @@ async function executeMutation(adapter, driverConfig, mutationBatch) {
43
73
  };
44
74
  } catch (error) {
45
75
  if (error instanceof Error && error.message.includes("Version conflict")) return { success: false };
76
+ const errorCode = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
77
+ if (errorCode === "40001" || errorCode === "40P01") return { success: false };
46
78
  throw error;
47
79
  }
48
80
  }
49
- function createExecutor(adapter, driverConfig, dryRun) {
81
+ function createExecutor(adapter, driverConfig, options) {
82
+ const dryRun = options.dryRun ?? false;
50
83
  return {
51
84
  async executeRetrievalPhase(retrievalBatch) {
52
85
  if (dryRun) return retrievalBatch.map(() => []);
@@ -57,9 +90,102 @@ function createExecutor(adapter, driverConfig, dryRun) {
57
90
  success: true,
58
91
  createdInternalIds: mutationBatch.map(() => null)
59
92
  };
60
- return executeMutation(adapter, driverConfig, mutationBatch);
93
+ return executeMutation(adapter, driverConfig, mutationBatch, options);
94
+ }
95
+ };
96
+ }
97
+ async function reserveOutboxVersion(tx, driverConfig, dialect) {
98
+ const key = `${SETTINGS_NAMESPACE}.outbox_version`;
99
+ const id = createId();
100
+ switch (driverConfig.outboxVersionstampStrategy) {
101
+ case "insert-on-conflict-returning": {
102
+ const query = driverConfig.databaseType === "postgresql" ? sql`
103
+ insert into fragno_db_settings (id, key, value)
104
+ values (${id}, ${key}, '0')
105
+ on conflict (key) do update
106
+ set value = (fragno_db_settings.value::bigint + 1)::text
107
+ returning value;
108
+ ` : sql`
109
+ insert into fragno_db_settings (id, key, value)
110
+ values (${id}, ${key}, '0')
111
+ on conflict (key) do update
112
+ set value = cast(fragno_db_settings.value as integer) + 1
113
+ returning value;
114
+ `;
115
+ const value = (await tx.executeQuery(query.compile(dialect))).rows[0]?.["value"];
116
+ return parseOutboxVersionValue(value);
117
+ }
118
+ case "update-returning": {
119
+ const query = driverConfig.databaseType === "postgresql" ? sql`
120
+ update fragno_db_settings
121
+ set value = (fragno_db_settings.value::bigint + 1)::text
122
+ where key = ${key}
123
+ returning value;
124
+ ` : sql`
125
+ update fragno_db_settings
126
+ set value = cast(fragno_db_settings.value as integer) + 1
127
+ where key = ${key}
128
+ returning value;
129
+ `;
130
+ const value = (await tx.executeQuery(query.compile(dialect))).rows[0]?.["value"];
131
+ if (value === void 0) throw new Error("Outbox version row was not found for update-returning strategy.");
132
+ return parseOutboxVersionValue(value);
133
+ }
134
+ case "insert-on-duplicate-last-insert-id": {
135
+ const insertQuery = sql`
136
+ insert into fragno_db_settings (id, key, value)
137
+ values (${id}, ${key}, LAST_INSERT_ID(0))
138
+ on duplicate key update value = LAST_INSERT_ID(cast(value as unsigned) + 1);
139
+ `;
140
+ await tx.executeQuery(insertQuery.compile(dialect));
141
+ const selectQuery = sql`select LAST_INSERT_ID() as value;`;
142
+ const value = (await tx.executeQuery(selectQuery.compile(dialect))).rows[0]?.["value"];
143
+ return parseOutboxVersionValue(value);
61
144
  }
145
+ }
146
+ }
147
+ async function resolveOutboxRefMap(tx, driverConfig, lookups, namingStrategy) {
148
+ if (lookups.length === 0) return;
149
+ const refMap = {};
150
+ const db = createColdKysely(driverConfig.databaseType);
151
+ for (const lookup of lookups) {
152
+ const namespace = lookup.namespace ?? null;
153
+ const logicalTable = lookup.table.name;
154
+ const schemaName = namingStrategy.namespaceScope === "schema" && namespace && namespace.length > 0 ? namingStrategy.namespaceToSchema(namespace) : null;
155
+ const scopedDb = schemaName ? db.withSchema(schemaName) : db;
156
+ const tableName = namingStrategy.tableName(logicalTable, namespace);
157
+ const internalColumn = namingStrategy.columnName(lookup.table.getInternalIdColumn().name, logicalTable);
158
+ const externalColumn = namingStrategy.columnName(lookup.table.getIdColumn().name, logicalTable);
159
+ const query = scopedDb.selectFrom(tableName).select(externalColumn).where(internalColumn, "=", lookup.internalId).compile();
160
+ const externalId = (await tx.executeQuery(query)).rows[0]?.[externalColumn];
161
+ if (typeof externalId !== "string") throw new Error(`Failed to resolve outbox reference for ${tableName}.${internalColumn}=${String(lookup.internalId)}`);
162
+ refMap[lookup.key] = externalId;
163
+ }
164
+ return Object.keys(refMap).length > 0 ? refMap : void 0;
165
+ }
166
+ async function insertOutboxRow(tx, driverConfig, options) {
167
+ const { id, versionstamp, uowId, payload, refMap } = options;
168
+ const refMapValue = refMap ?? null;
169
+ const serializer = createSQLSerializer(driverConfig);
170
+ const outboxTable = internalSchema.tables.fragno_db_outbox;
171
+ const values = {
172
+ id,
173
+ versionstamp,
174
+ uowId,
175
+ payload,
176
+ refMap: refMapValue
62
177
  };
178
+ const serializedValues = {};
179
+ for (const [key, value] of Object.entries(values)) {
180
+ const col = outboxTable.columns[key];
181
+ if (!col) {
182
+ serializedValues[key] = value;
183
+ continue;
184
+ }
185
+ serializedValues[col.name] = serializer.serialize(value, col);
186
+ }
187
+ const query = createColdKysely(driverConfig.databaseType).insertInto("fragno_db_outbox").values(serializedValues).compile();
188
+ await tx.executeQuery(query);
63
189
  }
64
190
 
65
191
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"generic-sql-uow-executor.js","names":["retrievalResults: unknown[]","createdInternalIds: (bigint | null)[]"],"sources":["../../../src/adapters/generic-sql/generic-sql-uow-executor.ts"],"sourcesContent":["import type {\n CompiledMutation,\n MutationResult,\n UOWExecutor,\n} from \"../../query/unit-of-work/unit-of-work\";\nimport type { CompiledQuery } from \"../../sql-driver/sql-driver\";\nimport type { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { ResultInterpreter } from \"./result-interpreter\";\n\nexport async function executeRetrieval(\n adapter: SqlDriverAdapter,\n retrievalBatch: CompiledQuery[],\n): Promise<unknown[]> {\n if (retrievalBatch.length === 0) {\n return [];\n }\n\n const retrievalResults: unknown[] = [];\n\n await adapter.transaction(async (tx) => {\n for (const compiledQuery of retrievalBatch) {\n const result = await tx.executeQuery(compiledQuery);\n retrievalResults.push(result.rows);\n }\n });\n\n return retrievalResults;\n}\n\nexport async function executeMutation(\n adapter: SqlDriverAdapter,\n driverConfig: DriverConfig,\n mutationBatch: CompiledMutation<CompiledQuery>[],\n): Promise<MutationResult> {\n if (mutationBatch.length === 0) {\n return { success: true, createdInternalIds: [] };\n }\n\n const createdInternalIds: (bigint | null)[] = [];\n const resultInterpreter = new ResultInterpreter(driverConfig);\n\n try {\n await adapter.transaction(async (tx) => {\n for (const compiledMutation of mutationBatch) {\n const result = await tx.executeQuery(compiledMutation.query);\n\n // Extract internal ID for INSERT operations\n if (compiledMutation.op === \"create\") {\n // Only try to extract internal ID if driver supports RETURNING\n // If not supported, push null (expected case - system falls back to subqueries)\n if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {\n const internalId = resultInterpreter.getCreatedInternalId(result);\n createdInternalIds.push(internalId);\n } else {\n // Driver doesn't support RETURNING - this is expected, push null\n createdInternalIds.push(null);\n }\n } else if (\n (compiledMutation.op === \"update\" || compiledMutation.op === \"delete\") &&\n compiledMutation.expectedAffectedRows !== null\n ) {\n // Check affected rows for updates/deletes\n const affectedRows = resultInterpreter.getAffectedRows(result);\n\n if (affectedRows !== compiledMutation.expectedAffectedRows) {\n // Version conflict detected - the UPDATE/DELETE didn't affect the expected number of rows\n // This means either the row doesn't exist or the version has changed\n throw new Error(\n `Version conflict: expected ${compiledMutation.expectedAffectedRows} rows affected, but got ${affectedRows}`,\n );\n }\n }\n // \"check\" operations are handled below via expectedReturnedRows\n\n if (compiledMutation.expectedReturnedRows !== null) {\n // For SELECT queries (check operations), verify row count\n const returnedRowCount = resultInterpreter.getReturnedRowCount(result);\n\n if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) {\n // Version conflict detected - the SELECT didn't return the expected number of rows\n // This means either the row doesn't exist or the version has changed\n throw new Error(\n `Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`,\n );\n }\n }\n }\n });\n\n return { success: true, createdInternalIds };\n } catch (error) {\n // Transaction failed - could be version conflict or other constraint violation\n // Return success=false to indicate the UOW should be retried\n if (error instanceof Error && error.message.includes(\"Version conflict\")) {\n return { success: false };\n }\n\n // Other database errors should be thrown\n throw error;\n }\n}\n\nexport function createExecutor(\n adapter: SqlDriverAdapter,\n driverConfig: DriverConfig,\n dryRun?: boolean,\n): UOWExecutor<CompiledQuery, unknown> {\n return {\n async executeRetrievalPhase(retrievalBatch: CompiledQuery[]) {\n // In dryRun mode, skip execution and return empty results\n if (dryRun) {\n return retrievalBatch.map(() => []);\n }\n\n return executeRetrieval(adapter, retrievalBatch);\n },\n async executeMutationPhase(mutationBatch: CompiledMutation<CompiledQuery>[]) {\n // In dryRun mode, skip execution and return success with mock internal IDs\n if (dryRun) {\n return {\n success: true,\n createdInternalIds: mutationBatch.map(() => null),\n };\n }\n\n return executeMutation(adapter, driverConfig, mutationBatch);\n },\n };\n}\n"],"mappings":";;;AAUA,eAAsB,iBACpB,SACA,gBACoB;AACpB,KAAI,eAAe,WAAW,EAC5B,QAAO,EAAE;CAGX,MAAMA,mBAA8B,EAAE;AAEtC,OAAM,QAAQ,YAAY,OAAO,OAAO;AACtC,OAAK,MAAM,iBAAiB,gBAAgB;GAC1C,MAAM,SAAS,MAAM,GAAG,aAAa,cAAc;AACnD,oBAAiB,KAAK,OAAO,KAAK;;GAEpC;AAEF,QAAO;;AAGT,eAAsB,gBACpB,SACA,cACA,eACyB;AACzB,KAAI,cAAc,WAAW,EAC3B,QAAO;EAAE,SAAS;EAAM,oBAAoB,EAAE;EAAE;CAGlD,MAAMC,qBAAwC,EAAE;CAChD,MAAM,oBAAoB,IAAI,kBAAkB,aAAa;AAE7D,KAAI;AACF,QAAM,QAAQ,YAAY,OAAO,OAAO;AACtC,QAAK,MAAM,oBAAoB,eAAe;IAC5C,MAAM,SAAS,MAAM,GAAG,aAAa,iBAAiB,MAAM;AAG5D,QAAI,iBAAiB,OAAO,SAG1B,KAAI,aAAa,qBAAqB,aAAa,kBAAkB;KACnE,MAAM,aAAa,kBAAkB,qBAAqB,OAAO;AACjE,wBAAmB,KAAK,WAAW;UAGnC,oBAAmB,KAAK,KAAK;cAG9B,iBAAiB,OAAO,YAAY,iBAAiB,OAAO,aAC7D,iBAAiB,yBAAyB,MAC1C;KAEA,MAAM,eAAe,kBAAkB,gBAAgB,OAAO;AAE9D,SAAI,iBAAiB,iBAAiB,qBAGpC,OAAM,IAAI,MACR,8BAA8B,iBAAiB,qBAAqB,0BAA0B,eAC/F;;AAKL,QAAI,iBAAiB,yBAAyB,MAAM;KAElD,MAAM,mBAAmB,kBAAkB,oBAAoB,OAAO;AAEtE,SAAI,qBAAqB,OAAO,iBAAiB,qBAAqB,CAGpE,OAAM,IAAI,MACR,8BAA8B,iBAAiB,qBAAqB,0BAA0B,mBAC/F;;;IAIP;AAEF,SAAO;GAAE,SAAS;GAAM;GAAoB;UACrC,OAAO;AAGd,MAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,mBAAmB,CACtE,QAAO,EAAE,SAAS,OAAO;AAI3B,QAAM;;;AAIV,SAAgB,eACd,SACA,cACA,QACqC;AACrC,QAAO;EACL,MAAM,sBAAsB,gBAAiC;AAE3D,OAAI,OACF,QAAO,eAAe,UAAU,EAAE,CAAC;AAGrC,UAAO,iBAAiB,SAAS,eAAe;;EAElD,MAAM,qBAAqB,eAAkD;AAE3E,OAAI,OACF,QAAO;IACL,SAAS;IACT,oBAAoB,cAAc,UAAU,KAAK;IAClD;AAGH,UAAO,gBAAgB,SAAS,cAAc,cAAc;;EAE/D"}
1
+ {"version":3,"file":"generic-sql-uow-executor.js","names":["retrievalResults: unknown[]","createdInternalIds: (bigint | null)[]","outboxVersion: bigint | null","refMap: OutboxRefMap","serializedValues: Record<string, unknown>"],"sources":["../../../src/adapters/generic-sql/generic-sql-uow-executor.ts"],"sourcesContent":["import type {\n CompiledMutation,\n MutationResult,\n UOWExecutor,\n} from \"../../query/unit-of-work/unit-of-work\";\nimport type { CompiledQuery, Dialect } from \"../../sql-driver/sql-driver\";\nimport type { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { ResultInterpreter } from \"./result-interpreter\";\nimport { sql } from \"../../sql-driver/sql\";\nimport { createId } from \"../../id\";\nimport superjson from \"superjson\";\nimport { createColdKysely } from \"./migration/cold-kysely\";\nimport { SETTINGS_NAMESPACE, internalSchema } from \"../../fragments/internal-fragment.schema\";\nimport {\n type OutboxConfig,\n type OutboxRefLookup,\n type OutboxRefMap,\n encodeVersionstamp,\n parseOutboxVersionValue,\n versionstampToHex,\n} from \"../../outbox/outbox\";\nimport { buildOutboxPlan, finalizeOutboxPayload } from \"../../outbox/outbox-builder\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport { type SqlNamingStrategy } from \"../../naming/sql-naming\";\n\nexport interface ExecutorOptions {\n dryRun?: boolean;\n dialect: Dialect;\n outbox?: OutboxConfig;\n namingStrategy?: SqlNamingStrategy;\n}\n\nexport async function executeRetrieval(\n adapter: SqlDriverAdapter,\n retrievalBatch: CompiledQuery[],\n): Promise<unknown[]> {\n if (retrievalBatch.length === 0) {\n return [];\n }\n\n const retrievalResults: unknown[] = [];\n\n await adapter.transaction(async (tx) => {\n for (const compiledQuery of retrievalBatch) {\n const result = await tx.executeQuery(compiledQuery);\n retrievalResults.push(result.rows);\n }\n });\n\n return retrievalResults;\n}\n\nexport async function executeMutation(\n adapter: SqlDriverAdapter,\n driverConfig: DriverConfig,\n mutationBatch: CompiledMutation<CompiledQuery>[],\n options: ExecutorOptions,\n): Promise<MutationResult> {\n if (mutationBatch.length === 0) {\n return { success: true, createdInternalIds: [] };\n }\n\n const createdInternalIds: (bigint | null)[] = [];\n const resultInterpreter = new ResultInterpreter(driverConfig);\n const outboxEnabled = options.outbox?.enabled ?? false;\n const namingStrategy = options.namingStrategy ?? driverConfig.defaultNamingStrategy;\n\n const outboxOperations = outboxEnabled\n ? mutationBatch.flatMap((mutation) => (mutation.operation ? [mutation.operation] : []))\n : [];\n\n const outboxPlan = outboxOperations.length > 0 ? buildOutboxPlan(outboxOperations) : null;\n const shouldWriteOutbox = outboxEnabled && outboxPlan !== null && outboxPlan.drafts.length > 0;\n\n try {\n await adapter.transaction(async (tx) => {\n let outboxVersion: bigint | null = null;\n\n if (shouldWriteOutbox) {\n outboxVersion = await reserveOutboxVersion(tx, driverConfig, options.dialect);\n }\n\n for (const compiledMutation of mutationBatch) {\n const result = await tx.executeQuery(compiledMutation.query);\n\n // Extract internal ID for INSERT operations\n if (compiledMutation.op === \"create\") {\n // Only try to extract internal ID if driver supports RETURNING\n // If not supported, push null (expected case - system falls back to subqueries)\n if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {\n const internalId = resultInterpreter.getCreatedInternalId(result);\n createdInternalIds.push(internalId);\n } else {\n // Driver doesn't support RETURNING - this is expected, push null\n createdInternalIds.push(null);\n }\n } else if (\n (compiledMutation.op === \"update\" || compiledMutation.op === \"delete\") &&\n compiledMutation.expectedAffectedRows !== null\n ) {\n // Check affected rows for updates/deletes\n const affectedRows = resultInterpreter.getAffectedRows(result);\n\n if (affectedRows !== compiledMutation.expectedAffectedRows) {\n // Version conflict detected - the UPDATE/DELETE didn't affect the expected number of rows\n // This means either the row doesn't exist or the version has changed\n throw new Error(\n `Version conflict: expected ${compiledMutation.expectedAffectedRows} rows affected, but got ${affectedRows}`,\n );\n }\n }\n // \"check\" operations are handled below via expectedReturnedRows\n\n if (compiledMutation.expectedReturnedRows !== null) {\n // For SELECT queries (check operations), verify row count\n const returnedRowCount = resultInterpreter.getReturnedRowCount(result);\n\n if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) {\n // Version conflict detected - the SELECT didn't return the expected number of rows\n // This means either the row doesn't exist or the version has changed\n throw new Error(\n `Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`,\n );\n }\n }\n }\n\n if (shouldWriteOutbox && outboxPlan && outboxVersion !== null) {\n const uowId = mutationBatch[0]?.uowId;\n if (!uowId) {\n throw new Error(\"Outbox mutation batch is missing uowId.\");\n }\n\n const refMap = await resolveOutboxRefMap(\n tx,\n driverConfig,\n outboxPlan.lookups,\n namingStrategy,\n );\n const payload = finalizeOutboxPayload(outboxPlan, outboxVersion);\n const payloadSerialized = superjson.serialize(payload);\n const versionstamp = versionstampToHex(encodeVersionstamp(outboxVersion, 0));\n\n await insertOutboxRow(tx, driverConfig, {\n id: createId(),\n versionstamp,\n uowId,\n payload: payloadSerialized,\n refMap,\n });\n }\n });\n\n return { success: true, createdInternalIds };\n } catch (error) {\n // Transaction failed - could be version conflict or other constraint violation\n // Return success=false to indicate the UOW should be retried\n if (error instanceof Error && error.message.includes(\"Version conflict\")) {\n return { success: false };\n }\n\n const errorCode =\n typeof error === \"object\" && error !== null && \"code\" in error\n ? (error as { code?: unknown }).code\n : undefined;\n\n if (errorCode === \"40001\" || errorCode === \"40P01\") {\n return { success: false };\n }\n\n // Other database errors should be thrown\n throw error;\n }\n}\n\nexport function createExecutor(\n adapter: SqlDriverAdapter,\n driverConfig: DriverConfig,\n options: ExecutorOptions,\n): UOWExecutor<CompiledQuery, unknown> {\n const dryRun = options.dryRun ?? false;\n\n return {\n async executeRetrievalPhase(retrievalBatch: CompiledQuery[]) {\n // In dryRun mode, skip execution and return empty results\n if (dryRun) {\n return retrievalBatch.map(() => []);\n }\n\n return executeRetrieval(adapter, retrievalBatch);\n },\n async executeMutationPhase(mutationBatch: CompiledMutation<CompiledQuery>[]) {\n // In dryRun mode, skip execution and return success with mock internal IDs\n if (dryRun) {\n return {\n success: true,\n createdInternalIds: mutationBatch.map(() => null),\n };\n }\n\n return executeMutation(adapter, driverConfig, mutationBatch, options);\n },\n };\n}\n\nasync function reserveOutboxVersion(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n dialect: Dialect,\n): Promise<bigint> {\n const key = `${SETTINGS_NAMESPACE}.outbox_version`;\n const id = createId();\n\n switch (driverConfig.outboxVersionstampStrategy) {\n case \"insert-on-conflict-returning\": {\n const query =\n driverConfig.databaseType === \"postgresql\"\n ? sql`\n insert into fragno_db_settings (id, key, value)\n values (${id}, ${key}, '0')\n on conflict (key) do update\n set value = (fragno_db_settings.value::bigint + 1)::text\n returning value;\n `\n : sql`\n insert into fragno_db_settings (id, key, value)\n values (${id}, ${key}, '0')\n on conflict (key) do update\n set value = cast(fragno_db_settings.value as integer) + 1\n returning value;\n `;\n\n const result = await tx.executeQuery(query.compile(dialect));\n const value = result.rows[0]?.[\"value\"];\n return parseOutboxVersionValue(value);\n }\n case \"update-returning\": {\n const query =\n driverConfig.databaseType === \"postgresql\"\n ? sql`\n update fragno_db_settings\n set value = (fragno_db_settings.value::bigint + 1)::text\n where key = ${key}\n returning value;\n `\n : sql`\n update fragno_db_settings\n set value = cast(fragno_db_settings.value as integer) + 1\n where key = ${key}\n returning value;\n `;\n\n const result = await tx.executeQuery(query.compile(dialect));\n const value = result.rows[0]?.[\"value\"];\n if (value === undefined) {\n throw new Error(\"Outbox version row was not found for update-returning strategy.\");\n }\n return parseOutboxVersionValue(value);\n }\n case \"insert-on-duplicate-last-insert-id\": {\n const insertQuery = sql`\n insert into fragno_db_settings (id, key, value)\n values (${id}, ${key}, LAST_INSERT_ID(0))\n on duplicate key update value = LAST_INSERT_ID(cast(value as unsigned) + 1);\n `;\n\n await tx.executeQuery(insertQuery.compile(dialect));\n\n const selectQuery = sql`select LAST_INSERT_ID() as value;`;\n const result = await tx.executeQuery(selectQuery.compile(dialect));\n const value = result.rows[0]?.[\"value\"];\n return parseOutboxVersionValue(value);\n }\n }\n}\n\nasync function resolveOutboxRefMap(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n lookups: OutboxRefLookup[],\n namingStrategy: SqlNamingStrategy,\n): Promise<OutboxRefMap | undefined> {\n if (lookups.length === 0) {\n return undefined;\n }\n\n const refMap: OutboxRefMap = {};\n const db = createColdKysely(driverConfig.databaseType);\n\n for (const lookup of lookups) {\n const namespace = lookup.namespace ?? null;\n const logicalTable = lookup.table.name;\n const schemaName =\n namingStrategy.namespaceScope === \"schema\" && namespace && namespace.length > 0\n ? namingStrategy.namespaceToSchema(namespace)\n : null;\n const scopedDb = schemaName ? db.withSchema(schemaName) : db;\n const tableName = namingStrategy.tableName(logicalTable, namespace);\n const internalColumn = namingStrategy.columnName(\n lookup.table.getInternalIdColumn().name,\n logicalTable,\n );\n const externalColumn = namingStrategy.columnName(lookup.table.getIdColumn().name, logicalTable);\n\n const query = scopedDb\n .selectFrom(tableName)\n .select(externalColumn)\n .where(internalColumn, \"=\", lookup.internalId)\n .compile();\n\n const result = await tx.executeQuery(query);\n const row = result.rows[0] as Record<string, unknown> | undefined;\n const externalId = row?.[externalColumn];\n\n if (typeof externalId !== \"string\") {\n throw new Error(\n `Failed to resolve outbox reference for ${tableName}.${internalColumn}=${String(lookup.internalId)}`,\n );\n }\n\n refMap[lookup.key] = externalId;\n }\n\n return Object.keys(refMap).length > 0 ? refMap : undefined;\n}\n\nasync function insertOutboxRow(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n options: {\n id: string;\n versionstamp: string;\n uowId: string;\n payload: { json: unknown; meta?: Record<string, unknown> };\n refMap?: OutboxRefMap;\n },\n): Promise<void> {\n const { id, versionstamp, uowId, payload, refMap } = options;\n const refMapValue = refMap ?? null;\n const serializer = createSQLSerializer(driverConfig);\n const outboxTable = internalSchema.tables.fragno_db_outbox;\n const values = { id, versionstamp, uowId, payload, refMap: refMapValue };\n const serializedValues: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(values)) {\n const col = outboxTable.columns[key];\n if (!col) {\n serializedValues[key] = value;\n continue;\n }\n serializedValues[col.name] = serializer.serialize(value, col);\n }\n const db = createColdKysely(driverConfig.databaseType);\n\n const query = db.insertInto(\"fragno_db_outbox\").values(serializedValues).compile();\n\n await tx.executeQuery(query);\n}\n"],"mappings":"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"}
@@ -40,18 +40,37 @@ var MySQLSQLGenerator = class extends SQLGenerator {
40
40
  /**
41
41
  * MySQL update-column uses modifyColumn which requires the full column definition.
42
42
  */
43
- compileUpdateColumn(tableName, operation) {
43
+ compileUpdateColumn(tableName, logicalTableName, operation, resolver) {
44
44
  const col = operation.value;
45
45
  if (col.role === "external-id" || col.role === "internal-id") throw new Error(errors.IdColumnUpdate);
46
46
  if (!isUpdated(operation)) return [];
47
- return this.db.schema.alterTable(tableName).modifyColumn(operation.name, sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b)).compile();
47
+ return this.getSchemaBuilder(resolver).alterTable(tableName).modifyColumn(this.getColumnName(operation.name, logicalTableName, resolver), sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b)).compile();
48
48
  }
49
49
  /**
50
50
  * MySQL doesn't support IF EXISTS for dropping constraints.
51
51
  */
52
- compileDropForeignKey(operation, mapper) {
53
- const { table, name } = operation;
54
- return this.db.schema.alterTable(this.getTableName(table, mapper)).dropConstraint(name).compile();
52
+ compileDropForeignKey(operation, resolver) {
53
+ const { table, name, referencedTable } = operation;
54
+ return this.getSchemaBuilder(resolver).alterTable(this.getTableName(table, resolver)).dropConstraint(this.getForeignKeyName(name, table, referencedTable, resolver)).compile();
55
+ }
56
+ /**
57
+ * MySQL: add a named primary key constraint for the internal ID column to align naming.
58
+ */
59
+ compileCreateTable(operation, resolver) {
60
+ const compiled = super.compileCreateTable(operation, resolver);
61
+ const tableName = this.getTableName(operation.name, resolver);
62
+ const internalIdColumn = operation.columns.find((col) => col.role === "internal-id");
63
+ if (!internalIdColumn) return compiled;
64
+ const pkColumn = this.getColumnName(internalIdColumn.name, operation.name, resolver);
65
+ const pkName = `${tableName}__${pkColumn.replace(/^_+/, "")}`;
66
+ const escapedPkColumn = pkColumn.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
67
+ const columnRegex = new RegExp("`" + escapedPkColumn + "`([^,]*?)\\bprimary key\\b", "i");
68
+ let sqlText = compiled.sql.replace(columnRegex, "`" + pkColumn + "`$1");
69
+ sqlText = sqlText.replace(/\)\s*$/, ", constraint `" + pkName + "` primary key (`" + pkColumn + "`))");
70
+ return {
71
+ ...compiled,
72
+ sql: sqlText
73
+ };
55
74
  }
56
75
  };
57
76
 
@@ -1 +1 @@
1
- {"version":3,"file":"mysql.js","names":[],"sources":["../../../../../src/adapters/generic-sql/migration/dialect/mysql.ts"],"sourcesContent":["import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from \"kysely\";\nimport type {\n ColumnInfo,\n ColumnOperation,\n MigrationOperation,\n} from \"../../../../migration-engine/shared\";\nimport { isUpdated } from \"../../../../migration-engine/shared\";\nimport type { TableNameMapper } from \"../../../shared/table-name-mapper\";\nimport { SQLGenerator } from \"../sql-generator\";\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n} as const;\n\n/**\n * MySQL-specific SQL generator.\n * Uses modifyColumn for updates and wraps migrations with FK checks disabled.\n */\nexport class MySQLSQLGenerator extends SQLGenerator {\n /**\n * MySQL preprocessing: wrap operations with SET FOREIGN_KEY_CHECKS = 0/1.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n if (operations.length === 0) {\n return operations;\n }\n\n return [\n { type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 0\" },\n ...operations,\n { type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 1\" },\n ];\n }\n\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder.autoIncrement();\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n // MySQL doesn't support default values for TEXT columns\n if (column.type === \"string\") {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * MySQL update-column uses modifyColumn which requires the full column definition.\n */\n protected override compileUpdateColumn(\n tableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n\n if (!isUpdated(operation)) {\n return [];\n }\n\n // MySQL: Use modifyColumn which requires the full column definition\n return this.db.schema\n .alterTable(tableName)\n .modifyColumn(operation.name, sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b))\n .compile();\n }\n\n /**\n * MySQL doesn't support IF EXISTS for dropping constraints.\n */\n protected override compileDropForeignKey(\n operation: Extract<MigrationOperation, { type: \"drop-foreign-key\" }>,\n mapper?: TableNameMapper,\n ): CompiledQuery {\n const { table, name } = operation;\n return this.db.schema\n .alterTable(this.getTableName(table, mapper))\n .dropConstraint(name)\n .compile();\n }\n}\n"],"mappings":";;;;;AAUA,MAAM,SAAS,EACb,gBACE,mHACH;;;;;AAMD,IAAa,oBAAb,cAAuC,aAAa;;;;CAIlD,AAAS,WAAW,YAAwD;AAC1E,MAAI,WAAW,WAAW,EACxB,QAAO;AAGT,SAAO;GACL;IAAE,MAAM;IAAU,KAAK;IAA8B;GACrD,GAAG;GACH;IAAE,MAAM;IAAU,KAAK;IAA8B;GACtD;;CAGH,AAAS,mBAAmB,SAA2D;AACrF,SAAO,QAAQ,eAAe;;CAGhC,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAIF,MAAI,OAAO,SAAS,SAClB;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,oBACjB,WACA,WACiC;EACjC,MAAM,MAAM,UAAU;AAEtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAGxC,MAAI,CAAC,UAAU,UAAU,CACvB,QAAO,EAAE;AAIX,SAAO,KAAK,GAAG,OACZ,WAAW,UAAU,CACrB,aAAa,UAAU,MAAM,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,GAAG,MAAM,KAAK,YAAY,KAAK,EAAE,CAAC,CAC3F,SAAS;;;;;CAMd,AAAmB,sBACjB,WACA,QACe;EACf,MAAM,EAAE,OAAO,SAAS;AACxB,SAAO,KAAK,GAAG,OACZ,WAAW,KAAK,aAAa,OAAO,OAAO,CAAC,CAC5C,eAAe,KAAK,CACpB,SAAS"}
1
+ {"version":3,"file":"mysql.js","names":[],"sources":["../../../../../src/adapters/generic-sql/migration/dialect/mysql.ts"],"sourcesContent":["import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from \"kysely\";\nimport type {\n ColumnInfo,\n ColumnOperation,\n MigrationOperation,\n} from \"../../../../migration-engine/shared\";\nimport { isUpdated } from \"../../../../migration-engine/shared\";\nimport type { NamingResolver } from \"../../../../naming/sql-naming\";\nimport { SQLGenerator } from \"../sql-generator\";\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n} as const;\n\n/**\n * MySQL-specific SQL generator.\n * Uses modifyColumn for updates and wraps migrations with FK checks disabled.\n */\nexport class MySQLSQLGenerator extends SQLGenerator {\n /**\n * MySQL preprocessing: wrap operations with SET FOREIGN_KEY_CHECKS = 0/1.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n if (operations.length === 0) {\n return operations;\n }\n\n return [\n { type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 0\" },\n ...operations,\n { type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 1\" },\n ];\n }\n\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder.autoIncrement();\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n // MySQL doesn't support default values for TEXT columns\n if (column.type === \"string\") {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * MySQL update-column uses modifyColumn which requires the full column definition.\n */\n protected override compileUpdateColumn(\n tableName: string,\n logicalTableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n\n if (!isUpdated(operation)) {\n return [];\n }\n\n // MySQL: Use modifyColumn which requires the full column definition\n return this.getSchemaBuilder(resolver)\n .alterTable(tableName)\n .modifyColumn(\n this.getColumnName(operation.name, logicalTableName, resolver),\n sql.raw(this.getDBType(col)),\n (b) => this.buildColumn(col, b),\n )\n .compile();\n }\n\n /**\n * MySQL doesn't support IF EXISTS for dropping constraints.\n */\n protected override compileDropForeignKey(\n operation: Extract<MigrationOperation, { type: \"drop-foreign-key\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery {\n const { table, name, referencedTable } = operation;\n return this.getSchemaBuilder(resolver)\n .alterTable(this.getTableName(table, resolver))\n .dropConstraint(this.getForeignKeyName(name, table, referencedTable, resolver))\n .compile();\n }\n\n /**\n * MySQL: add a named primary key constraint for the internal ID column to align naming.\n */\n protected override compileCreateTable(\n operation: Extract<MigrationOperation, { type: \"create-table\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery {\n const compiled = super.compileCreateTable(operation, resolver);\n const tableName = this.getTableName(operation.name, resolver);\n const internalIdColumn = operation.columns.find((col) => col.role === \"internal-id\");\n\n if (!internalIdColumn) {\n return compiled;\n }\n\n const pkColumn = this.getColumnName(internalIdColumn.name, operation.name, resolver);\n const pkName = `${tableName}__${pkColumn.replace(/^_+/, \"\")}`;\n const escapedPkColumn = pkColumn.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const columnRegex = new RegExp(\"`\" + escapedPkColumn + \"`([^,]*?)\\\\bprimary key\\\\b\", \"i\");\n\n let sqlText = compiled.sql.replace(columnRegex, \"`\" + pkColumn + \"`$1\");\n sqlText = sqlText.replace(\n /\\)\\s*$/,\n \", constraint `\" + pkName + \"` primary key (`\" + pkColumn + \"`))\",\n );\n\n return {\n ...compiled,\n sql: sqlText,\n };\n }\n}\n"],"mappings":";;;;;AAUA,MAAM,SAAS,EACb,gBACE,mHACH;;;;;AAMD,IAAa,oBAAb,cAAuC,aAAa;;;;CAIlD,AAAS,WAAW,YAAwD;AAC1E,MAAI,WAAW,WAAW,EACxB,QAAO;AAGT,SAAO;GACL;IAAE,MAAM;IAAU,KAAK;IAA8B;GACrD,GAAG;GACH;IAAE,MAAM;IAAU,KAAK;IAA8B;GACtD;;CAGH,AAAS,mBAAmB,SAA2D;AACrF,SAAO,QAAQ,eAAe;;CAGhC,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAIF,MAAI,OAAO,SAAS,SAClB;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,oBACjB,WACA,kBACA,WACA,UACiC;EACjC,MAAM,MAAM,UAAU;AAEtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAGxC,MAAI,CAAC,UAAU,UAAU,CACvB,QAAO,EAAE;AAIX,SAAO,KAAK,iBAAiB,SAAS,CACnC,WAAW,UAAU,CACrB,aACC,KAAK,cAAc,UAAU,MAAM,kBAAkB,SAAS,EAC9D,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,GAC3B,MAAM,KAAK,YAAY,KAAK,EAAE,CAChC,CACA,SAAS;;;;;CAMd,AAAmB,sBACjB,WACA,UACe;EACf,MAAM,EAAE,OAAO,MAAM,oBAAoB;AACzC,SAAO,KAAK,iBAAiB,SAAS,CACnC,WAAW,KAAK,aAAa,OAAO,SAAS,CAAC,CAC9C,eAAe,KAAK,kBAAkB,MAAM,OAAO,iBAAiB,SAAS,CAAC,CAC9E,SAAS;;;;;CAMd,AAAmB,mBACjB,WACA,UACe;EACf,MAAM,WAAW,MAAM,mBAAmB,WAAW,SAAS;EAC9D,MAAM,YAAY,KAAK,aAAa,UAAU,MAAM,SAAS;EAC7D,MAAM,mBAAmB,UAAU,QAAQ,MAAM,QAAQ,IAAI,SAAS,cAAc;AAEpF,MAAI,CAAC,iBACH,QAAO;EAGT,MAAM,WAAW,KAAK,cAAc,iBAAiB,MAAM,UAAU,MAAM,SAAS;EACpF,MAAM,SAAS,GAAG,UAAU,IAAI,SAAS,QAAQ,OAAO,GAAG;EAC3D,MAAM,kBAAkB,SAAS,QAAQ,uBAAuB,OAAO;EACvE,MAAM,cAAc,IAAI,OAAO,MAAM,kBAAkB,8BAA8B,IAAI;EAEzF,IAAI,UAAU,SAAS,IAAI,QAAQ,aAAa,MAAM,WAAW,MAAM;AACvE,YAAU,QAAQ,QAChB,UACA,mBAAmB,SAAS,qBAAqB,WAAW,MAC7D;AAED,SAAO;GACL,GAAG;GACH,KAAK;GACN"}
@@ -32,20 +32,21 @@ var PostgresSQLGenerator = class extends SQLGenerator {
32
32
  /**
33
33
  * PostgreSQL update-column uses USING clause for type conversion.
34
34
  */
35
- compileUpdateColumn(tableName, operation) {
35
+ compileUpdateColumn(tableName, logicalTableName, operation, resolver) {
36
36
  const col = operation.value;
37
37
  if (col.role === "external-id" || col.role === "internal-id") throw new Error(errors.IdColumnUpdate);
38
38
  if (!isUpdated(operation)) return [];
39
39
  const queries = [];
40
- const alter = () => this.db.schema.alterTable(tableName);
40
+ const alter = () => this.getSchemaBuilder(resolver).alterTable(tableName);
41
+ const physicalColumnName = this.getColumnName(operation.name, logicalTableName, resolver);
41
42
  if (operation.updateDataType) {
42
43
  const dbType = sql.raw(this.getDBType(col));
43
- queries.push(sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(operation.name)} TYPE ${dbType} USING (${sql.ref(operation.name)}::${dbType})`.compile(this.db));
44
+ queries.push(sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(physicalColumnName)} TYPE ${dbType} USING (${sql.ref(physicalColumnName)}::${dbType})`.compile(this.db));
44
45
  }
45
- if (operation.updateNullable) queries.push(alter().alterColumn(operation.name, (build) => col.isNullable ? build.dropNotNull() : build.setNotNull()).compile());
46
+ if (operation.updateNullable) queries.push(alter().alterColumn(physicalColumnName, (build) => col.isNullable ? build.dropNotNull() : build.setNotNull()).compile());
46
47
  if (operation.updateDefault) {
47
48
  const defaultValue = this.getDefaultValue(col);
48
- queries.push(alter().alterColumn(operation.name, (build) => {
49
+ queries.push(alter().alterColumn(physicalColumnName, (build) => {
49
50
  if (!defaultValue) return build.dropDefault();
50
51
  return build.setDefault(defaultValue);
51
52
  }).compile());
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.js","names":["queries: CompiledQuery[]"],"sources":["../../../../../src/adapters/generic-sql/migration/dialect/postgres.ts"],"sourcesContent":["import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from \"kysely\";\nimport type {\n ColumnInfo,\n ColumnOperation,\n MigrationOperation,\n} from \"../../../../migration-engine/shared\";\nimport { isUpdated } from \"../../../../migration-engine/shared\";\nimport { SQLGenerator } from \"../sql-generator\";\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n} as const;\n\n/**\n * PostgreSQL-specific SQL generator.\n * Uses USING clauses for type conversion and SERIAL for auto-increment.\n */\nexport class PostgresSQLGenerator extends SQLGenerator {\n /**\n * PostgreSQL doesn't need preprocessing - it handles FKs normally.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n return operations;\n }\n\n /**\n * PostgreSQL uses SERIAL/BIGSERIAL types for auto-increment,\n * which is already handled in PostgreSQLTypeMapper. No builder modification needed.\n */\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder;\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * PostgreSQL update-column uses USING clause for type conversion.\n */\n protected override compileUpdateColumn(\n tableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n\n if (!isUpdated(operation)) {\n return [];\n }\n\n const queries: CompiledQuery[] = [];\n const alter = () => this.db.schema.alterTable(tableName);\n\n // PostgreSQL: Use explicit USING clause for type conversion\n if (operation.updateDataType) {\n const dbType = sql.raw(this.getDBType(col));\n queries.push(\n sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(operation.name)} TYPE ${dbType} USING (${sql.ref(operation.name)}::${dbType})`.compile(\n this.db,\n ),\n );\n }\n\n if (operation.updateNullable) {\n queries.push(\n alter()\n .alterColumn(operation.name, (build) =>\n col.isNullable ? build.dropNotNull() : build.setNotNull(),\n )\n .compile(),\n );\n }\n\n if (operation.updateDefault) {\n const defaultValue = this.getDefaultValue(col);\n queries.push(\n alter()\n .alterColumn(operation.name, (build) => {\n if (!defaultValue) {\n return build.dropDefault();\n }\n return build.setDefault(defaultValue);\n })\n .compile(),\n );\n }\n\n return queries;\n }\n}\n"],"mappings":";;;;;AASA,MAAM,SAAS,EACb,gBACE,mHACH;;;;;AAMD,IAAa,uBAAb,cAA0C,aAAa;;;;CAIrD,AAAS,WAAW,YAAwD;AAC1E,SAAO;;;;;;CAOT,AAAS,mBAAmB,SAA2D;AACrF,SAAO;;CAGT,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,oBACjB,WACA,WACiC;EACjC,MAAM,MAAM,UAAU;AAEtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAGxC,MAAI,CAAC,UAAU,UAAU,CACvB,QAAO,EAAE;EAGX,MAAMA,UAA2B,EAAE;EACnC,MAAM,cAAc,KAAK,GAAG,OAAO,WAAW,UAAU;AAGxD,MAAI,UAAU,gBAAgB;GAC5B,MAAM,SAAS,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAC3C,WAAQ,KACN,GAAG,eAAe,IAAI,IAAI,UAAU,CAAC,gBAAgB,IAAI,IAAI,UAAU,KAAK,CAAC,QAAQ,OAAO,UAAU,IAAI,IAAI,UAAU,KAAK,CAAC,IAAI,OAAO,GAAG,QAC1I,KAAK,GACN,CACF;;AAGH,MAAI,UAAU,eACZ,SAAQ,KACN,OAAO,CACJ,YAAY,UAAU,OAAO,UAC5B,IAAI,aAAa,MAAM,aAAa,GAAG,MAAM,YAAY,CAC1D,CACA,SAAS,CACb;AAGH,MAAI,UAAU,eAAe;GAC3B,MAAM,eAAe,KAAK,gBAAgB,IAAI;AAC9C,WAAQ,KACN,OAAO,CACJ,YAAY,UAAU,OAAO,UAAU;AACtC,QAAI,CAAC,aACH,QAAO,MAAM,aAAa;AAE5B,WAAO,MAAM,WAAW,aAAa;KACrC,CACD,SAAS,CACb;;AAGH,SAAO"}
1
+ {"version":3,"file":"postgres.js","names":["queries: CompiledQuery[]"],"sources":["../../../../../src/adapters/generic-sql/migration/dialect/postgres.ts"],"sourcesContent":["import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from \"kysely\";\nimport type {\n ColumnInfo,\n ColumnOperation,\n MigrationOperation,\n} from \"../../../../migration-engine/shared\";\nimport { isUpdated } from \"../../../../migration-engine/shared\";\nimport { SQLGenerator } from \"../sql-generator\";\nimport type { NamingResolver } from \"../../../../naming/sql-naming\";\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n} as const;\n\n/**\n * PostgreSQL-specific SQL generator.\n * Uses USING clauses for type conversion and SERIAL for auto-increment.\n */\nexport class PostgresSQLGenerator extends SQLGenerator {\n /**\n * PostgreSQL doesn't need preprocessing - it handles FKs normally.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n return operations;\n }\n\n /**\n * PostgreSQL uses SERIAL/BIGSERIAL types for auto-increment,\n * which is already handled in PostgreSQLTypeMapper. No builder modification needed.\n */\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder;\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * PostgreSQL update-column uses USING clause for type conversion.\n */\n protected override compileUpdateColumn(\n tableName: string,\n logicalTableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n\n if (!isUpdated(operation)) {\n return [];\n }\n\n const queries: CompiledQuery[] = [];\n const alter = () => this.getSchemaBuilder(resolver).alterTable(tableName);\n const physicalColumnName = this.getColumnName(operation.name, logicalTableName, resolver);\n\n // PostgreSQL: Use explicit USING clause for type conversion\n if (operation.updateDataType) {\n const dbType = sql.raw(this.getDBType(col));\n queries.push(\n sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(physicalColumnName)} TYPE ${dbType} USING (${sql.ref(physicalColumnName)}::${dbType})`.compile(\n this.db,\n ),\n );\n }\n\n if (operation.updateNullable) {\n queries.push(\n alter()\n .alterColumn(physicalColumnName, (build) =>\n col.isNullable ? build.dropNotNull() : build.setNotNull(),\n )\n .compile(),\n );\n }\n\n if (operation.updateDefault) {\n const defaultValue = this.getDefaultValue(col);\n queries.push(\n alter()\n .alterColumn(physicalColumnName, (build) => {\n if (!defaultValue) {\n return build.dropDefault();\n }\n return build.setDefault(defaultValue);\n })\n .compile(),\n );\n }\n\n return queries;\n }\n}\n"],"mappings":";;;;;AAUA,MAAM,SAAS,EACb,gBACE,mHACH;;;;;AAMD,IAAa,uBAAb,cAA0C,aAAa;;;;CAIrD,AAAS,WAAW,YAAwD;AAC1E,SAAO;;;;;;CAOT,AAAS,mBAAmB,SAA2D;AACrF,SAAO;;CAGT,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,oBACjB,WACA,kBACA,WACA,UACiC;EACjC,MAAM,MAAM,UAAU;AAEtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAGxC,MAAI,CAAC,UAAU,UAAU,CACvB,QAAO,EAAE;EAGX,MAAMA,UAA2B,EAAE;EACnC,MAAM,cAAc,KAAK,iBAAiB,SAAS,CAAC,WAAW,UAAU;EACzE,MAAM,qBAAqB,KAAK,cAAc,UAAU,MAAM,kBAAkB,SAAS;AAGzF,MAAI,UAAU,gBAAgB;GAC5B,MAAM,SAAS,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAC3C,WAAQ,KACN,GAAG,eAAe,IAAI,IAAI,UAAU,CAAC,gBAAgB,IAAI,IAAI,mBAAmB,CAAC,QAAQ,OAAO,UAAU,IAAI,IAAI,mBAAmB,CAAC,IAAI,OAAO,GAAG,QAClJ,KAAK,GACN,CACF;;AAGH,MAAI,UAAU,eACZ,SAAQ,KACN,OAAO,CACJ,YAAY,qBAAqB,UAChC,IAAI,aAAa,MAAM,aAAa,GAAG,MAAM,YAAY,CAC1D,CACA,SAAS,CACb;AAGH,MAAI,UAAU,eAAe;GAC3B,MAAM,eAAe,KAAK,gBAAgB,IAAI;AAC9C,WAAQ,KACN,OAAO,CACJ,YAAY,qBAAqB,UAAU;AAC1C,QAAI,CAAC,aACH,QAAO,MAAM,aAAa;AAE5B,WAAO,MAAM,WAAW,aAAa;KACrC,CACD,SAAS,CACb;;AAGH,SAAO"}
@@ -55,36 +55,47 @@ var SQLiteSQLGenerator = class extends SQLGenerator {
55
55
  const value = column.default;
56
56
  if (!value) return;
57
57
  if ("value" in value && value.value !== void 0) return sql.lit(value.value);
58
- if ("dbSpecial" in value && value.dbSpecial === "now") return sql`CURRENT_TIMESTAMP`;
58
+ if ("dbSpecial" in value && value.dbSpecial === "now") {
59
+ if (this.typeMapper.getDatabaseType(column) === "integer" && (column.type === "timestamp" || column.type === "date")) return sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;
60
+ return sql`CURRENT_TIMESTAMP`;
61
+ }
59
62
  if ("runtime" in value) return;
60
63
  }
61
64
  /**
62
65
  * Override create-table to add inline foreign keys from metadata.
63
66
  */
64
- compileCreateTable(operation, mapper) {
65
- const tableName = this.getTableName(operation.name, mapper);
66
- let builder = this.db.schema.createTable(tableName);
67
- for (const col of operation.columns) builder = builder.addColumn(col.name, sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b));
67
+ compileCreateTable(operation, resolver) {
68
+ const tableName = this.getTableName(operation.name, resolver);
69
+ let builder = this.getSchemaBuilder(resolver).createTable(tableName);
70
+ for (const col of operation.columns) {
71
+ const columnName = this.getColumnName(col.name, operation.name, resolver);
72
+ builder = builder.addColumn(columnName, sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b));
73
+ }
68
74
  const metadata = operation.metadata;
69
- if (metadata?.inlineForeignKeys) for (const fk of metadata.inlineForeignKeys) builder = builder.addForeignKeyConstraint(fk.name, fk.columns, this.getTableName(fk.referencedTable, mapper), fk.referencedColumns, (cb) => cb.onUpdate("restrict").onDelete("restrict"));
70
- return builder.compile();
75
+ if (metadata?.inlineForeignKeys) for (const fk of metadata.inlineForeignKeys) builder = builder.addForeignKeyConstraint(this.getForeignKeyName(fk.name, operation.name, fk.referencedTable, resolver), fk.columns.map((columnName) => this.getColumnName(columnName, operation.name, resolver)), this.getTableName(fk.referencedTable, resolver), fk.referencedColumns.map((columnName) => this.getColumnName(columnName, fk.referencedTable, resolver)), (cb) => cb.onUpdate("restrict").onDelete("restrict"));
76
+ const compiled = builder.compile();
77
+ const sqlText = compiled.sql.replace(/\bconstraint\s+"[^"]+"\s+foreign key\b/gi, "foreign key");
78
+ return {
79
+ ...compiled,
80
+ sql: sqlText
81
+ };
71
82
  }
72
83
  /**
73
84
  * SQLite doesn't support adding foreign keys to existing tables.
74
85
  */
75
- compileAddForeignKey(_operation, _mapper) {
86
+ compileAddForeignKey(_operation, _resolver) {
76
87
  throw new Error(errors.SQLiteUpdateForeignKeys);
77
88
  }
78
89
  /**
79
90
  * SQLite doesn't support dropping foreign keys.
80
91
  */
81
- compileDropForeignKey(_operation, _mapper) {
92
+ compileDropForeignKey(_operation, _resolver) {
82
93
  throw new Error(errors.SQLiteUpdateForeignKeys);
83
94
  }
84
95
  /**
85
96
  * SQLite doesn't support updating columns.
86
97
  */
87
- compileUpdateColumn(_tableName, operation) {
98
+ compileUpdateColumn(_tableName, _logicalTableName, operation, _resolver) {
88
99
  const col = operation.value;
89
100
  if (col.role === "external-id" || col.role === "internal-id") throw new Error(errors.IdColumnUpdate);
90
101
  throw new Error(errors.SQLiteUpdateColumn);
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.js","names":["result: MigrationOperation[]","metadata: SqliteCreateTableMetadata","builder: CreateTableBuilderAny"],"sources":["../../../../../src/adapters/generic-sql/migration/dialect/sqlite.ts"],"sourcesContent":["import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from \"kysely\";\nimport type {\n ColumnInfo,\n ColumnOperation,\n ForeignKeyInfo,\n MigrationOperation,\n} from \"../../../../migration-engine/shared\";\nimport type { TableNameMapper } from \"../../../shared/table-name-mapper\";\nimport { SQLGenerator } from \"../sql-generator\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype CreateTableBuilderAny = any;\n\n/**\n * Metadata attached to create-table operations for inline foreign keys.\n */\ninterface SqliteCreateTableMetadata {\n [key: string]: unknown;\n inlineForeignKeys?: ForeignKeyInfo[];\n}\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n SQLiteUpdateColumn: \"SQLite doesn't support updating columns. Recreate the table instead.\",\n SQLiteUpdateForeignKeys:\n \"SQLite doesn't support modifying foreign keys directly. Use `recreate-table` instead.\",\n} as const;\n\n/**\n * SQLite-specific SQL generator.\n * Handles SQLite's limitations around foreign keys and column updates.\n */\nexport class SQLiteSQLGenerator extends SQLGenerator {\n /**\n * SQLite preprocessing: merge add-foreign-key operations into create-table operations\n * when both exist in the same batch, and add pragma for deferred foreign keys.\n *\n * SQLite requires foreign keys to be defined at table creation time.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n if (operations.length === 0) {\n return operations;\n }\n\n const result: MigrationOperation[] = [];\n const createTableIndices = new Map<string, number>();\n const foreignKeysByTable = new Map<\n string,\n Extract<MigrationOperation, { type: \"add-foreign-key\" }>[]\n >();\n\n // First pass: identify create-table operations and collect foreign keys\n for (const op of operations) {\n if (op.type === \"create-table\") {\n createTableIndices.set(op.name, result.length);\n result.push(op);\n } else if (op.type === \"add-foreign-key\") {\n if (!foreignKeysByTable.has(op.table)) {\n foreignKeysByTable.set(op.table, []);\n }\n foreignKeysByTable.get(op.table)!.push(op);\n } else {\n result.push(op);\n }\n }\n\n // Second pass: attach foreign keys as metadata to create-table ops\n for (const [tableName, fkOps] of foreignKeysByTable.entries()) {\n const createTableIdx = createTableIndices.get(tableName);\n\n if (createTableIdx !== undefined) {\n const createOp = result[createTableIdx];\n if (createOp.type === \"create-table\") {\n const metadata: SqliteCreateTableMetadata = {\n inlineForeignKeys: fkOps.map((fkOp) => fkOp.value),\n };\n result[createTableIdx] = {\n ...createOp,\n metadata,\n };\n }\n } else {\n // Table already exists - keep add-foreign-key operations (will throw error during compile)\n result.push(...fkOps);\n }\n }\n\n // Add pragma at the beginning for deferred foreign key checking\n return [{ type: \"custom\", sql: \"PRAGMA defer_foreign_keys = ON\" }, ...result];\n }\n\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder.autoIncrement();\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * Override create-table to add inline foreign keys from metadata.\n */\n protected override compileCreateTable(\n operation: Extract<MigrationOperation, { type: \"create-table\" }>,\n mapper?: TableNameMapper,\n ): CompiledQuery {\n const tableName = this.getTableName(operation.name, mapper);\n let builder: CreateTableBuilderAny = this.db.schema.createTable(tableName);\n\n // Add columns\n for (const col of operation.columns) {\n builder = builder.addColumn(\n col.name,\n sql.raw(this.getDBType(col)),\n (b: ColumnDefinitionBuilder) => this.buildColumn(col, b),\n );\n }\n\n // Add inline foreign keys from metadata\n const metadata = operation.metadata as SqliteCreateTableMetadata | undefined;\n if (metadata?.inlineForeignKeys) {\n for (const fk of metadata.inlineForeignKeys) {\n builder = builder.addForeignKeyConstraint(\n fk.name,\n fk.columns,\n this.getTableName(fk.referencedTable, mapper),\n fk.referencedColumns,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (cb: any) => cb.onUpdate(\"restrict\").onDelete(\"restrict\"),\n );\n }\n }\n\n return builder.compile();\n }\n\n /**\n * SQLite doesn't support adding foreign keys to existing tables.\n */\n protected override compileAddForeignKey(\n _operation: Extract<MigrationOperation, { type: \"add-foreign-key\" }>,\n _mapper?: TableNameMapper,\n ): CompiledQuery {\n throw new Error(errors.SQLiteUpdateForeignKeys);\n }\n\n /**\n * SQLite doesn't support dropping foreign keys.\n */\n protected override compileDropForeignKey(\n _operation: Extract<MigrationOperation, { type: \"drop-foreign-key\" }>,\n _mapper?: TableNameMapper,\n ): CompiledQuery {\n throw new Error(errors.SQLiteUpdateForeignKeys);\n }\n\n /**\n * SQLite doesn't support updating columns.\n */\n protected override compileUpdateColumn(\n _tableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n throw new Error(errors.SQLiteUpdateColumn);\n }\n}\n"],"mappings":";;;;AAqBA,MAAM,SAAS;CACb,gBACE;CACF,oBAAoB;CACpB,yBACE;CACH;;;;;AAMD,IAAa,qBAAb,cAAwC,aAAa;;;;;;;CAOnD,AAAS,WAAW,YAAwD;AAC1E,MAAI,WAAW,WAAW,EACxB,QAAO;EAGT,MAAMA,SAA+B,EAAE;EACvC,MAAM,qCAAqB,IAAI,KAAqB;EACpD,MAAM,qCAAqB,IAAI,KAG5B;AAGH,OAAK,MAAM,MAAM,WACf,KAAI,GAAG,SAAS,gBAAgB;AAC9B,sBAAmB,IAAI,GAAG,MAAM,OAAO,OAAO;AAC9C,UAAO,KAAK,GAAG;aACN,GAAG,SAAS,mBAAmB;AACxC,OAAI,CAAC,mBAAmB,IAAI,GAAG,MAAM,CACnC,oBAAmB,IAAI,GAAG,OAAO,EAAE,CAAC;AAEtC,sBAAmB,IAAI,GAAG,MAAM,CAAE,KAAK,GAAG;QAE1C,QAAO,KAAK,GAAG;AAKnB,OAAK,MAAM,CAAC,WAAW,UAAU,mBAAmB,SAAS,EAAE;GAC7D,MAAM,iBAAiB,mBAAmB,IAAI,UAAU;AAExD,OAAI,mBAAmB,QAAW;IAChC,MAAM,WAAW,OAAO;AACxB,QAAI,SAAS,SAAS,gBAAgB;KACpC,MAAMC,WAAsC,EAC1C,mBAAmB,MAAM,KAAK,SAAS,KAAK,MAAM,EACnD;AACD,YAAO,kBAAkB;MACvB,GAAG;MACH;MACD;;SAIH,QAAO,KAAK,GAAG,MAAM;;AAKzB,SAAO,CAAC;GAAE,MAAM;GAAU,KAAK;GAAkC,EAAE,GAAG,OAAO;;CAG/E,AAAS,mBAAmB,SAA2D;AACrF,SAAO,QAAQ,eAAe;;CAGhC,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,mBACjB,WACA,QACe;EACf,MAAM,YAAY,KAAK,aAAa,UAAU,MAAM,OAAO;EAC3D,IAAIC,UAAiC,KAAK,GAAG,OAAO,YAAY,UAAU;AAG1E,OAAK,MAAM,OAAO,UAAU,QAC1B,WAAU,QAAQ,UAChB,IAAI,MACJ,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,GAC3B,MAA+B,KAAK,YAAY,KAAK,EAAE,CACzD;EAIH,MAAM,WAAW,UAAU;AAC3B,MAAI,UAAU,kBACZ,MAAK,MAAM,MAAM,SAAS,kBACxB,WAAU,QAAQ,wBAChB,GAAG,MACH,GAAG,SACH,KAAK,aAAa,GAAG,iBAAiB,OAAO,EAC7C,GAAG,oBAEF,OAAY,GAAG,SAAS,WAAW,CAAC,SAAS,WAAW,CAC1D;AAIL,SAAO,QAAQ,SAAS;;;;;CAM1B,AAAmB,qBACjB,YACA,SACe;AACf,QAAM,IAAI,MAAM,OAAO,wBAAwB;;;;;CAMjD,AAAmB,sBACjB,YACA,SACe;AACf,QAAM,IAAI,MAAM,OAAO,wBAAwB;;;;;CAMjD,AAAmB,oBACjB,YACA,WACiC;EACjC,MAAM,MAAM,UAAU;AACtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAExC,QAAM,IAAI,MAAM,OAAO,mBAAmB"}
1
+ {"version":3,"file":"sqlite.js","names":["result: MigrationOperation[]","metadata: SqliteCreateTableMetadata","builder: CreateTableBuilderAny"],"sources":["../../../../../src/adapters/generic-sql/migration/dialect/sqlite.ts"],"sourcesContent":["import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from \"kysely\";\nimport type {\n ColumnInfo,\n ColumnOperation,\n ForeignKeyInfo,\n MigrationOperation,\n} from \"../../../../migration-engine/shared\";\nimport type { NamingResolver } from \"../../../../naming/sql-naming\";\nimport { SQLGenerator } from \"../sql-generator\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype CreateTableBuilderAny = any;\n\n/**\n * Metadata attached to create-table operations for inline foreign keys.\n */\ninterface SqliteCreateTableMetadata {\n [key: string]: unknown;\n inlineForeignKeys?: ForeignKeyInfo[];\n}\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n SQLiteUpdateColumn: \"SQLite doesn't support updating columns. Recreate the table instead.\",\n SQLiteUpdateForeignKeys:\n \"SQLite doesn't support modifying foreign keys directly. Use `recreate-table` instead.\",\n} as const;\n\n/**\n * SQLite-specific SQL generator.\n * Handles SQLite's limitations around foreign keys and column updates.\n */\nexport class SQLiteSQLGenerator extends SQLGenerator {\n /**\n * SQLite preprocessing: merge add-foreign-key operations into create-table operations\n * when both exist in the same batch, and add pragma for deferred foreign keys.\n *\n * SQLite requires foreign keys to be defined at table creation time.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n if (operations.length === 0) {\n return operations;\n }\n\n const result: MigrationOperation[] = [];\n const createTableIndices = new Map<string, number>();\n const foreignKeysByTable = new Map<\n string,\n Extract<MigrationOperation, { type: \"add-foreign-key\" }>[]\n >();\n\n // First pass: identify create-table operations and collect foreign keys\n for (const op of operations) {\n if (op.type === \"create-table\") {\n createTableIndices.set(op.name, result.length);\n result.push(op);\n } else if (op.type === \"add-foreign-key\") {\n if (!foreignKeysByTable.has(op.table)) {\n foreignKeysByTable.set(op.table, []);\n }\n foreignKeysByTable.get(op.table)!.push(op);\n } else {\n result.push(op);\n }\n }\n\n // Second pass: attach foreign keys as metadata to create-table ops\n for (const [tableName, fkOps] of foreignKeysByTable.entries()) {\n const createTableIdx = createTableIndices.get(tableName);\n\n if (createTableIdx !== undefined) {\n const createOp = result[createTableIdx];\n if (createOp.type === \"create-table\") {\n const metadata: SqliteCreateTableMetadata = {\n inlineForeignKeys: fkOps.map((fkOp) => fkOp.value),\n };\n result[createTableIdx] = {\n ...createOp,\n metadata,\n };\n }\n } else {\n // Table already exists - keep add-foreign-key operations (will throw error during compile)\n result.push(...fkOps);\n }\n }\n\n // Add pragma at the beginning for deferred foreign key checking\n return [{ type: \"custom\", sql: \"PRAGMA defer_foreign_keys = ON\" }, ...result];\n }\n\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder.autoIncrement();\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n const dbType = this.typeMapper.getDatabaseType(column);\n if (dbType === \"integer\" && (column.type === \"timestamp\" || column.type === \"date\")) {\n return sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;\n }\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * Override create-table to add inline foreign keys from metadata.\n */\n protected override compileCreateTable(\n operation: Extract<MigrationOperation, { type: \"create-table\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery {\n const tableName = this.getTableName(operation.name, resolver);\n let builder: CreateTableBuilderAny = this.getSchemaBuilder(resolver).createTable(tableName);\n\n // Add columns\n for (const col of operation.columns) {\n const columnName = this.getColumnName(col.name, operation.name, resolver);\n builder = builder.addColumn(\n columnName,\n sql.raw(this.getDBType(col)),\n (b: ColumnDefinitionBuilder) => this.buildColumn(col, b),\n );\n }\n\n // Add inline foreign keys from metadata\n const metadata = operation.metadata as SqliteCreateTableMetadata | undefined;\n if (metadata?.inlineForeignKeys) {\n for (const fk of metadata.inlineForeignKeys) {\n builder = builder.addForeignKeyConstraint(\n this.getForeignKeyName(fk.name, operation.name, fk.referencedTable, resolver),\n fk.columns.map((columnName) => this.getColumnName(columnName, operation.name, resolver)),\n this.getTableName(fk.referencedTable, resolver),\n fk.referencedColumns.map((columnName) =>\n this.getColumnName(columnName, fk.referencedTable, resolver),\n ),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (cb: any) => cb.onUpdate(\"restrict\").onDelete(\"restrict\"),\n );\n }\n }\n\n const compiled = builder.compile();\n // SQLite constraint names are ignored by Drizzle migrations; strip them for parity.\n const sqlText = compiled.sql.replace(/\\bconstraint\\s+\"[^\"]+\"\\s+foreign key\\b/gi, \"foreign key\");\n return {\n ...compiled,\n sql: sqlText,\n };\n }\n\n /**\n * SQLite doesn't support adding foreign keys to existing tables.\n */\n protected override compileAddForeignKey(\n _operation: Extract<MigrationOperation, { type: \"add-foreign-key\" }>,\n _resolver?: NamingResolver,\n ): CompiledQuery {\n throw new Error(errors.SQLiteUpdateForeignKeys);\n }\n\n /**\n * SQLite doesn't support dropping foreign keys.\n */\n protected override compileDropForeignKey(\n _operation: Extract<MigrationOperation, { type: \"drop-foreign-key\" }>,\n _resolver?: NamingResolver,\n ): CompiledQuery {\n throw new Error(errors.SQLiteUpdateForeignKeys);\n }\n\n /**\n * SQLite doesn't support updating columns.\n */\n protected override compileUpdateColumn(\n _tableName: string,\n _logicalTableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n _resolver?: NamingResolver,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n throw new Error(errors.SQLiteUpdateColumn);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prepared-migrations.d.ts","names":[],"sources":["../../../../src/adapters/generic-sql/migration/prepared-migrations.ts"],"sourcesContent":[],"mappings":";;;;;AA2BA;;;AAwBY,UApCK,cAAA,CAoCL;EAGE;;;;EAuBgE,wBAAA,CAAA,EAAA,OAAA;;;;;;UAlD7D,kBAAA;;;;;;;;;;;;6DAY4C,iBAAiB;;;;;;;;;;4BAYlE,qEAGE,iBACT;;;;;;;;;;4DAWuD;;;;;;;;;;6DAWC,iBAAiB"}
1
+ {"version":3,"file":"prepared-migrations.d.ts","names":[],"sources":["../../../../src/adapters/generic-sql/migration/prepared-migrations.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAuDc,UAvCG,cAAA,CAuCH;EACT;;;;EAsB0F,wBAAA,CAAA,EAAA,OAAA;;;;;;UAlD9E,kBAAA;;;;;;;;;;;;6DAY4C,iBAAiB;;;;;;;;;;4BAYlE,qEAGE,iBACT;;;;;;;;;;4DAWuD;;;;;;;;;;6DAWC,iBAAiB"}
@@ -1,5 +1,5 @@
1
- import { generateMigrationFromSchema } from "../../../migration-engine/auto-from-schema.js";
2
1
  import { createColdKysely } from "./cold-kysely.js";
2
+ import { generateMigrationFromSchema } from "../../../migration-engine/auto-from-schema.js";
3
3
  import "./sql-generator.js";
4
4
  import { SQLiteSQLGenerator } from "./dialect/sqlite.js";
5
5
  import { PostgresSQLGenerator } from "./dialect/postgres.js";
@@ -11,8 +11,8 @@ import { executeMigration } from "./executor.js";
11
11
  * Create a PreparedMigrations instance for a schema and namespace.
12
12
  */
13
13
  function createPreparedMigrations(config) {
14
- const { schema, namespace, database, driver, updateVersionInMigration: defaultUpdateVersion = true } = config;
15
- const generator = createSQLGenerator(database, createColdKysely(database));
14
+ const { schema, namespace, database, driverConfig, sqliteStorageMode, driver, updateVersionInMigration: defaultUpdateVersion = true } = config;
15
+ const generator = createSQLGenerator(database, createColdKysely(database), driverConfig, sqliteStorageMode);
16
16
  /**
17
17
  * Internal method to compile a migration for a given version range.
18
18
  */
@@ -22,7 +22,7 @@ function createPreparedMigrations(config) {
22
22
  if (toVersion < fromVersion) throw new Error(`Cannot migrate backwards: fromVersion (${fromVersion}) > toVersion (${toVersion})`);
23
23
  if (toVersion > schema.version) throw new Error(`toVersion (${toVersion}) exceeds schema version (${schema.version})`);
24
24
  const operations = generateMigrationFromSchema(schema, fromVersion, toVersion);
25
- const statements = generator.compile(operations, config.mapper);
25
+ const statements = generator.compile(operations, config.resolver);
26
26
  if (updateVersionInMigration && toVersion !== fromVersion) {
27
27
  const versionUpdate = generator.generateVersionUpdateSQL(namespace, fromVersion, toVersion);
28
28
  statements.push(versionUpdate);
@@ -55,11 +55,11 @@ function createPreparedMigrations(config) {
55
55
  /**
56
56
  * Create the appropriate SQL generator for a database type.
57
57
  */
58
- function createSQLGenerator(database, coldKysely) {
58
+ function createSQLGenerator(database, coldKysely, driverConfig, sqliteStorageMode) {
59
59
  switch (database) {
60
- case "sqlite": return new SQLiteSQLGenerator(coldKysely, database);
61
- case "postgresql": return new PostgresSQLGenerator(coldKysely, database);
62
- case "mysql": return new MySQLSQLGenerator(coldKysely, database);
60
+ case "sqlite": return new SQLiteSQLGenerator(coldKysely, database, driverConfig, sqliteStorageMode);
61
+ case "postgresql": return new PostgresSQLGenerator(coldKysely, database, driverConfig, sqliteStorageMode);
62
+ case "mysql": return new MySQLSQLGenerator(coldKysely, database, driverConfig, sqliteStorageMode);
63
63
  }
64
64
  }
65
65