@fragno-dev/db 0.2.2 → 0.4.1

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 (587) hide show
  1. package/.turbo/turbo-build.log +404 -175
  2. package/CHANGELOG.md +109 -0
  3. package/README.md +54 -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 +24 -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 +60 -22
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +169 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js +25 -6
  19. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js +7 -6
  21. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +193 -16
  23. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  24. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
  25. package/dist/adapters/generic-sql/migration/executor.js +30 -3
  26. package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
  27. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  28. package/dist/adapters/generic-sql/migration/prepared-migrations.js +9 -9
  29. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  30. package/dist/adapters/generic-sql/migration/sql-generator.js +75 -52
  31. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +7 -6
  33. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  35. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
  37. package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
  38. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +32 -21
  39. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  40. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  41. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  42. package/dist/adapters/generic-sql/query/sql-query-compiler.js +49 -18
  43. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  44. package/dist/adapters/generic-sql/query/where-builder.js +43 -29
  45. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  46. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  47. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  48. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  49. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  50. package/dist/adapters/generic-sql/uow-decoder.js +6 -2
  51. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  52. package/dist/adapters/generic-sql/uow-encoder.js +27 -8
  53. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  54. package/dist/adapters/in-memory/condition-evaluator.js +135 -0
  55. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  56. package/dist/adapters/in-memory/errors.d.ts +13 -0
  57. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  58. package/dist/adapters/in-memory/errors.js +23 -0
  59. package/dist/adapters/in-memory/errors.js.map +1 -0
  60. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  61. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  62. package/dist/adapters/in-memory/in-memory-adapter.js +196 -0
  63. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  64. package/dist/adapters/in-memory/in-memory-uow.js +871 -0
  65. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  66. package/dist/adapters/in-memory/index.d.ts +4 -0
  67. package/dist/adapters/in-memory/index.js +4 -0
  68. package/dist/adapters/in-memory/options.d.ts +30 -0
  69. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  70. package/dist/adapters/in-memory/options.js +62 -0
  71. package/dist/adapters/in-memory/options.js.map +1 -0
  72. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  73. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  74. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  75. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  76. package/dist/adapters/in-memory/store.js +71 -0
  77. package/dist/adapters/in-memory/store.js.map +1 -0
  78. package/dist/adapters/in-memory/value-comparison.js +28 -0
  79. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  80. package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
  81. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  82. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  83. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  84. package/dist/adapters/sql/index.d.ts +5 -0
  85. package/dist/adapters/sql/index.js +4 -0
  86. package/dist/browser/adapters/adapters.d.ts +61 -0
  87. package/dist/browser/adapters/adapters.d.ts.map +1 -0
  88. package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
  89. package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  90. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  91. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  92. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
  93. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  94. package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
  95. package/dist/browser/adapters/in-memory/index.d.ts +2 -0
  96. package/dist/browser/adapters/in-memory/options.d.ts +1 -0
  97. package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
  98. package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
  99. package/dist/browser/durable-hooks.d.ts +3 -0
  100. package/dist/browser/fragments/internal-fragment.d.ts +317 -0
  101. package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
  102. package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
  103. package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
  104. package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
  105. package/dist/browser/hooks/hooks.d.ts +146 -0
  106. package/dist/browser/hooks/hooks.d.ts.map +1 -0
  107. package/dist/browser/id.js +1 -0
  108. package/dist/browser/internal/adapter-registry.d.ts +4 -0
  109. package/dist/browser/internal/outbox-state.d.ts +2 -0
  110. package/dist/browser/mod.d.ts +15 -0
  111. package/dist/browser/mod.d.ts.map +1 -0
  112. package/dist/browser/mod.js +17 -0
  113. package/dist/browser/mod.js.map +1 -0
  114. package/dist/browser/mod2.d.ts +48 -0
  115. package/dist/browser/mod2.d.ts.map +1 -0
  116. package/dist/browser/naming/sql-naming.d.ts +19 -0
  117. package/dist/browser/naming/sql-naming.d.ts.map +1 -0
  118. package/dist/browser/outbox/outbox.d.ts +21 -0
  119. package/dist/browser/outbox/outbox.d.ts.map +1 -0
  120. package/dist/browser/query/column-defaults.js +1 -0
  121. package/dist/browser/query/condition-builder.d.ts +44 -0
  122. package/dist/browser/query/condition-builder.d.ts.map +1 -0
  123. package/dist/browser/query/condition-builder.js +97 -0
  124. package/dist/browser/query/condition-builder.js.map +1 -0
  125. package/dist/browser/query/cursor.d.ts +105 -0
  126. package/dist/browser/query/cursor.d.ts.map +1 -0
  127. package/dist/browser/query/cursor.js +150 -0
  128. package/dist/browser/query/cursor.js.map +1 -0
  129. package/dist/browser/query/db-now.d.ts +22 -0
  130. package/dist/browser/query/db-now.d.ts.map +1 -0
  131. package/dist/browser/query/db-now.js +33 -0
  132. package/dist/browser/query/db-now.js.map +1 -0
  133. package/dist/browser/query/orm/orm.d.ts +18 -0
  134. package/dist/browser/query/orm/orm.d.ts.map +1 -0
  135. package/dist/browser/query/simple-query-interface.d.ts +108 -0
  136. package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
  137. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
  138. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  139. package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
  140. package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  141. package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
  142. package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
  143. package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
  144. package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
  145. package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
  146. package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  147. package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
  148. package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
  149. package/dist/browser/query/value-encoding.js +38 -0
  150. package/dist/browser/query/value-encoding.js.map +1 -0
  151. package/dist/browser/schema/create.d.ts +326 -0
  152. package/dist/browser/schema/create.d.ts.map +1 -0
  153. package/dist/browser/schema/create.js +89 -0
  154. package/dist/browser/schema/create.js.map +1 -0
  155. package/dist/browser/schema/generate-id.js +28 -0
  156. package/dist/browser/schema/generate-id.js.map +1 -0
  157. package/dist/browser/shared/providers.d.ts +6 -0
  158. package/dist/browser/shared/providers.d.ts.map +1 -0
  159. package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
  160. package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
  161. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  162. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  163. package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
  164. package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  165. package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
  166. package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
  167. package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
  168. package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  169. package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
  170. package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  171. package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
  172. package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
  173. package/dist/browser/sync/commands.d.ts +15 -0
  174. package/dist/browser/sync/commands.d.ts.map +1 -0
  175. package/dist/browser/sync/commands.js +27 -0
  176. package/dist/browser/sync/commands.js.map +1 -0
  177. package/dist/browser/sync/types.d.ts +63 -0
  178. package/dist/browser/sync/types.d.ts.map +1 -0
  179. package/dist/browser/util/types.d.ts +8 -0
  180. package/dist/browser/util/types.d.ts.map +1 -0
  181. package/dist/browser/with-database.d.ts +29 -0
  182. package/dist/browser/with-database.d.ts.map +1 -0
  183. package/dist/client.d.ts +4 -0
  184. package/dist/client.js +5 -0
  185. package/dist/db-fragment-definition-builder.d.ts +101 -33
  186. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  187. package/dist/db-fragment-definition-builder.js +450 -60
  188. package/dist/db-fragment-definition-builder.js.map +1 -1
  189. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
  190. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
  191. package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
  192. package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
  193. package/dist/dispatchers/cloudflare-do/index.d.ts +11 -0
  194. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  195. package/dist/dispatchers/cloudflare-do/index.js +31 -0
  196. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  197. package/dist/dispatchers/node/dispatcher.d.ts +14 -0
  198. package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
  199. package/dist/dispatchers/node/dispatcher.js +80 -0
  200. package/dist/dispatchers/node/dispatcher.js.map +1 -0
  201. package/dist/dispatchers/node/index.d.ts +12 -0
  202. package/dist/dispatchers/node/index.d.ts.map +1 -0
  203. package/dist/dispatchers/node/index.js +27 -0
  204. package/dist/dispatchers/node/index.js.map +1 -0
  205. package/dist/durable-hooks.d.ts +31 -0
  206. package/dist/durable-hooks.d.ts.map +1 -0
  207. package/dist/durable-hooks.js +23 -0
  208. package/dist/durable-hooks.js.map +1 -0
  209. package/dist/fragments/internal-fragment.d.ts +186 -8
  210. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  211. package/dist/fragments/internal-fragment.js +203 -38
  212. package/dist/fragments/internal-fragment.js.map +1 -1
  213. package/dist/fragments/internal-fragment.routes.js +164 -0
  214. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  215. package/dist/fragments/internal-fragment.schema.d.ts +15 -0
  216. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  217. package/dist/fragments/internal-fragment.schema.js +39 -0
  218. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  219. package/dist/hooks/durable-hooks-logger.d.ts +10 -0
  220. package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
  221. package/dist/hooks/durable-hooks-logger.js +75 -0
  222. package/dist/hooks/durable-hooks-logger.js.map +1 -0
  223. package/dist/hooks/durable-hooks-processor.d.ts +1 -0
  224. package/dist/hooks/durable-hooks-processor.js +80 -0
  225. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  226. package/dist/hooks/durable-hooks-runtime.js +44 -0
  227. package/dist/hooks/durable-hooks-runtime.js.map +1 -0
  228. package/dist/hooks/hooks.d.ts +100 -1
  229. package/dist/hooks/hooks.d.ts.map +1 -1
  230. package/dist/hooks/hooks.js +254 -27
  231. package/dist/hooks/hooks.js.map +1 -1
  232. package/dist/id.d.ts +2 -2
  233. package/dist/id.js +2 -2
  234. package/dist/internal/adapter-registry.d.ts +11 -0
  235. package/dist/internal/adapter-registry.d.ts.map +1 -0
  236. package/dist/internal/adapter-registry.js +135 -0
  237. package/dist/internal/adapter-registry.js.map +1 -0
  238. package/dist/internal/outbox-state.d.ts +2 -0
  239. package/dist/internal/outbox-state.js +26 -0
  240. package/dist/internal/outbox-state.js.map +1 -0
  241. package/dist/migration-engine/auto-from-schema.d.ts +33 -0
  242. package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
  243. package/dist/migration-engine/auto-from-schema.js +223 -37
  244. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  245. package/dist/migration-engine/generation-engine.d.ts +16 -10
  246. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  247. package/dist/migration-engine/generation-engine.js +86 -35
  248. package/dist/migration-engine/generation-engine.js.map +1 -1
  249. package/dist/migration-engine/shared.d.ts +113 -0
  250. package/dist/migration-engine/shared.d.ts.map +1 -0
  251. package/dist/migration-engine/shared.js.map +1 -1
  252. package/dist/mod.d.ts +20 -12
  253. package/dist/mod.d.ts.map +1 -1
  254. package/dist/mod.js +18 -12
  255. package/dist/mod.js.map +1 -1
  256. package/dist/naming/sql-naming.d.ts +19 -0
  257. package/dist/naming/sql-naming.d.ts.map +1 -0
  258. package/dist/naming/sql-naming.js +116 -0
  259. package/dist/naming/sql-naming.js.map +1 -0
  260. package/dist/outbox/outbox-builder.js +156 -0
  261. package/dist/outbox/outbox-builder.js.map +1 -0
  262. package/dist/outbox/outbox.d.ts +54 -0
  263. package/dist/outbox/outbox.d.ts.map +1 -0
  264. package/dist/outbox/outbox.js +37 -0
  265. package/dist/outbox/outbox.js.map +1 -0
  266. package/dist/query/column-defaults.js +20 -4
  267. package/dist/query/column-defaults.js.map +1 -1
  268. package/dist/query/condition-builder.d.ts +7 -1
  269. package/dist/query/condition-builder.d.ts.map +1 -1
  270. package/dist/query/condition-builder.js +5 -1
  271. package/dist/query/condition-builder.js.map +1 -1
  272. package/dist/query/cursor-client.d.ts +105 -0
  273. package/dist/query/cursor-client.d.ts.map +1 -0
  274. package/dist/query/cursor-client.js +165 -0
  275. package/dist/query/cursor-client.js.map +1 -0
  276. package/dist/query/cursor.d.ts +3 -1
  277. package/dist/query/cursor.d.ts.map +1 -1
  278. package/dist/query/cursor.js +51 -14
  279. package/dist/query/cursor.js.map +1 -1
  280. package/dist/query/db-now.d.ts +22 -0
  281. package/dist/query/db-now.d.ts.map +1 -0
  282. package/dist/query/db-now.js +35 -0
  283. package/dist/query/db-now.js.map +1 -0
  284. package/dist/query/orm/orm.js.map +1 -1
  285. package/dist/query/serialize/create-sql-serializer.js +5 -4
  286. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  287. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  288. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  289. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  290. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  291. package/dist/query/serialize/dialect/sqlite-serializer.js +60 -12
  292. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  293. package/dist/query/serialize/sql-serializer.js +2 -2
  294. package/dist/query/serialize/sql-serializer.js.map +1 -1
  295. package/dist/query/simple-query-interface.d.ts +13 -4
  296. package/dist/query/simple-query-interface.d.ts.map +1 -1
  297. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
  298. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  299. package/dist/query/unit-of-work/execute-unit-of-work.js +50 -24
  300. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  301. package/dist/query/unit-of-work/unit-of-work.d.ts +92 -30
  302. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  303. package/dist/query/unit-of-work/unit-of-work.js +136 -11
  304. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  305. package/dist/query/value-decoding.js +16 -6
  306. package/dist/query/value-decoding.js.map +1 -1
  307. package/dist/query/value-encoding.js +29 -9
  308. package/dist/query/value-encoding.js.map +1 -1
  309. package/dist/schema/create.d.ts +103 -35
  310. package/dist/schema/create.d.ts.map +1 -1
  311. package/dist/schema/create.js +172 -58
  312. package/dist/schema/create.js.map +1 -1
  313. package/dist/schema/generate-id.js +2 -2
  314. package/dist/schema/generate-id.js.map +1 -1
  315. package/dist/schema/type-conversion/create-sql-type-mapper.js +4 -3
  316. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  317. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  318. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  319. package/dist/schema/validator.d.ts +10 -0
  320. package/dist/schema/validator.d.ts.map +1 -0
  321. package/dist/schema/validator.js +123 -0
  322. package/dist/schema/validator.js.map +1 -0
  323. package/dist/schema-output/drizzle.d.ts +30 -0
  324. package/dist/schema-output/drizzle.d.ts.map +1 -0
  325. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +88 -60
  326. package/dist/schema-output/drizzle.js.map +1 -0
  327. package/dist/schema-output/prisma.d.ts +17 -0
  328. package/dist/schema-output/prisma.d.ts.map +1 -0
  329. package/dist/schema-output/prisma.js +307 -0
  330. package/dist/schema-output/prisma.js.map +1 -0
  331. package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
  332. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
  333. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
  334. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
  335. package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
  336. package/dist/sql-driver/sql.js.map +1 -1
  337. package/dist/sync/commands.d.ts +15 -0
  338. package/dist/sync/commands.d.ts.map +1 -0
  339. package/dist/sync/commands.js +27 -0
  340. package/dist/sync/commands.js.map +1 -0
  341. package/dist/sync/index.d.ts +4 -0
  342. package/dist/sync/index.js +4 -0
  343. package/dist/sync/read-tracking.d.ts +25 -0
  344. package/dist/sync/read-tracking.d.ts.map +1 -0
  345. package/dist/sync/read-tracking.js +148 -0
  346. package/dist/sync/read-tracking.js.map +1 -0
  347. package/dist/sync/submit.js +213 -0
  348. package/dist/sync/submit.js.map +1 -0
  349. package/dist/sync/types.d.ts +63 -0
  350. package/dist/sync/types.d.ts.map +1 -0
  351. package/dist/util/default-database-adapter.js +66 -0
  352. package/dist/util/default-database-adapter.js.map +1 -0
  353. package/dist/with-database.d.ts +3 -6
  354. package/dist/with-database.d.ts.map +1 -1
  355. package/dist/with-database.js +8 -7
  356. package/dist/with-database.js.map +1 -1
  357. package/package.json +62 -55
  358. package/src/adapters/adapters.ts +33 -26
  359. package/src/adapters/drizzle/migrate-drizzle.test.ts +99 -41
  360. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +601 -0
  361. package/src/adapters/drizzle/test-utils.ts +13 -8
  362. package/src/adapters/generic-sql/driver-config.ts +38 -0
  363. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +10 -8
  364. package/src/adapters/generic-sql/generic-sql-adapter.ts +117 -34
  365. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +55 -0
  366. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +297 -3
  367. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +120 -0
  368. package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
  369. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +27 -8
  370. package/src/adapters/generic-sql/migration/dialect/mysql.ts +47 -8
  371. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +28 -9
  372. package/src/adapters/generic-sql/migration/dialect/postgres.ts +9 -4
  373. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +839 -8
  374. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +396 -53
  375. package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
  376. package/src/adapters/generic-sql/migration/executor.ts +47 -4
  377. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +238 -46
  378. package/src/adapters/generic-sql/migration/prepared-migrations.ts +21 -13
  379. package/src/adapters/generic-sql/migration/sql-generator.ts +145 -66
  380. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +11 -8
  381. package/src/adapters/generic-sql/query/cursor-utils.test.ts +272 -0
  382. package/src/adapters/generic-sql/query/cursor-utils.ts +42 -7
  383. package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
  384. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +171 -35
  385. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +53 -40
  386. package/src/adapters/generic-sql/query/select-builder.test.ts +16 -11
  387. package/src/adapters/generic-sql/query/select-builder.ts +7 -3
  388. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +75 -6
  389. package/src/adapters/generic-sql/query/sql-query-compiler.ts +129 -24
  390. package/src/adapters/generic-sql/query/where-builder.test.ts +96 -20
  391. package/src/adapters/generic-sql/query/where-builder.ts +112 -41
  392. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +11 -20
  393. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +851 -0
  394. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +18 -15
  395. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +282 -14
  396. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +129 -12
  397. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +9 -7
  398. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  399. package/src/adapters/generic-sql/uow-decoder.test.ts +5 -4
  400. package/src/adapters/generic-sql/uow-decoder.ts +23 -5
  401. package/src/adapters/generic-sql/uow-encoder.test.ts +36 -3
  402. package/src/adapters/generic-sql/uow-encoder.ts +48 -13
  403. package/src/adapters/in-memory/condition-evaluator.test.ts +194 -0
  404. package/src/adapters/in-memory/condition-evaluator.ts +280 -0
  405. package/src/adapters/in-memory/errors.ts +20 -0
  406. package/src/adapters/in-memory/in-memory-adapter.ts +388 -0
  407. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +344 -0
  408. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +255 -0
  409. package/src/adapters/in-memory/in-memory-uow.ts +1724 -0
  410. package/src/adapters/in-memory/index.ts +3 -0
  411. package/src/adapters/in-memory/options.test.ts +42 -0
  412. package/src/adapters/in-memory/options.ts +91 -0
  413. package/src/adapters/in-memory/outbox.test.ts +361 -0
  414. package/src/adapters/in-memory/reference-resolution.test.ts +51 -0
  415. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  416. package/src/adapters/in-memory/sorted-array-index.test.ts +124 -0
  417. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  418. package/src/adapters/in-memory/store.test.ts +69 -0
  419. package/src/adapters/in-memory/store.ts +145 -0
  420. package/src/adapters/in-memory/value-comparison.ts +53 -0
  421. package/src/adapters/in-memory/value-normalization.test.ts +58 -0
  422. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1207 -0
  423. package/src/adapters/shared/from-unit-of-work-compiler.ts +159 -47
  424. package/src/adapters/shared/uow-operation-compiler.ts +28 -18
  425. package/src/adapters/sql/index.ts +12 -0
  426. package/src/browser/mod.ts +64 -0
  427. package/src/client.ts +19 -0
  428. package/src/db-fragment-definition-builder.test.ts +845 -53
  429. package/src/db-fragment-definition-builder.ts +911 -95
  430. package/src/db-fragment-instantiator.test.ts +210 -94
  431. package/src/db-fragment-integration.test.ts +17 -12
  432. package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
  433. package/src/dispatchers/cloudflare-do/index.test.ts +206 -0
  434. package/src/dispatchers/cloudflare-do/index.ts +63 -0
  435. package/src/dispatchers/node/dispatcher.ts +112 -0
  436. package/src/dispatchers/node/index.test.ts +120 -0
  437. package/src/dispatchers/node/index.ts +50 -0
  438. package/src/durable-hooks.test.ts +80 -0
  439. package/src/durable-hooks.ts +67 -0
  440. package/src/fragments/internal-fragment.routes.test.ts +570 -0
  441. package/src/fragments/internal-fragment.routes.ts +334 -0
  442. package/src/fragments/internal-fragment.schema.ts +95 -0
  443. package/src/fragments/internal-fragment.test.ts +505 -83
  444. package/src/fragments/internal-fragment.ts +453 -70
  445. package/src/hooks/durable-hooks-logger.ts +126 -0
  446. package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
  447. package/src/hooks/durable-hooks-processor.test.ts +282 -0
  448. package/src/hooks/durable-hooks-processor.ts +173 -0
  449. package/src/hooks/durable-hooks-runtime.test.ts +65 -0
  450. package/src/hooks/durable-hooks-runtime.ts +81 -0
  451. package/src/hooks/hooks.test.ts +455 -34
  452. package/src/hooks/hooks.ts +501 -34
  453. package/src/id.test.ts +34 -0
  454. package/src/id.ts +1 -3
  455. package/src/internal/adapter-registry.test.ts +93 -0
  456. package/src/internal/adapter-registry.ts +239 -0
  457. package/src/internal/outbox-state.ts +43 -0
  458. package/src/migration-engine/auto-from-schema.test.ts +107 -14
  459. package/src/migration-engine/auto-from-schema.ts +365 -44
  460. package/src/migration-engine/create.test.ts +4 -3
  461. package/src/migration-engine/create.ts +1 -1
  462. package/src/migration-engine/generation-engine.test.ts +292 -110
  463. package/src/migration-engine/generation-engine.ts +117 -66
  464. package/src/migration-engine/shared.ts +14 -0
  465. package/src/mod.ts +95 -39
  466. package/src/naming/sql-naming.ts +181 -0
  467. package/src/outbox/outbox-builder.ts +241 -0
  468. package/src/outbox/outbox.test.ts +424 -0
  469. package/src/outbox/outbox.ts +139 -0
  470. package/src/query/column-defaults.ts +42 -4
  471. package/src/query/condition-builder.test.ts +18 -3
  472. package/src/query/condition-builder.ts +7 -0
  473. package/src/query/cursor-client.test.ts +70 -0
  474. package/src/query/cursor-client.ts +263 -0
  475. package/src/query/cursor.test.ts +119 -20
  476. package/src/query/cursor.ts +88 -27
  477. package/src/query/db-now.ts +73 -0
  478. package/src/query/orm/orm.ts +2 -2
  479. package/src/query/query-type.test.ts +4 -3
  480. package/src/query/serialize/create-sql-serializer.ts +10 -5
  481. package/src/query/serialize/dialect/mysql-serializer.ts +13 -5
  482. package/src/query/serialize/dialect/postgres-serializer.ts +35 -5
  483. package/src/query/serialize/dialect/sqlite-serializer.test.ts +90 -3
  484. package/src/query/serialize/dialect/sqlite-serializer.ts +108 -12
  485. package/src/query/serialize/sql-serializer.ts +4 -4
  486. package/src/query/simple-query-interface.ts +15 -4
  487. package/src/query/unit-of-work/execute-unit-of-work.test.ts +372 -10
  488. package/src/query/unit-of-work/execute-unit-of-work.ts +87 -27
  489. package/src/query/unit-of-work/retry-policy.test.ts +1 -0
  490. package/src/query/unit-of-work/tx-builder.test.ts +73 -1
  491. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +17 -16
  492. package/src/query/unit-of-work/unit-of-work-types.test.ts +42 -12
  493. package/src/query/unit-of-work/unit-of-work.test.ts +196 -39
  494. package/src/query/unit-of-work/unit-of-work.ts +309 -38
  495. package/src/query/value-decoding.test.ts +63 -4
  496. package/src/query/value-decoding.ts +32 -6
  497. package/src/query/value-encoding.test.ts +86 -2
  498. package/src/query/value-encoding.ts +56 -6
  499. package/src/schema/create.test.ts +293 -47
  500. package/src/schema/create.ts +406 -70
  501. package/src/schema/generate-id.test.ts +3 -2
  502. package/src/schema/generate-id.ts +2 -2
  503. package/src/schema/serialize.test.ts +18 -5
  504. package/src/schema/type-conversion/create-sql-type-mapper.ts +8 -3
  505. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  506. package/src/schema/type-conversion/type-mapping.test.ts +26 -1
  507. package/src/schema/validator.test.ts +199 -0
  508. package/src/schema/validator.ts +232 -0
  509. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +232 -129
  510. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +155 -99
  511. package/src/schema-output/prisma.test.ts +694 -0
  512. package/src/schema-output/prisma.ts +593 -0
  513. package/src/sql-driver/better-sqlite3.test.ts +5 -3
  514. package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
  515. package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
  516. package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
  517. package/src/sql-driver/query-executor/query-executor.ts +1 -1
  518. package/src/sql-driver/sql-driver-adapter.ts +2 -2
  519. package/src/sql-driver/sql.ts +2 -1
  520. package/src/sql-driver/sqlocal.test.ts +4 -2
  521. package/src/sync/commands.test.ts +39 -0
  522. package/src/sync/commands.ts +51 -0
  523. package/src/sync/conflict-checker.test.ts +450 -0
  524. package/src/sync/conflict-checker.ts +248 -0
  525. package/src/sync/index.ts +14 -0
  526. package/src/sync/plan.ts +9 -0
  527. package/src/sync/read-tracking.test.ts +177 -0
  528. package/src/sync/read-tracking.ts +287 -0
  529. package/src/sync/submit.test.ts +205 -0
  530. package/src/sync/submit.ts +328 -0
  531. package/src/sync/types.ts +80 -0
  532. package/src/util/default-database-adapter.ts +119 -0
  533. package/src/with-database.ts +20 -31
  534. package/tsconfig.json +1 -1
  535. package/tsdown.config.ts +38 -24
  536. package/vitest.config.ts +1 -0
  537. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  538. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  539. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  540. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  541. package/dist/adapters/drizzle/generate.d.ts +0 -30
  542. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  543. package/dist/adapters/drizzle/generate.js.map +0 -1
  544. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  545. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  546. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  547. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  548. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  549. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  550. package/dist/adapters/shared/table-name-mapper.js +0 -43
  551. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  552. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +0 -165
  553. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  554. package/dist/packages/fragno/dist/api/bind-services.js +0 -20
  555. package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
  556. package/dist/packages/fragno/dist/api/error.js +0 -48
  557. package/dist/packages/fragno/dist/api/error.js.map +0 -1
  558. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -320
  559. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
  560. package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -525
  561. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
  562. package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
  563. package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
  564. package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
  565. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
  566. package/dist/packages/fragno/dist/api/internal/route.js +0 -10
  567. package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
  568. package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
  569. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
  570. package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
  571. package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
  572. package/dist/packages/fragno/dist/api/request-input-context.js +0 -118
  573. package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
  574. package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
  575. package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
  576. package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
  577. package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
  578. package/dist/packages/fragno/dist/api/route.js +0 -17
  579. package/dist/packages/fragno/dist/api/route.js.map +0 -1
  580. package/dist/packages/fragno/dist/internal/symbols.js +0 -10
  581. package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
  582. package/dist/schema-generator/schema-generator.d.ts +0 -15
  583. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  584. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  585. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  586. package/src/adapters/shared/table-name-mapper.ts +0 -50
  587. package/src/schema-generator/schema-generator.ts +0 -12
@@ -1,27 +1,48 @@
1
- import { RequestContextStorage } from "../../packages/fragno/dist/api/request-context-storage.js";
2
- import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "../adapters.js";
3
- import { createTableNameMapper } from "../shared/table-name-mapper.js";
4
- import { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter.js";
1
+ import { createNamingResolver } from "../../naming/sql-naming.js";
2
+ import { getOutboxConfigForAdapter } from "../../internal/outbox-state.js";
3
+ import { sqliteStorageDefault, sqliteStoragePrisma } from "./sqlite-storage.js";
4
+ import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
5
5
  import { sql } from "../../sql-driver/sql.js";
6
+ import { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter.js";
7
+ import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "../adapters.js";
8
+ import { fromUnitOfWorkCompiler } from "../shared/from-unit-of-work-compiler.js";
9
+ import { createUOWCompilerFromOperationCompiler } from "../shared/uow-operation-compiler.js";
6
10
  import { createExecutor } from "./generic-sql-uow-executor.js";
7
- import { UnitOfWorkDecoder } from "./uow-decoder.js";
8
11
  import { createPreparedMigrations } from "./migration/prepared-migrations.js";
9
- import { createUOWCompilerFromOperationCompiler } from "../shared/uow-operation-compiler.js";
10
12
  import { GenericSQLUOWOperationCompiler } from "./query/generic-sql-uow-operation-compiler.js";
11
- import { fromUnitOfWorkCompiler } from "../shared/from-unit-of-work-compiler.js";
13
+ import { UnitOfWorkDecoder } from "./uow-decoder.js";
14
+ import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
12
15
 
13
16
  //#region src/adapters/generic-sql/generic-sql-adapter.ts
14
- var GenericSQLAdapter = class {
17
+ const sqliteProfiles = {
18
+ default: sqliteStorageDefault,
19
+ prisma: sqliteStoragePrisma
20
+ };
21
+ var SqlAdapter = class {
15
22
  dialect;
16
23
  driverConfig;
17
24
  uowConfig;
25
+ sqliteStorageMode;
26
+ sqliteProfile;
27
+ adapterMetadata;
28
+ namingStrategy;
18
29
  #schemaNamespaceMap = /* @__PURE__ */ new WeakMap();
19
30
  #contextStorage;
20
31
  #driver;
21
- constructor({ dialect, driverConfig, uowConfig }) {
32
+ constructor({ dialect, driverConfig, uowConfig, sqliteProfile, sqliteStorageMode, namingStrategy }) {
22
33
  this.dialect = dialect;
23
34
  this.driverConfig = driverConfig;
24
35
  this.uowConfig = uowConfig;
36
+ this.namingStrategy = namingStrategy ?? driverConfig.defaultNamingStrategy;
37
+ const resolvedProfile = sqliteProfile ?? "default";
38
+ if (sqliteStorageMode && sqliteProfile) throw new Error("sqliteStorageMode cannot be used together with sqliteProfile.");
39
+ this.sqliteStorageMode = driverConfig.databaseType === "sqlite" ? sqliteStorageMode ?? sqliteProfiles[resolvedProfile] : void 0;
40
+ this.sqliteProfile = driverConfig.databaseType === "sqlite" && !sqliteStorageMode ? resolvedProfile : void 0;
41
+ this.adapterMetadata = {
42
+ databaseType: driverConfig.databaseType,
43
+ sqliteProfile: this.sqliteProfile,
44
+ sqliteStorageMode: this.sqliteStorageMode
45
+ };
25
46
  this.#schemaNamespaceMap = /* @__PURE__ */ new WeakMap();
26
47
  this.#contextStorage = new RequestContextStorage();
27
48
  this.#driver = new SqlDriverAdapter(dialect);
@@ -30,10 +51,10 @@ var GenericSQLAdapter = class {
30
51
  return this.#driver;
31
52
  }
32
53
  get [fragnoDatabaseAdapterNameFakeSymbol]() {
33
- return "generic-sql";
54
+ return "sql";
34
55
  }
35
56
  get [fragnoDatabaseAdapterVersionFakeSymbol]() {
36
- return 0;
57
+ return 1;
37
58
  }
38
59
  get contextStorage() {
39
60
  return this.#contextStorage;
@@ -42,20 +63,21 @@ var GenericSQLAdapter = class {
42
63
  return this.#driver.destroy();
43
64
  }
44
65
  async isConnectionHealthy() {
45
- return (await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect))).rows[0]["healthy"] === 1;
66
+ const healthyValue = (await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect))).rows[0]?.["healthy"];
67
+ return healthyValue === 1 || healthyValue === 1n || healthyValue === "1";
46
68
  }
47
69
  prepareMigrations(schema, namespace) {
70
+ const resolver = createNamingResolver(schema, namespace, this.namingStrategy);
48
71
  return createPreparedMigrations({
49
72
  schema,
50
- namespace,
73
+ namespace: namespace ?? schema.name,
51
74
  database: this.driverConfig.databaseType,
52
- mapper: namespace ? this.createTableNameMapper(namespace) : void 0,
75
+ driverConfig: this.driverConfig,
76
+ sqliteStorageMode: this.sqliteStorageMode,
77
+ resolver,
53
78
  driver: this.#driver
54
79
  });
55
80
  }
56
- createTableNameMapper(namespace) {
57
- return createTableNameMapper(namespace, false);
58
- }
59
81
  async getSchemaVersion(namespace) {
60
82
  const query = sql`SELECT value FROM fragno_db_settings WHERE key = ${`${namespace}.schema_version`};`.compile(this.dialect);
61
83
  let result;
@@ -72,16 +94,32 @@ var GenericSQLAdapter = class {
72
94
  }
73
95
  createQueryEngine(schema, namespace) {
74
96
  this.#schemaNamespaceMap.set(schema, namespace);
75
- return fromUnitOfWorkCompiler(schema, {
76
- compiler: createUOWCompilerFromOperationCompiler(new GenericSQLUOWOperationCompiler(this.driverConfig, (ns) => ns ? this.createTableNameMapper(ns) : void 0)),
77
- executor: createExecutor(this.#driver, this.driverConfig, false),
78
- decoder: new UnitOfWorkDecoder(this.driverConfig),
97
+ const resolver = createNamingResolver(schema, namespace, this.namingStrategy);
98
+ const queryEngine = fromUnitOfWorkCompiler(schema, {
99
+ compiler: createUOWCompilerFromOperationCompiler(new GenericSQLUOWOperationCompiler(this.driverConfig, this.sqliteStorageMode, (schemaForResolver, namespaceForResolver) => createNamingResolver(schemaForResolver, namespaceForResolver, this.namingStrategy))),
100
+ executor: createExecutor(this.#driver, this.driverConfig, {
101
+ dialect: this.dialect,
102
+ dryRun: false,
103
+ outbox: getOutboxConfigForAdapter(this),
104
+ namingStrategy: this.namingStrategy
105
+ }),
106
+ decoder: new UnitOfWorkDecoder(this.driverConfig, this.sqliteStorageMode, resolver),
79
107
  uowConfig: this.uowConfig,
80
108
  schemaNamespaceMap: this.#schemaNamespaceMap
81
109
  });
110
+ const serializer = createSQLSerializer(this.driverConfig, this.sqliteStorageMode);
111
+ const timestampColumn = { type: "timestamp" };
112
+ return {
113
+ ...queryEngine,
114
+ now: async () => {
115
+ const rawValue = (await this.#driver.executeQuery(sql`SELECT CURRENT_TIMESTAMP as now`.compile(this.dialect))).rows[0]?.["now"];
116
+ if (rawValue === void 0 || rawValue === null) throw new Error("Failed to fetch database time");
117
+ return serializer.deserialize(rawValue, timestampColumn);
118
+ }
119
+ };
82
120
  }
83
121
  };
84
122
 
85
123
  //#endregion
86
- export { GenericSQLAdapter };
124
+ export { SqlAdapter, sqliteProfiles };
87
125
  //# sourceMappingURL=generic-sql-adapter.js.map
@@ -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\";\n\nimport { getOutboxConfigForAdapter } from \"../../internal/outbox-state\";\nimport {\n createNamingResolver,\n type NamingResolver,\n type SqlNamingStrategy,\n} from \"../../naming/sql-naming\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport type { SimpleQueryInterface } from \"../../query/simple-query-interface\";\nimport type { UOWInstrumentation } from \"../../query/unit-of-work/unit-of-work\";\nimport type { AnyColumn, AnySchema } from \"../../schema/create\";\nimport { sql } from \"../../sql-driver/sql\";\nimport type { CompiledQuery, Dialect, QueryResult } from \"../../sql-driver/sql-driver\";\nimport { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport {\n fragnoDatabaseAdapterNameFakeSymbol,\n fragnoDatabaseAdapterVersionFakeSymbol,\n type DatabaseAdapter,\n type DatabaseContextStorage,\n type DatabaseAdapterMetadata,\n type SQLiteProfile,\n} from \"../adapters\";\nimport {\n fromUnitOfWorkCompiler,\n type UnitOfWorkFactory,\n} from \"../shared/from-unit-of-work-compiler\";\nimport { createUOWCompilerFromOperationCompiler } from \"../shared/uow-operation-compiler\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { createExecutor } from \"./generic-sql-uow-executor\";\nimport { createPreparedMigrations, type PreparedMigrations } from \"./migration/prepared-migrations\";\nimport { GenericSQLUOWOperationCompiler } from \"./query/generic-sql-uow-operation-compiler\";\nimport type { SQLiteStorageMode } from \"./sqlite-storage\";\nimport { sqliteStorageDefault, sqliteStoragePrisma } from \"./sqlite-storage\";\nimport { UnitOfWorkDecoder } from \"./uow-decoder\";\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 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 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 sqliteProfile,\n sqliteStorageMode,\n namingStrategy,\n }: SqlAdapterOptions) {\n this.dialect = dialect;\n this.driverConfig = driverConfig;\n this.uowConfig = uowConfig;\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: getOutboxConfigForAdapter(this),\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":"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"}
@@ -1,4 +1,12 @@
1
+ import { createId } from "../../id.js";
2
+ import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
3
+ import { sql } from "../../sql-driver/sql.js";
4
+ import { SETTINGS_NAMESPACE, internalSchema } from "../../fragments/internal-fragment.schema.js";
5
+ import { encodeVersionstamp, parseOutboxVersionValue, versionstampToHex } from "../../outbox/outbox.js";
6
+ import { buildOutboxPlan, finalizeOutboxPayload } from "../../outbox/outbox-builder.js";
7
+ import { createColdKysely } from "./migration/cold-kysely.js";
1
8
  import { ResultInterpreter } from "./result-interpreter.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,28 @@ 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 shouldInclude = options.outbox?.shouldInclude;
32
+ const namingStrategy = options.namingStrategy ?? driverConfig.defaultNamingStrategy;
33
+ const outboxOperations = outboxEnabled ? mutationBatch.flatMap((mutation) => {
34
+ const operation = mutation.operation;
35
+ if (!operation) return [];
36
+ if (shouldInclude && !shouldInclude(operation)) return [];
37
+ return [operation];
38
+ }) : [];
39
+ const outboxPlan = outboxOperations.length > 0 ? buildOutboxPlan(outboxOperations) : null;
40
+ const shouldWriteOutbox = outboxEnabled && outboxPlan !== null && outboxPlan.drafts.length > 0;
22
41
  try {
23
42
  await adapter.transaction(async (tx) => {
43
+ let outboxVersion = null;
44
+ if (shouldWriteOutbox) outboxVersion = await reserveOutboxVersion(tx, driverConfig, options.dialect);
24
45
  for (const compiledMutation of mutationBatch) {
25
46
  const result = await tx.executeQuery(compiledMutation.query);
26
47
  if (compiledMutation.op === "create") if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {
@@ -36,6 +57,26 @@ async function executeMutation(adapter, driverConfig, mutationBatch) {
36
57
  if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) throw new Error(`Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`);
37
58
  }
38
59
  }
60
+ if (shouldWriteOutbox && outboxPlan && outboxVersion !== null) {
61
+ const uowId = mutationBatch[0]?.uowId;
62
+ if (!uowId) throw new Error("Outbox mutation batch is missing uowId.");
63
+ const refMap = await resolveOutboxRefMap(tx, driverConfig, outboxPlan.lookups, namingStrategy);
64
+ const payload = finalizeOutboxPayload(outboxPlan, outboxVersion);
65
+ const payloadSerialized = superjson.serialize(payload);
66
+ const versionstamp = versionstampToHex(encodeVersionstamp(outboxVersion, 0));
67
+ await insertOutboxMutationRows(tx, driverConfig, {
68
+ entryVersionstamp: versionstamp,
69
+ uowId,
70
+ mutations: payload.mutations
71
+ });
72
+ await insertOutboxRow(tx, driverConfig, {
73
+ id: createId(),
74
+ versionstamp,
75
+ uowId,
76
+ payload: payloadSerialized,
77
+ refMap
78
+ });
79
+ }
39
80
  });
40
81
  return {
41
82
  success: true,
@@ -43,10 +84,13 @@ async function executeMutation(adapter, driverConfig, mutationBatch) {
43
84
  };
44
85
  } catch (error) {
45
86
  if (error instanceof Error && error.message.includes("Version conflict")) return { success: false };
87
+ const errorCode = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
88
+ if (errorCode === "40001" || errorCode === "40P01") return { success: false };
46
89
  throw error;
47
90
  }
48
91
  }
49
- function createExecutor(adapter, driverConfig, dryRun) {
92
+ function createExecutor(adapter, driverConfig, options) {
93
+ const dryRun = options.dryRun ?? false;
50
94
  return {
51
95
  async executeRetrievalPhase(retrievalBatch) {
52
96
  if (dryRun) return retrievalBatch.map(() => []);
@@ -57,10 +101,132 @@ function createExecutor(adapter, driverConfig, dryRun) {
57
101
  success: true,
58
102
  createdInternalIds: mutationBatch.map(() => null)
59
103
  };
60
- return executeMutation(adapter, driverConfig, mutationBatch);
104
+ return executeMutation(adapter, driverConfig, mutationBatch, options);
61
105
  }
62
106
  };
63
107
  }
108
+ async function reserveOutboxVersion(tx, driverConfig, dialect) {
109
+ const key = `${SETTINGS_NAMESPACE}.outbox_version`;
110
+ const id = createId();
111
+ switch (driverConfig.outboxVersionstampStrategy) {
112
+ case "insert-on-conflict-returning": {
113
+ const query = driverConfig.databaseType === "postgresql" ? sql`
114
+ insert into fragno_db_settings (id, key, value)
115
+ values (${id}, ${key}, '0')
116
+ on conflict (key) do update
117
+ set value = (fragno_db_settings.value::bigint + 1)::text
118
+ returning value;
119
+ ` : sql`
120
+ insert into fragno_db_settings (id, key, value)
121
+ values (${id}, ${key}, '0')
122
+ on conflict (key) do update
123
+ set value = cast(fragno_db_settings.value as integer) + 1
124
+ returning value;
125
+ `;
126
+ const value = (await tx.executeQuery(query.compile(dialect))).rows[0]?.["value"];
127
+ return parseOutboxVersionValue(value);
128
+ }
129
+ case "update-returning": {
130
+ const query = driverConfig.databaseType === "postgresql" ? sql`
131
+ update fragno_db_settings
132
+ set value = (fragno_db_settings.value::bigint + 1)::text
133
+ where key = ${key}
134
+ returning value;
135
+ ` : sql`
136
+ update fragno_db_settings
137
+ set value = cast(fragno_db_settings.value as integer) + 1
138
+ where key = ${key}
139
+ returning value;
140
+ `;
141
+ const value = (await tx.executeQuery(query.compile(dialect))).rows[0]?.["value"];
142
+ if (value === void 0) throw new Error("Outbox version row was not found for update-returning strategy.");
143
+ return parseOutboxVersionValue(value);
144
+ }
145
+ case "insert-on-duplicate-last-insert-id": {
146
+ const insertQuery = sql`
147
+ insert into fragno_db_settings (id, key, value)
148
+ values (${id}, ${key}, LAST_INSERT_ID(0))
149
+ on duplicate key update value = LAST_INSERT_ID(cast(value as unsigned) + 1);
150
+ `;
151
+ await tx.executeQuery(insertQuery.compile(dialect));
152
+ const selectQuery = sql`select LAST_INSERT_ID() as value;`;
153
+ const value = (await tx.executeQuery(selectQuery.compile(dialect))).rows[0]?.["value"];
154
+ return parseOutboxVersionValue(value);
155
+ }
156
+ }
157
+ }
158
+ async function resolveOutboxRefMap(tx, driverConfig, lookups, namingStrategy) {
159
+ if (lookups.length === 0) return;
160
+ const refMap = {};
161
+ const db = createColdKysely(driverConfig.databaseType);
162
+ for (const lookup of lookups) {
163
+ const namespace = lookup.namespace ?? null;
164
+ const logicalTable = lookup.table.name;
165
+ const schemaName = namingStrategy.namespaceScope === "schema" && namespace && namespace.length > 0 ? namingStrategy.namespaceToSchema(namespace) : null;
166
+ const scopedDb = schemaName ? db.withSchema(schemaName) : db;
167
+ const tableName = namingStrategy.tableName(logicalTable, namespace);
168
+ const internalColumn = namingStrategy.columnName(lookup.table.getInternalIdColumn().name, logicalTable);
169
+ const externalColumn = namingStrategy.columnName(lookup.table.getIdColumn().name, logicalTable);
170
+ const query = scopedDb.selectFrom(tableName).select(externalColumn).where(internalColumn, "=", lookup.internalId).compile();
171
+ const externalId = (await tx.executeQuery(query)).rows[0]?.[externalColumn];
172
+ if (typeof externalId !== "string") throw new Error(`Failed to resolve outbox reference for ${tableName}.${internalColumn}=${String(lookup.internalId)}`);
173
+ refMap[lookup.key] = externalId;
174
+ }
175
+ return Object.keys(refMap).length > 0 ? refMap : void 0;
176
+ }
177
+ async function insertOutboxRow(tx, driverConfig, options) {
178
+ const { id, versionstamp, uowId, payload, refMap } = options;
179
+ const refMapValue = refMap ?? null;
180
+ const serializer = createSQLSerializer(driverConfig);
181
+ const outboxTable = internalSchema.tables.fragno_db_outbox;
182
+ const values = {
183
+ id,
184
+ versionstamp,
185
+ uowId,
186
+ payload,
187
+ refMap: refMapValue
188
+ };
189
+ const serializedValues = {};
190
+ for (const [key, value] of Object.entries(values)) {
191
+ const col = outboxTable.getColumnByName(key);
192
+ if (!col) {
193
+ serializedValues[key] = value;
194
+ continue;
195
+ }
196
+ serializedValues[col.name] = serializer.serialize(value, col);
197
+ }
198
+ const query = createColdKysely(driverConfig.databaseType).insertInto("fragno_db_outbox").values(serializedValues).compile();
199
+ await tx.executeQuery(query);
200
+ }
201
+ async function insertOutboxMutationRows(tx, driverConfig, options) {
202
+ if (options.mutations.length === 0) return;
203
+ const serializer = createSQLSerializer(driverConfig);
204
+ const mutationsTable = internalSchema.tables.fragno_db_outbox_mutations;
205
+ const db = createColdKysely(driverConfig.databaseType);
206
+ for (const mutation of options.mutations) {
207
+ const values = {
208
+ id: createId(),
209
+ entryVersionstamp: options.entryVersionstamp,
210
+ mutationVersionstamp: mutation.versionstamp,
211
+ uowId: options.uowId,
212
+ schema: mutation.schema,
213
+ table: mutation.table,
214
+ externalId: mutation.externalId,
215
+ op: mutation.op
216
+ };
217
+ const serializedValues = {};
218
+ for (const [key, value] of Object.entries(values)) {
219
+ const col = mutationsTable.getColumnByName(key);
220
+ if (!col) {
221
+ serializedValues[key] = value;
222
+ continue;
223
+ }
224
+ serializedValues[col.name] = serializer.serialize(value, col);
225
+ }
226
+ const query = db.insertInto("fragno_db_outbox_mutations").values(serializedValues).compile();
227
+ await tx.executeQuery(query);
228
+ }
229
+ }
64
230
 
65
231
  //#endregion
66
232
  export { createExecutor };
@@ -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 superjson from \"superjson\";\n\nimport { SETTINGS_NAMESPACE, internalSchema } from \"../../fragments/internal-fragment.schema\";\nimport { createId } from \"../../id\";\nimport { type SqlNamingStrategy } from \"../../naming/sql-naming\";\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 {\n CompiledMutation,\n MutationResult,\n UOWExecutor,\n} from \"../../query/unit-of-work/unit-of-work\";\nimport { sql } from \"../../sql-driver/sql\";\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 { createColdKysely } from \"./migration/cold-kysely\";\nimport { ResultInterpreter } from \"./result-interpreter\";\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 shouldInclude = options.outbox?.shouldInclude;\n const namingStrategy = options.namingStrategy ?? driverConfig.defaultNamingStrategy;\n\n const outboxOperations = outboxEnabled\n ? mutationBatch.flatMap((mutation) => {\n const operation = mutation.operation;\n if (!operation) {\n return [];\n }\n if (shouldInclude && !shouldInclude(operation)) {\n return [];\n }\n return [operation];\n })\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 insertOutboxMutationRows(tx, driverConfig, {\n entryVersionstamp: versionstamp,\n uowId,\n mutations: payload.mutations,\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.getColumnByName(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\nasync function insertOutboxMutationRows(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n options: {\n entryVersionstamp: string;\n uowId: string;\n mutations: {\n versionstamp: string;\n schema: string;\n table: string;\n externalId: string;\n op: string;\n }[];\n },\n): Promise<void> {\n if (options.mutations.length === 0) {\n return;\n }\n\n const serializer = createSQLSerializer(driverConfig);\n const mutationsTable = internalSchema.tables.fragno_db_outbox_mutations;\n const db = createColdKysely(driverConfig.databaseType);\n\n for (const mutation of options.mutations) {\n const values = {\n id: createId(),\n entryVersionstamp: options.entryVersionstamp,\n mutationVersionstamp: mutation.versionstamp,\n uowId: options.uowId,\n schema: mutation.schema,\n table: mutation.table,\n externalId: mutation.externalId,\n op: mutation.op,\n };\n const serializedValues: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n const col = mutationsTable.getColumnByName(key);\n if (!col) {\n serializedValues[key] = value;\n continue;\n }\n serializedValues[col.name] = serializer.serialize(value, col);\n }\n\n const query = db.insertInto(\"fragno_db_outbox_mutations\").values(serializedValues).compile();\n await tx.executeQuery(query);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cold-kysely.js","names":[],"sources":["../../../../src/adapters/generic-sql/migration/cold-kysely.ts"],"sourcesContent":["import {\n DummyDriver,\n Kysely,\n MysqlAdapter,\n MysqlIntrospector,\n MysqlQueryCompiler,\n PostgresAdapter,\n PostgresIntrospector,\n PostgresQueryCompiler,\n SqliteAdapter,\n SqliteIntrospector,\n SqliteQueryCompiler,\n} from \"kysely\";\nimport type { SupportedDatabase } from \"../driver-config\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KyselyAny = Kysely<any>;\n\n/**\n * Creates a Kysely instance that can only build queries, not execute them.\n * This is used for SQL generation without requiring a database connection.\n */\nexport function createColdKysely(database: SupportedDatabase): KyselyAny {\n switch (database) {\n case \"postgresql\":\n return new Kysely({\n dialect: {\n createAdapter: () => new PostgresAdapter(),\n createDriver: () => new DummyDriver(),\n createIntrospector: (db) => new PostgresIntrospector(db),\n createQueryCompiler: () => new PostgresQueryCompiler(),\n },\n });\n\n case \"mysql\":\n return new Kysely({\n dialect: {\n createAdapter: () => new MysqlAdapter(),\n createDriver: () => new DummyDriver(),\n createIntrospector: (db) => new MysqlIntrospector(db),\n createQueryCompiler: () => new MysqlQueryCompiler(),\n },\n });\n\n case \"sqlite\":\n return new Kysely({\n dialect: {\n createAdapter: () => new SqliteAdapter(),\n createDriver: () => new DummyDriver(),\n createIntrospector: (db) => new SqliteIntrospector(db),\n createQueryCompiler: () => new SqliteQueryCompiler(),\n },\n });\n }\n}\n"],"mappings":";;;;;;;AAsBA,SAAgB,iBAAiB,UAAwC;AACvE,SAAQ,UAAR;EACE,KAAK,aACH,QAAO,IAAI,OAAO,EAChB,SAAS;GACP,qBAAqB,IAAI,iBAAiB;GAC1C,oBAAoB,IAAI,aAAa;GACrC,qBAAqB,OAAO,IAAI,qBAAqB,GAAG;GACxD,2BAA2B,IAAI,uBAAuB;GACvD,EACF,CAAC;EAEJ,KAAK,QACH,QAAO,IAAI,OAAO,EAChB,SAAS;GACP,qBAAqB,IAAI,cAAc;GACvC,oBAAoB,IAAI,aAAa;GACrC,qBAAqB,OAAO,IAAI,kBAAkB,GAAG;GACrD,2BAA2B,IAAI,oBAAoB;GACpD,EACF,CAAC;EAEJ,KAAK,SACH,QAAO,IAAI,OAAO,EAChB,SAAS;GACP,qBAAqB,IAAI,eAAe;GACxC,oBAAoB,IAAI,aAAa;GACrC,qBAAqB,OAAO,IAAI,mBAAmB,GAAG;GACtD,2BAA2B,IAAI,qBAAqB;GACrD,EACF,CAAC"}
1
+ {"version":3,"file":"cold-kysely.js","names":[],"sources":["../../../../src/adapters/generic-sql/migration/cold-kysely.ts"],"sourcesContent":["import {\n DummyDriver,\n Kysely,\n MysqlAdapter,\n MysqlIntrospector,\n MysqlQueryCompiler,\n PostgresAdapter,\n PostgresIntrospector,\n PostgresQueryCompiler,\n SqliteAdapter,\n SqliteIntrospector,\n SqliteQueryCompiler,\n} from \"kysely\";\n\nimport type { SupportedDatabase } from \"../driver-config\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype KyselyAny = Kysely<any>;\n\n/**\n * Creates a Kysely instance that can only build queries, not execute them.\n * This is used for SQL generation without requiring a database connection.\n */\nexport function createColdKysely(database: SupportedDatabase): KyselyAny {\n switch (database) {\n case \"postgresql\":\n return new Kysely({\n dialect: {\n createAdapter: () => new PostgresAdapter(),\n createDriver: () => new DummyDriver(),\n createIntrospector: (db) => new PostgresIntrospector(db),\n createQueryCompiler: () => new PostgresQueryCompiler(),\n },\n });\n\n case \"mysql\":\n return new Kysely({\n dialect: {\n createAdapter: () => new MysqlAdapter(),\n createDriver: () => new DummyDriver(),\n createIntrospector: (db) => new MysqlIntrospector(db),\n createQueryCompiler: () => new MysqlQueryCompiler(),\n },\n });\n\n case \"sqlite\":\n return new Kysely({\n dialect: {\n createAdapter: () => new SqliteAdapter(),\n createDriver: () => new DummyDriver(),\n createIntrospector: (db) => new SqliteIntrospector(db),\n createQueryCompiler: () => new SqliteQueryCompiler(),\n },\n });\n }\n}\n"],"mappings":";;;;;;;AAuBA,SAAgB,iBAAiB,UAAwC;AACvE,SAAQ,UAAR;EACE,KAAK,aACH,QAAO,IAAI,OAAO,EAChB,SAAS;GACP,qBAAqB,IAAI,iBAAiB;GAC1C,oBAAoB,IAAI,aAAa;GACrC,qBAAqB,OAAO,IAAI,qBAAqB,GAAG;GACxD,2BAA2B,IAAI,uBAAuB;GACvD,EACF,CAAC;EAEJ,KAAK,QACH,QAAO,IAAI,OAAO,EAChB,SAAS;GACP,qBAAqB,IAAI,cAAc;GACvC,oBAAoB,IAAI,aAAa;GACrC,qBAAqB,OAAO,IAAI,kBAAkB,GAAG;GACrD,2BAA2B,IAAI,oBAAoB;GACpD,EACF,CAAC;EAEJ,KAAK,SACH,QAAO,IAAI,OAAO,EAChB,SAAS;GACP,qBAAqB,IAAI,eAAe;GACxC,oBAAoB,IAAI,aAAa;GACrC,qBAAqB,OAAO,IAAI,mBAAmB,GAAG;GACtD,2BAA2B,IAAI,qBAAqB;GACrD,EACF,CAAC"}
@@ -1,5 +1,5 @@
1
- import { SQLGenerator } from "../sql-generator.js";
2
1
  import { isUpdated } from "../../../../migration-engine/shared.js";
2
+ import { SQLGenerator } from "../sql-generator.js";
3
3
  import { sql } from "kysely";
4
4
 
5
5
  //#region src/adapters/generic-sql/migration/dialect/mysql.ts
@@ -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\";\n\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":";;;;;AAWA,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"}
@@ -1,5 +1,5 @@
1
- import { SQLGenerator } from "../sql-generator.js";
2
1
  import { isUpdated } from "../../../../migration-engine/shared.js";
2
+ import { SQLGenerator } from "../sql-generator.js";
3
3
  import { sql } from "kysely";
4
4
 
5
5
  //#region src/adapters/generic-sql/migration/dialect/postgres.ts
@@ -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\";\n\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 * 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":";;;;;AAWA,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"}