@fragno-dev/db 0.3.0 → 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 (516) hide show
  1. package/.turbo/turbo-build.log +327 -160
  2. package/CHANGELOG.md +74 -0
  3. package/README.md +24 -0
  4. package/dist/adapters/adapters.d.ts +1 -1
  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/generic-sql-adapter.d.ts +0 -3
  8. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/generic-sql-adapter.js +11 -12
  10. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +46 -6
  12. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  13. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
  14. package/dist/adapters/generic-sql/migration/dialect/mysql.js +1 -1
  15. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  16. package/dist/adapters/generic-sql/migration/dialect/postgres.js +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  18. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +185 -19
  19. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  20. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
  21. package/dist/adapters/generic-sql/migration/executor.js +30 -3
  22. package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +3 -3
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +1 -1
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +1 -1
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  31. package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
  32. package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +9 -6
  34. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +37 -9
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +24 -20
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/uow-decoder.js +1 -1
  41. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  42. package/dist/adapters/generic-sql/uow-encoder.js +8 -9
  43. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  44. package/dist/adapters/in-memory/condition-evaluator.js +10 -6
  45. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -1
  46. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -1
  47. package/dist/adapters/in-memory/in-memory-adapter.js +45 -25
  48. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -1
  49. package/dist/adapters/in-memory/in-memory-uow.js +236 -13
  50. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -1
  51. package/dist/adapters/in-memory/options.d.ts +2 -0
  52. package/dist/adapters/in-memory/options.d.ts.map +1 -1
  53. package/dist/adapters/in-memory/options.js +3 -2
  54. package/dist/adapters/in-memory/options.js.map +1 -1
  55. package/dist/adapters/in-memory/reference-resolution.js.map +1 -1
  56. package/dist/adapters/in-memory/store.js +1 -1
  57. package/dist/adapters/in-memory/store.js.map +1 -1
  58. package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
  59. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  60. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  61. package/dist/browser/adapters/adapters.d.ts +61 -0
  62. package/dist/browser/adapters/adapters.d.ts.map +1 -0
  63. package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
  64. package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  65. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  66. package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  67. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
  68. package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  69. package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
  70. package/dist/browser/adapters/in-memory/index.d.ts +2 -0
  71. package/dist/browser/adapters/in-memory/options.d.ts +1 -0
  72. package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
  73. package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
  74. package/dist/browser/durable-hooks.d.ts +3 -0
  75. package/dist/browser/fragments/internal-fragment.d.ts +317 -0
  76. package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
  77. package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
  78. package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
  79. package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
  80. package/dist/browser/hooks/hooks.d.ts +146 -0
  81. package/dist/browser/hooks/hooks.d.ts.map +1 -0
  82. package/dist/browser/id.js +1 -0
  83. package/dist/browser/internal/adapter-registry.d.ts +4 -0
  84. package/dist/browser/internal/outbox-state.d.ts +2 -0
  85. package/dist/browser/mod.d.ts +15 -0
  86. package/dist/browser/mod.d.ts.map +1 -0
  87. package/dist/browser/mod.js +17 -0
  88. package/dist/browser/mod.js.map +1 -0
  89. package/dist/browser/mod2.d.ts +48 -0
  90. package/dist/browser/mod2.d.ts.map +1 -0
  91. package/dist/browser/naming/sql-naming.d.ts +19 -0
  92. package/dist/browser/naming/sql-naming.d.ts.map +1 -0
  93. package/dist/browser/outbox/outbox.d.ts +21 -0
  94. package/dist/browser/outbox/outbox.d.ts.map +1 -0
  95. package/dist/browser/query/column-defaults.js +1 -0
  96. package/dist/browser/query/condition-builder.d.ts +44 -0
  97. package/dist/browser/query/condition-builder.d.ts.map +1 -0
  98. package/dist/browser/query/condition-builder.js +97 -0
  99. package/dist/browser/query/condition-builder.js.map +1 -0
  100. package/dist/browser/query/cursor.d.ts +105 -0
  101. package/dist/browser/query/cursor.d.ts.map +1 -0
  102. package/dist/browser/query/cursor.js +150 -0
  103. package/dist/browser/query/cursor.js.map +1 -0
  104. package/dist/browser/query/db-now.d.ts +22 -0
  105. package/dist/browser/query/db-now.d.ts.map +1 -0
  106. package/dist/browser/query/db-now.js +33 -0
  107. package/dist/browser/query/db-now.js.map +1 -0
  108. package/dist/browser/query/orm/orm.d.ts +18 -0
  109. package/dist/browser/query/orm/orm.d.ts.map +1 -0
  110. package/dist/browser/query/simple-query-interface.d.ts +108 -0
  111. package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
  112. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
  113. package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  114. package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
  115. package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  116. package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
  117. package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
  118. package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
  119. package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
  120. package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
  121. package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  122. package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
  123. package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
  124. package/dist/browser/query/value-encoding.js +38 -0
  125. package/dist/browser/query/value-encoding.js.map +1 -0
  126. package/dist/browser/schema/create.d.ts +326 -0
  127. package/dist/browser/schema/create.d.ts.map +1 -0
  128. package/dist/browser/schema/create.js +89 -0
  129. package/dist/browser/schema/create.js.map +1 -0
  130. package/dist/browser/schema/generate-id.js +28 -0
  131. package/dist/browser/schema/generate-id.js.map +1 -0
  132. package/dist/browser/shared/providers.d.ts +6 -0
  133. package/dist/browser/shared/providers.d.ts.map +1 -0
  134. package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
  135. package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
  136. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  137. package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  138. package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
  139. package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  140. package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
  141. package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
  142. package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
  143. package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  144. package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
  145. package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  146. package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
  147. package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
  148. package/dist/browser/sync/commands.d.ts +15 -0
  149. package/dist/browser/sync/commands.d.ts.map +1 -0
  150. package/dist/browser/sync/commands.js +27 -0
  151. package/dist/browser/sync/commands.js.map +1 -0
  152. package/dist/browser/sync/types.d.ts +63 -0
  153. package/dist/browser/sync/types.d.ts.map +1 -0
  154. package/dist/browser/util/types.d.ts +8 -0
  155. package/dist/browser/util/types.d.ts.map +1 -0
  156. package/dist/browser/with-database.d.ts +29 -0
  157. package/dist/browser/with-database.d.ts.map +1 -0
  158. package/dist/client.d.ts +4 -0
  159. package/dist/client.js +5 -0
  160. package/dist/db-fragment-definition-builder.d.ts +85 -28
  161. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  162. package/dist/db-fragment-definition-builder.js +374 -46
  163. package/dist/db-fragment-definition-builder.js.map +1 -1
  164. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
  165. package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
  166. package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
  167. package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
  168. package/dist/dispatchers/cloudflare-do/index.d.ts +5 -20
  169. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -1
  170. package/dist/dispatchers/cloudflare-do/index.js +23 -55
  171. package/dist/dispatchers/cloudflare-do/index.js.map +1 -1
  172. package/dist/dispatchers/node/dispatcher.d.ts +14 -0
  173. package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
  174. package/dist/dispatchers/node/dispatcher.js +80 -0
  175. package/dist/dispatchers/node/dispatcher.js.map +1 -0
  176. package/dist/dispatchers/node/index.d.ts +5 -10
  177. package/dist/dispatchers/node/index.d.ts.map +1 -1
  178. package/dist/dispatchers/node/index.js +21 -53
  179. package/dist/dispatchers/node/index.js.map +1 -1
  180. package/dist/durable-hooks.d.ts +31 -0
  181. package/dist/durable-hooks.d.ts.map +1 -0
  182. package/dist/durable-hooks.js +23 -0
  183. package/dist/durable-hooks.js.map +1 -0
  184. package/dist/fragments/internal-fragment.d.ts +128 -27
  185. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  186. package/dist/fragments/internal-fragment.js +125 -78
  187. package/dist/fragments/internal-fragment.js.map +1 -1
  188. package/dist/fragments/internal-fragment.routes.js +138 -3
  189. package/dist/fragments/internal-fragment.routes.js.map +1 -1
  190. package/dist/fragments/internal-fragment.schema.d.ts +7 -1
  191. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -1
  192. package/dist/fragments/internal-fragment.schema.js +18 -1
  193. package/dist/fragments/internal-fragment.schema.js.map +1 -1
  194. package/dist/hooks/durable-hooks-logger.d.ts +10 -0
  195. package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
  196. package/dist/hooks/durable-hooks-logger.js +75 -0
  197. package/dist/hooks/durable-hooks-logger.js.map +1 -0
  198. package/dist/hooks/durable-hooks-processor.d.ts +1 -14
  199. package/dist/hooks/durable-hooks-processor.js +58 -10
  200. package/dist/hooks/durable-hooks-processor.js.map +1 -1
  201. package/dist/hooks/durable-hooks-runtime.js +44 -0
  202. package/dist/hooks/durable-hooks-runtime.js.map +1 -0
  203. package/dist/hooks/hooks.d.ts +60 -2
  204. package/dist/hooks/hooks.d.ts.map +1 -1
  205. package/dist/hooks/hooks.js +214 -53
  206. package/dist/hooks/hooks.js.map +1 -1
  207. package/dist/id.d.ts +2 -2
  208. package/dist/id.js +2 -2
  209. package/dist/internal/adapter-registry.d.ts +11 -0
  210. package/dist/internal/adapter-registry.d.ts.map +1 -0
  211. package/dist/internal/adapter-registry.js +135 -0
  212. package/dist/internal/adapter-registry.js.map +1 -0
  213. package/dist/internal/outbox-state.d.ts +2 -0
  214. package/dist/internal/outbox-state.js +26 -0
  215. package/dist/internal/outbox-state.js.map +1 -0
  216. package/dist/migration-engine/auto-from-schema.d.ts +33 -0
  217. package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
  218. package/dist/migration-engine/auto-from-schema.js +210 -27
  219. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  220. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  221. package/dist/migration-engine/generation-engine.js +17 -5
  222. package/dist/migration-engine/generation-engine.js.map +1 -1
  223. package/dist/migration-engine/shared.d.ts +113 -0
  224. package/dist/migration-engine/shared.d.ts.map +1 -0
  225. package/dist/migration-engine/shared.js.map +1 -1
  226. package/dist/mod.d.ts +12 -11
  227. package/dist/mod.d.ts.map +1 -1
  228. package/dist/mod.js +10 -10
  229. package/dist/mod.js.map +1 -1
  230. package/dist/naming/sql-naming.d.ts.map +1 -1
  231. package/dist/naming/sql-naming.js.map +1 -1
  232. package/dist/outbox/outbox-builder.js.map +1 -1
  233. package/dist/outbox/outbox.d.ts +3 -1
  234. package/dist/outbox/outbox.d.ts.map +1 -1
  235. package/dist/outbox/outbox.js.map +1 -1
  236. package/dist/query/column-defaults.js.map +1 -1
  237. package/dist/query/condition-builder.d.ts +7 -1
  238. package/dist/query/condition-builder.d.ts.map +1 -1
  239. package/dist/query/condition-builder.js +5 -1
  240. package/dist/query/condition-builder.js.map +1 -1
  241. package/dist/query/cursor-client.d.ts +105 -0
  242. package/dist/query/cursor-client.d.ts.map +1 -0
  243. package/dist/query/cursor-client.js +165 -0
  244. package/dist/query/cursor-client.js.map +1 -0
  245. package/dist/query/cursor.d.ts.map +1 -1
  246. package/dist/query/cursor.js +7 -1
  247. package/dist/query/cursor.js.map +1 -1
  248. package/dist/query/db-now.d.ts +15 -1
  249. package/dist/query/db-now.d.ts.map +1 -1
  250. package/dist/query/db-now.js +30 -2
  251. package/dist/query/db-now.js.map +1 -1
  252. package/dist/query/orm/orm.js.map +1 -1
  253. package/dist/query/serialize/create-sql-serializer.js +2 -2
  254. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  255. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  256. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  257. package/dist/query/serialize/dialect/sqlite-serializer.js +6 -2
  258. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  259. package/dist/query/simple-query-interface.d.ts +7 -3
  260. package/dist/query/simple-query-interface.d.ts.map +1 -1
  261. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
  262. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  263. package/dist/query/unit-of-work/execute-unit-of-work.js +39 -18
  264. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  265. package/dist/query/unit-of-work/unit-of-work.d.ts +42 -16
  266. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  267. package/dist/query/unit-of-work/unit-of-work.js +50 -6
  268. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  269. package/dist/query/value-decoding.js +8 -1
  270. package/dist/query/value-decoding.js.map +1 -1
  271. package/dist/query/value-encoding.js.map +1 -1
  272. package/dist/schema/create.d.ts +69 -25
  273. package/dist/schema/create.d.ts.map +1 -1
  274. package/dist/schema/create.js +91 -16
  275. package/dist/schema/create.js.map +1 -1
  276. package/dist/schema/type-conversion/create-sql-type-mapper.js +1 -1
  277. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  278. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  279. package/dist/schema/validator.d.ts.map +1 -1
  280. package/dist/schema/validator.js.map +1 -1
  281. package/dist/schema-output/drizzle.d.ts.map +1 -1
  282. package/dist/schema-output/drizzle.js +8 -6
  283. package/dist/schema-output/drizzle.js.map +1 -1
  284. package/dist/schema-output/prisma.d.ts.map +1 -1
  285. package/dist/schema-output/prisma.js +21 -10
  286. package/dist/schema-output/prisma.js.map +1 -1
  287. package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
  288. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
  289. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
  290. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
  291. package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
  292. package/dist/sql-driver/sql.js.map +1 -1
  293. package/dist/sync/commands.d.ts +15 -0
  294. package/dist/sync/commands.d.ts.map +1 -0
  295. package/dist/sync/commands.js +27 -0
  296. package/dist/sync/commands.js.map +1 -0
  297. package/dist/sync/index.d.ts +4 -0
  298. package/dist/sync/index.js +4 -0
  299. package/dist/sync/read-tracking.d.ts +25 -0
  300. package/dist/sync/read-tracking.d.ts.map +1 -0
  301. package/dist/sync/read-tracking.js +148 -0
  302. package/dist/sync/read-tracking.js.map +1 -0
  303. package/dist/sync/submit.js +213 -0
  304. package/dist/sync/submit.js.map +1 -0
  305. package/dist/sync/types.d.ts +63 -0
  306. package/dist/sync/types.d.ts.map +1 -0
  307. package/dist/util/default-database-adapter.js +6 -1
  308. package/dist/util/default-database-adapter.js.map +1 -1
  309. package/dist/with-database.d.ts +3 -6
  310. package/dist/with-database.d.ts.map +1 -1
  311. package/dist/with-database.js +7 -15
  312. package/dist/with-database.js.map +1 -1
  313. package/package.json +33 -41
  314. package/src/adapters/adapters.ts +5 -4
  315. package/src/adapters/drizzle/migrate-drizzle.test.ts +46 -9
  316. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +5 -3
  317. package/src/adapters/drizzle/test-utils.ts +2 -1
  318. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -3
  319. package/src/adapters/generic-sql/generic-sql-adapter.ts +21 -24
  320. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +1 -0
  321. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +81 -15
  322. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +4 -2
  323. package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
  324. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +3 -2
  325. package/src/adapters/generic-sql/migration/dialect/mysql.ts +1 -0
  326. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +5 -4
  327. package/src/adapters/generic-sql/migration/dialect/postgres.ts +2 -1
  328. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +795 -3
  329. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +385 -57
  330. package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
  331. package/src/adapters/generic-sql/migration/executor.ts +47 -4
  332. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +117 -14
  333. package/src/adapters/generic-sql/migration/prepared-migrations.ts +9 -8
  334. package/src/adapters/generic-sql/migration/sql-generator.ts +5 -3
  335. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +3 -3
  336. package/src/adapters/generic-sql/query/cursor-utils.test.ts +3 -2
  337. package/src/adapters/generic-sql/query/cursor-utils.ts +1 -1
  338. package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
  339. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +144 -8
  340. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +16 -17
  341. package/src/adapters/generic-sql/query/select-builder.test.ts +1 -0
  342. package/src/adapters/generic-sql/query/select-builder.ts +2 -2
  343. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +24 -5
  344. package/src/adapters/generic-sql/query/sql-query-compiler.ts +83 -13
  345. package/src/adapters/generic-sql/query/where-builder.test.ts +7 -5
  346. package/src/adapters/generic-sql/query/where-builder.ts +48 -29
  347. package/src/adapters/generic-sql/sql-adapter-pglite-migrations.test.ts +6 -15
  348. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +52 -7
  349. package/src/adapters/generic-sql/sql-adapter-pglite-queries.test.ts +9 -6
  350. package/src/adapters/generic-sql/sql-adapter-sqlite3-driver.test.ts +273 -5
  351. package/src/adapters/generic-sql/sql-adapter-sqlite3-uow.test.ts +123 -6
  352. package/src/adapters/generic-sql/sql-adapter-sqlocal.test.ts +4 -2
  353. package/src/adapters/generic-sql/uow-decoder.test.ts +4 -3
  354. package/src/adapters/generic-sql/uow-decoder.ts +3 -3
  355. package/src/adapters/generic-sql/uow-encoder.test.ts +4 -2
  356. package/src/adapters/generic-sql/uow-encoder.ts +14 -18
  357. package/src/adapters/in-memory/condition-evaluator.test.ts +2 -1
  358. package/src/adapters/in-memory/condition-evaluator.ts +9 -4
  359. package/src/adapters/in-memory/in-memory-adapter.ts +155 -44
  360. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +50 -2
  361. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +158 -3
  362. package/src/adapters/in-memory/in-memory-uow.ts +402 -26
  363. package/src/adapters/in-memory/options.test.ts +1 -0
  364. package/src/adapters/in-memory/options.ts +5 -1
  365. package/src/adapters/in-memory/outbox.test.ts +361 -0
  366. package/src/adapters/in-memory/reference-resolution.test.ts +3 -2
  367. package/src/adapters/in-memory/reference-resolution.ts +2 -2
  368. package/src/adapters/in-memory/sorted-array-index.test.ts +1 -0
  369. package/src/adapters/in-memory/store.test.ts +1 -0
  370. package/src/adapters/in-memory/store.ts +3 -3
  371. package/src/adapters/in-memory/value-normalization.test.ts +1 -0
  372. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +51 -7
  373. package/src/adapters/shared/from-unit-of-work-compiler.ts +156 -46
  374. package/src/adapters/shared/uow-operation-compiler.ts +3 -3
  375. package/src/browser/mod.ts +64 -0
  376. package/src/client.ts +19 -0
  377. package/src/db-fragment-definition-builder.test.ts +821 -47
  378. package/src/db-fragment-definition-builder.ts +857 -110
  379. package/src/db-fragment-instantiator.test.ts +114 -90
  380. package/src/db-fragment-integration.test.ts +9 -6
  381. package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
  382. package/src/dispatchers/cloudflare-do/index.test.ts +145 -12
  383. package/src/dispatchers/cloudflare-do/index.ts +49 -90
  384. package/src/dispatchers/node/dispatcher.ts +112 -0
  385. package/src/dispatchers/node/index.test.ts +43 -14
  386. package/src/dispatchers/node/index.ts +38 -75
  387. package/src/durable-hooks.test.ts +80 -0
  388. package/src/durable-hooks.ts +67 -0
  389. package/src/fragments/internal-fragment.routes.test.ts +570 -0
  390. package/src/fragments/internal-fragment.routes.ts +297 -5
  391. package/src/fragments/internal-fragment.schema.ts +45 -1
  392. package/src/fragments/internal-fragment.test.ts +223 -251
  393. package/src/fragments/internal-fragment.ts +278 -154
  394. package/src/hooks/durable-hooks-logger.ts +126 -0
  395. package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
  396. package/src/hooks/durable-hooks-processor.test.ts +179 -14
  397. package/src/hooks/durable-hooks-processor.ts +120 -14
  398. package/src/hooks/durable-hooks-runtime.test.ts +65 -0
  399. package/src/hooks/durable-hooks-runtime.ts +81 -0
  400. package/src/hooks/hooks.test.ts +314 -53
  401. package/src/hooks/hooks.ts +360 -81
  402. package/src/id.test.ts +34 -0
  403. package/src/id.ts +1 -3
  404. package/src/internal/adapter-registry.test.ts +93 -0
  405. package/src/internal/adapter-registry.ts +239 -0
  406. package/src/internal/outbox-state.ts +43 -0
  407. package/src/migration-engine/auto-from-schema.test.ts +93 -0
  408. package/src/migration-engine/auto-from-schema.ts +360 -42
  409. package/src/migration-engine/create.test.ts +2 -1
  410. package/src/migration-engine/create.ts +1 -1
  411. package/src/migration-engine/generation-engine.test.ts +66 -9
  412. package/src/migration-engine/generation-engine.ts +31 -10
  413. package/src/migration-engine/shared.ts +13 -0
  414. package/src/mod.ts +45 -27
  415. package/src/naming/sql-naming.ts +1 -0
  416. package/src/outbox/outbox-builder.ts +2 -2
  417. package/src/outbox/outbox.test.ts +216 -45
  418. package/src/outbox/outbox.ts +3 -1
  419. package/src/query/column-defaults.ts +1 -1
  420. package/src/query/condition-builder.test.ts +15 -0
  421. package/src/query/condition-builder.ts +7 -0
  422. package/src/query/cursor-client.test.ts +70 -0
  423. package/src/query/cursor-client.ts +263 -0
  424. package/src/query/cursor.test.ts +3 -2
  425. package/src/query/cursor.ts +15 -3
  426. package/src/query/db-now.ts +69 -2
  427. package/src/query/orm/orm.ts +2 -2
  428. package/src/query/query-type.test.ts +2 -1
  429. package/src/query/serialize/create-sql-serializer.ts +3 -3
  430. package/src/query/serialize/dialect/mysql-serializer.ts +1 -1
  431. package/src/query/serialize/dialect/postgres-serializer.ts +1 -1
  432. package/src/query/serialize/dialect/sqlite-serializer.test.ts +39 -2
  433. package/src/query/serialize/dialect/sqlite-serializer.ts +18 -5
  434. package/src/query/simple-query-interface.ts +10 -4
  435. package/src/query/unit-of-work/execute-unit-of-work.test.ts +347 -9
  436. package/src/query/unit-of-work/execute-unit-of-work.ts +63 -20
  437. package/src/query/unit-of-work/retry-policy.test.ts +1 -0
  438. package/src/query/unit-of-work/tx-builder.test.ts +73 -1
  439. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +5 -4
  440. package/src/query/unit-of-work/unit-of-work-types.test.ts +41 -11
  441. package/src/query/unit-of-work/unit-of-work.test.ts +28 -2
  442. package/src/query/unit-of-work/unit-of-work.ts +105 -19
  443. package/src/query/value-decoding.test.ts +50 -2
  444. package/src/query/value-decoding.ts +17 -4
  445. package/src/query/value-encoding.test.ts +1 -0
  446. package/src/query/value-encoding.ts +1 -1
  447. package/src/schema/create.test.ts +164 -5
  448. package/src/schema/create.ts +222 -24
  449. package/src/schema/generate-id.test.ts +1 -0
  450. package/src/schema/serialize.test.ts +4 -3
  451. package/src/schema/type-conversion/create-sql-type-mapper.ts +1 -1
  452. package/src/schema/type-conversion/dialect/sqlite.ts +2 -2
  453. package/src/schema/type-conversion/type-mapping.test.ts +2 -1
  454. package/src/schema/validator.test.ts +4 -2
  455. package/src/schema/validator.ts +1 -0
  456. package/src/schema-output/drizzle.test.ts +72 -19
  457. package/src/schema-output/drizzle.ts +24 -18
  458. package/src/schema-output/prisma.test.ts +172 -14
  459. package/src/schema-output/prisma.ts +34 -14
  460. package/src/sql-driver/better-sqlite3.test.ts +5 -3
  461. package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
  462. package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
  463. package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
  464. package/src/sql-driver/query-executor/query-executor.ts +1 -1
  465. package/src/sql-driver/sql-driver-adapter.ts +2 -2
  466. package/src/sql-driver/sql.ts +2 -1
  467. package/src/sql-driver/sqlocal.test.ts +4 -2
  468. package/src/sync/commands.test.ts +39 -0
  469. package/src/sync/commands.ts +51 -0
  470. package/src/sync/conflict-checker.test.ts +450 -0
  471. package/src/sync/conflict-checker.ts +248 -0
  472. package/src/sync/index.ts +14 -0
  473. package/src/sync/plan.ts +9 -0
  474. package/src/sync/read-tracking.test.ts +177 -0
  475. package/src/sync/read-tracking.ts +287 -0
  476. package/src/sync/submit.test.ts +205 -0
  477. package/src/sync/submit.ts +328 -0
  478. package/src/sync/types.ts +80 -0
  479. package/src/util/default-database-adapter.ts +15 -2
  480. package/src/with-database.ts +20 -50
  481. package/tsconfig.json +1 -1
  482. package/tsdown.config.ts +38 -26
  483. package/vitest.config.ts +1 -0
  484. package/dist/hooks/durable-hooks-processor.d.ts.map +0 -1
  485. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js +0 -168
  486. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +0 -1
  487. package/dist/packages/fragno/dist/api/bind-services.js +0 -20
  488. package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
  489. package/dist/packages/fragno/dist/api/error.js +0 -48
  490. package/dist/packages/fragno/dist/api/error.js.map +0 -1
  491. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -321
  492. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
  493. package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -669
  494. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
  495. package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
  496. package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
  497. package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
  498. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
  499. package/dist/packages/fragno/dist/api/internal/route.js +0 -10
  500. package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
  501. package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
  502. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
  503. package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
  504. package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
  505. package/dist/packages/fragno/dist/api/request-input-context.js +0 -185
  506. package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
  507. package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
  508. package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
  509. package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
  510. package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
  511. package/dist/packages/fragno/dist/api/route.js +0 -30
  512. package/dist/packages/fragno/dist/api/route.js.map +0 -1
  513. package/dist/packages/fragno/dist/internal/symbols.js +0 -10
  514. package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
  515. package/dist/packages/fragno/dist/internal/trace-context.js +0 -12
  516. package/dist/packages/fragno/dist/internal/trace-context.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,79 @@
1
1
  # @fragno-dev/db
2
2
 
3
+ ## 0.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [0020e39]
8
+ - @fragno-dev/core@0.2.2
9
+
10
+ ## 0.4.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 8a96998: feat: allow altering existing columns to become nullable
15
+
16
+ ### Patch Changes
17
+
18
+ - 3e2ff94: feat: register schemas via adapter registry and mount internal routes
19
+ - f34d7d7: fix: ensure cross-schema durable hook enqueuing works reliably
20
+ - 4d141f8: fix: remove development exports from published packages
21
+ - c8841b5: feat: add callServices helper with implicit request context
22
+ - ae54a60: fix: add browser-safe db entry and rewrite sync command imports for browser builds
23
+ - 7dd7055: feat: remove deps.db and add db-time helpers on builders
24
+ - e178bf4: fix: treat missing left-joined relations as null/[]
25
+ - d2f68ba: feat: add db now offsets and interval helpers
26
+ - 75191db: fix: return fresh DO SQL connections per acquire
27
+ - d395ad2: fix: improve durable hook claiming and wake scheduling
28
+ - 75407f3: feat: add durable hook pagination and newest-first indexing
29
+ - bfdd4b1: fix: skip better-sqlite3 fallback in Cloudflare workers
30
+ - 3ffa711: fix: align dev browser exports to avoid server entry in clients
31
+ - c2c3229: fix: ignore join-only relations in in-memory FK enforcement
32
+ - e559425: feat: add serviceCalls helper to preserve tuple inference for service deps
33
+ - fc5c256: fix(fragno-db): decode bigint values from SQLite blob columns
34
+ - 93fa469: fix: replace cuid2 with a shared Web Crypto id generator
35
+ - 14e00b1: feat: expose hook event metadata in HookContext
36
+ - f33286c: feat: add join-only addReference foreignKey:false support
37
+ - 95cdf95: feat: add browser-safe client exports entrypoint
38
+ - eabdb9c: feat(db): add in-memory outbox support
39
+ - 9eeba53: feat: add internal fragment describe metadata and adapter identity
40
+ - 49a9f4f: feat: add internal outbox mutation log and sync request tables
41
+ - dcba383: fix: write outbox mutation log rows during commits
42
+ - c895c07: feat(db): add internal sync submit endpoint and idempotency
43
+ - ed4b4a0: fix: add workerd/worker export conditions for server entry resolution
44
+ - 1102ce0: fix: support multi-column cursor pagination for SQL adapters
45
+ - ad2ef56: feat: move outbox opt-in to fragment options
46
+ - 0f9b7ef: refactor: replace linked fragments with internal routes
47
+ - 6d043ea: feat: add durable hooks runtime and dispatcher helpers
48
+ - fe55a13: feat(db): add read tracking hooks and plan mode support
49
+ - 01fc2cb: fix: scope db roundtrip guard to route handlers and enable by default in tests
50
+ - 0176aa8: fix: coerce join-only left-side ids and join where aliases
51
+ - 00f2631: feat: allow triggerHook to accept explicit hook ids
52
+ - c13c1c1: fix: handle sqlite FK preprocessing when FK columns are added in alter-table
53
+ - 0a6c8da: fix: stabilize sqlite recreate-table migrations
54
+ - 7a40517: fix: stabilize schema output ordering by schema name
55
+ - 91a2ac0: feat: add WorkflowStepTx API for step-scoped mutations
56
+ - 7bda0b2: feat(db): add sync command registry, registration, and sync entrypoint
57
+ - c115600: feat: widen external ids to 128 chars
58
+ - Updated dependencies [3e2ff94]
59
+ - Updated dependencies [f34d7d7]
60
+ - Updated dependencies [4d141f8]
61
+ - Updated dependencies [c8841b5]
62
+ - Updated dependencies [83f6223]
63
+ - Updated dependencies [567c3b3]
64
+ - Updated dependencies [8a2da9d]
65
+ - Updated dependencies [93fa469]
66
+ - Updated dependencies [b3ad7eb]
67
+ - Updated dependencies [9eeba53]
68
+ - Updated dependencies [2ae432c]
69
+ - Updated dependencies [9f87189]
70
+ - Updated dependencies [0f9b7ef]
71
+ - Updated dependencies [f4aedad]
72
+ - Updated dependencies [f042c9d]
73
+ - Updated dependencies [7bda0b2]
74
+ - Updated dependencies [b84a3d0]
75
+ - @fragno-dev/core@0.2.1
76
+
3
77
  ## 0.3.0
4
78
 
5
79
  ### Minor Changes
package/README.md CHANGED
@@ -124,6 +124,30 @@ const commentLib = createCommentLibrary(
124
124
  - **ORM agnostic**: SQL runtime with explicit schema output formats (SQL, Drizzle, Prisma).
125
125
  - **Namespaced tables**: avoids conflicts with user tables.
126
126
 
127
+ ## Internal registry + describe route
128
+
129
+ When multiple fragments share a database adapter, Fragno maintains an in-memory, adapter-scoped
130
+ registry of schemas and fragment mount routes. Each fragment exposes a lightweight internal describe
131
+ endpoint at `/_internal` (mounted under the fragment's mount route) that aggregates this registry.
132
+
133
+ Example response:
134
+
135
+ ```json
136
+ {
137
+ "fragments": [{ "name": "comment-library", "mountRoute": "/api/comment-library" }],
138
+ "schemas": [
139
+ { "name": "comment", "namespace": "comment", "version": 1, "tables": ["comment", "user"] }
140
+ ],
141
+ "routes": { "internal": "/_internal", "outbox": "/_internal/outbox" }
142
+ }
143
+ ```
144
+
145
+ Notes:
146
+
147
+ - `schemas` excludes the internal Fragno schema.
148
+ - `fragments` only includes fragments that opted into outbox support via fragment options.
149
+ - `routes.outbox` is only present when at least one fragment has outbox enabled.
150
+
127
151
  ## ORM and database support
128
152
 
129
153
  `@fragno-dev/db` works with Kysely dialects for runtime execution and supports SQL migrations plus
@@ -3,8 +3,8 @@ import { SqlNamingStrategy } from "../naming/sql-naming.js";
3
3
  import { SQLiteStorageMode } from "./generic-sql/sqlite-storage.js";
4
4
  import { IUnitOfWork } from "../query/unit-of-work/unit-of-work.js";
5
5
  import { SimpleQueryInterface } from "../query/simple-query-interface.js";
6
- import { PreparedMigrations } from "./generic-sql/migration/prepared-migrations.js";
7
6
  import { SQLProvider } from "../shared/providers.js";
7
+ import { PreparedMigrations } from "./generic-sql/migration/prepared-migrations.js";
8
8
  import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
9
9
 
10
10
  //#region src/adapters/adapters.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.d.ts","names":[],"sources":["../../src/adapters/adapters.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cASa;cACA;AADb;AACA;AAMA;AAIA;AAEiB,KANL,sBAAA,GAM4B;EACvB,GAAA,EANV,WAMU;CACC;AACI,KALV,aAAA,GAKU,SAAA,GAAA,QAAA;AAAiB,UAHtB,uBAAA,CAGsB;EAGtB,YAAA,CAAA,EALA,WAKe;EAC7B,aAAA,CAAA,EALe,aAKf;EACA,iBAAA,CAAA,EALmB,iBAKnB;;AAMwB,UARV,eAQU,CAAA,aAAA,IAAA,CAAA,CAAA;EAMwB,CAbhD,mCAAA,CAagD,EAAA,MAAA;EAAhB,CAZhC,sCAAA,CAYgC,EAAA,MAAA;EAKI;;;;EAgB3B,SAAA,cAAA,EA3Be,qBA2Bf,CA3BqC,sBA2BrC,CAAA;EAEgB;;;;EAGhB,wBAAA,CAAA,EAAA,GAAA,GA1BuB,eA0BvB,CA1BuC,UA0BvC,CAAA;EAEL;;;EAIe,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EA3BiB,OA2BjB,CAAA,MAAA,GAAA,SAAA,CAAA;;;;6BAtBO;;;;2BAKF;;;;sCAKW,mBAC1B,gCAEL,qBAAqB,GAAG;uCAEQ,mBAC3B,gCAEL;6BAEsB;eAEd"}
1
+ {"version":3,"file":"adapters.d.ts","names":[],"sources":["../../src/adapters/adapters.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAUa;cACA;AADb;AACA;AAMA;AAIA;AAEiB,KANL,sBAAA,GAM4B;EACvB,GAAA,EANV,WAMU;CACC;AACI,KALV,aAAA,GAKU,SAAA,GAAA,QAAA;AAAiB,UAHtB,uBAAA,CAGsB;EAGtB,YAAA,CAAA,EALA,WAKe;EAC7B,aAAA,CAAA,EALe,aAKf;EACA,iBAAA,CAAA,EALmB,iBAKnB;;AAMwB,UARV,eAQU,CAAA,aAAA,IAAA,CAAA,CAAA;EAMwB,CAbhD,mCAAA,CAagD,EAAA,MAAA;EAAhB,CAZhC,sCAAA,CAYgC,EAAA,MAAA;EAKI;;;;EAgB3B,SAAA,cAAA,EA3Be,qBA2Bf,CA3BqC,sBA2BrC,CAAA;EAEgB;;;;EAGhB,wBAAA,CAAA,EAAA,GAAA,GA1BuB,eA0BvB,CA1BuC,UA0BvC,CAAA;EAEL;;;EAIe,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EA3BiB,OA2BjB,CAAA,MAAA,GAAA,SAAA,CAAA;;;;6BAtBO;;;;2BAKF;;;;sCAKW,mBAC1B,gCAEL,qBAAqB,GAAG;uCAEQ,mBAC3B,gCAEL;6BAEsB;eAEd"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapters.js","names":[],"sources":["../../src/adapters/adapters.ts"],"sourcesContent":["import type { SimpleQueryInterface } from \"../query/simple-query-interface\";\nimport type { AnySchema } from \"../schema/create\";\nimport type { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\nimport type { IUnitOfWork } from \"../query/unit-of-work/unit-of-work\";\nimport type { PreparedMigrations } from \"./generic-sql/migration/prepared-migrations\";\nimport type { SQLProvider } from \"../shared/providers\";\nimport type { SQLiteStorageMode } from \"./generic-sql/sqlite-storage\";\nimport type { SqlNamingStrategy } from \"../naming/sql-naming\";\n\nexport const fragnoDatabaseAdapterNameFakeSymbol = \"$fragno-database-adapter-name\" as const;\nexport const fragnoDatabaseAdapterVersionFakeSymbol = \"$fragno-database-adapter-version\" as const;\n\n/**\n * Storage type for database context - stores the Unit of Work.\n * This is shared across all fragments using the same adapter.\n */\nexport type DatabaseContextStorage = {\n uow: IUnitOfWork;\n};\n\nexport type SQLiteProfile = \"default\" | \"prisma\";\n\nexport interface DatabaseAdapterMetadata {\n databaseType?: SQLProvider;\n sqliteProfile?: SQLiteProfile;\n sqliteStorageMode?: SQLiteStorageMode;\n}\n\nexport interface DatabaseAdapter<TUOWConfig = void> {\n [fragnoDatabaseAdapterNameFakeSymbol]: string;\n [fragnoDatabaseAdapterVersionFakeSymbol]: number;\n\n /**\n * Request context storage shared across all fragments using this adapter.\n * This allows multiple fragments to participate in the same Unit of Work.\n */\n readonly contextStorage: RequestContextStorage<DatabaseContextStorage>;\n\n /**\n * Optional adapter override used for durable hook processing.\n * Use this when the public adapter wraps another adapter (e.g. model checker).\n */\n getHookProcessingAdapter?: () => DatabaseAdapter<TUOWConfig>;\n\n /**\n * Get current schema version, undefined if not initialized.\n */\n getSchemaVersion(namespace: string): Promise<string | undefined>;\n\n /**\n * Optional metadata used by schema output tooling.\n */\n readonly adapterMetadata?: DatabaseAdapterMetadata;\n\n /**\n * Naming strategy used for physical SQL identifiers.\n */\n readonly namingStrategy: SqlNamingStrategy;\n\n /**\n * @deprecated Avoid using query engines directly in fragment code. Prefer handlerTx/serviceTx.\n */\n createQueryEngine: <const T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ) => SimpleQueryInterface<T, TUOWConfig>;\n\n prepareMigrations?: <const T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ) => PreparedMigrations;\n\n isConnectionHealthy: () => Promise<boolean>;\n\n close: () => Promise<void>;\n}\n"],"mappings":";AASA,MAAa,sCAAsC;AACnD,MAAa,yCAAyC"}
1
+ {"version":3,"file":"adapters.js","names":[],"sources":["../../src/adapters/adapters.ts"],"sourcesContent":["import type { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\n\nimport type { SqlNamingStrategy } from \"../naming/sql-naming\";\nimport type { SimpleQueryInterface } from \"../query/simple-query-interface\";\nimport type { IUnitOfWork } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema } from \"../schema/create\";\nimport type { SQLProvider } from \"../shared/providers\";\nimport type { PreparedMigrations } from \"./generic-sql/migration/prepared-migrations\";\nimport type { SQLiteStorageMode } from \"./generic-sql/sqlite-storage\";\n\nexport const fragnoDatabaseAdapterNameFakeSymbol = \"$fragno-database-adapter-name\" as const;\nexport const fragnoDatabaseAdapterVersionFakeSymbol = \"$fragno-database-adapter-version\" as const;\n\n/**\n * Storage type for database context - stores the Unit of Work.\n * This is shared across all fragments using the same adapter.\n */\nexport type DatabaseContextStorage = {\n uow: IUnitOfWork;\n};\n\nexport type SQLiteProfile = \"default\" | \"prisma\";\n\nexport interface DatabaseAdapterMetadata {\n databaseType?: SQLProvider;\n sqliteProfile?: SQLiteProfile;\n sqliteStorageMode?: SQLiteStorageMode;\n}\n\nexport interface DatabaseAdapter<TUOWConfig = void> {\n [fragnoDatabaseAdapterNameFakeSymbol]: string;\n [fragnoDatabaseAdapterVersionFakeSymbol]: number;\n\n /**\n * Request context storage shared across all fragments using this adapter.\n * This allows multiple fragments to participate in the same Unit of Work.\n */\n readonly contextStorage: RequestContextStorage<DatabaseContextStorage>;\n\n /**\n * Optional adapter override used for durable hook processing.\n * Use this when the public adapter wraps another adapter (e.g. model checker).\n */\n getHookProcessingAdapter?: () => DatabaseAdapter<TUOWConfig>;\n\n /**\n * Get current schema version, undefined if not initialized.\n */\n getSchemaVersion(namespace: string): Promise<string | undefined>;\n\n /**\n * Optional metadata used by schema output tooling.\n */\n readonly adapterMetadata?: DatabaseAdapterMetadata;\n\n /**\n * Naming strategy used for physical SQL identifiers.\n */\n readonly namingStrategy: SqlNamingStrategy;\n\n /**\n * @deprecated Avoid using query engines directly in fragment code. Prefer handlerTx/serviceTx.\n */\n createQueryEngine: <const T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ) => SimpleQueryInterface<T, TUOWConfig>;\n\n prepareMigrations?: <const T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ) => PreparedMigrations;\n\n isConnectionHealthy: () => Promise<boolean>;\n\n close: () => Promise<void>;\n}\n"],"mappings":";AAUA,MAAa,sCAAsC;AACnD,MAAa,yCAAyC"}
@@ -21,7 +21,6 @@ interface SqlAdapterOptions {
21
21
  dialect: Dialect;
22
22
  driverConfig: DriverConfig;
23
23
  uowConfig?: UnitOfWorkConfig;
24
- outbox?: OutboxConfig;
25
24
  sqliteProfile?: SQLiteProfile;
26
25
  sqliteStorageMode?: SQLiteStorageMode;
27
26
  namingStrategy?: SqlNamingStrategy;
@@ -32,7 +31,6 @@ declare class SqlAdapter implements DatabaseAdapter<UnitOfWorkConfig> {
32
31
  readonly dialect: Dialect;
33
32
  readonly driverConfig: DriverConfig;
34
33
  readonly uowConfig?: UnitOfWorkConfig;
35
- readonly outbox?: OutboxConfig;
36
34
  readonly sqliteStorageMode?: SQLiteStorageMode;
37
35
  readonly sqliteProfile?: SQLiteProfile;
38
36
  readonly adapterMetadata: DatabaseAdapterMetadata;
@@ -41,7 +39,6 @@ declare class SqlAdapter implements DatabaseAdapter<UnitOfWorkConfig> {
41
39
  dialect,
42
40
  driverConfig,
43
41
  uowConfig,
44
- outbox,
45
42
  sqliteProfile,
46
43
  sqliteStorageMode,
47
44
  namingStrategy
@@ -1 +1 @@
1
- {"version":3,"file":"generic-sql-adapter.d.ts","names":[],"sources":["../../../src/adapters/generic-sql/generic-sql-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;UAmCiB,gBAAA;oBACG;EADH,MAAA,CAAA,EAAA,OAAA;EAMA,eAAA,CAAA,EAHG,kBAGc;;AAElB,UAFC,iBAAA,CAED;EACF,OAAA,EAFH,OAEG;EACH,YAAA,EAFK,YAEL;EACO,SAAA,CAAA,EAFJ,gBAEI;EACI,MAAA,CAAA,EAFX,YAEW;EACH,aAAA,CAAA,EAFD,aAEC;EAAiB,iBAAA,CAAA,EADd,iBACc;EAGvB,cAAA,CAAA,EAHM,iBAMlB;;AAHkD,cAAtC,cAAsC,EAAtB,MAAsB,CAAf,aAAe,EAAA,iBAAA,CAAA;AAAtB,cAKhB,UAAA,YAAsB,eALN,CAKsB,gBALtB,CAAA,CAAA;EAAM,CAAA,OAAA;EAKtB,SAAA,OAAW,EACJ,OADI;EAA2B,SAAA,YAAA,EAE1B,YAF0B;EAC/B,SAAA,SAAA,CAAA,EAEG,gBAFH;EACK,SAAA,MAAA,CAAA,EAEL,YAFK;EACF,SAAA,iBAAA,CAAA,EAEQ,iBAFR;EACH,SAAA,aAAA,CAAA,EAEO,aAFP;EACW,SAAA,eAAA,EAEH,uBAFG;EACJ,SAAA,cAAA,EAEA,iBAFA;EACC,WAAA,CAAA;IAAA,OAAA;IAAA,YAAA;IAAA,SAAA;IAAA,MAAA;IAAA,aAAA;IAAA,iBAAA;IAAA;EAAA,CAAA,EAgBvB,iBAhBuB;EACD,IAAA,MAAA,CAAA,CAAA,EA8CX,gBA9CW;EAQvB,KA0CG,mCAAA,GA1CH,EAAA,MAAA;EACA,KA6CG,sCAAA,GA7CH,EAAA,MAAA;EACA,IAAA,cAAA,CAAA,CAAA,EAgDoB,qBAhDpB,CAgD0C,sBAhD1C,CAAA;EACA,KAAA,CAAA,CAAA,EAmDO,OAnDP,CAAA,IAAA,CAAA;EACA,mBAAA,CAAA,CAAA,EAsD2B,OAtD3B,CAAA,OAAA,CAAA;EACA,iBAAA,CAAA,UA2D0B,SA3D1B,CAAA,CAAA,MAAA,EA2D6C,CA3D7C,EAAA,SAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EA2D2E,kBA3D3E;EACA,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAuEyC,OAvEzC,CAAA,MAAA,GAAA,SAAA,CAAA;EACC,iBAAA,CAAA,UAmGyB,SAnGzB,CAAA,CAAA,MAAA,EAoGO,CApGP,EAAA,SAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EAsGA,oBAtGA,CAsGqB,CAtGrB,EAsGwB,gBAtGxB,CAAA"}
1
+ {"version":3,"file":"generic-sql-adapter.d.ts","names":[],"sources":["../../../src/adapters/generic-sql/generic-sql-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;UAoCiB,gBAAA;oBACG;;EADH,eAAA,CAAA,EAGG,kBAFA;AAKpB;AACW,UADM,iBAAA,CACN;EACK,OAAA,EADL,OACK;EACF,YAAA,EADE,YACF;EACI,SAAA,CAAA,EADJ,gBACI;EACI,aAAA,CAAA,EADJ,aACI;EACH,iBAAA,CAAA,EADG,iBACH;EAAiB,cAAA,CAAA,EAAjB,iBAAiB;AAGpC;AAAoC,cAAvB,cAAuB,EAAP,MAAO,CAAA,aAAA,EAAe,iBAAf,CAAA;AAAe,cAKtC,UAAA,YAAsB,eALgB,CAKA,gBALA,CAAA,CAAA;EAAtB,CAAA,OAAA;EAAM,SAAA,OAAA,EAMf,OANe;EAKtB,SAAA,YAAW,EAEC,YAFD;EAA2B,SAAA,SAAA,CAAA,EAG5B,gBAH4B;EAC/B,SAAA,iBAAA,CAAA,EAGW,iBAHX;EACK,SAAA,aAAA,CAAA,EAGE,aAHF;EACF,SAAA,eAAA,EAGK,uBAHL;EACQ,SAAA,cAAA,EAGJ,iBAHI;EACJ,WAAA,CAAA;IAAA,OAAA;IAAA,YAAA;IAAA,SAAA;IAAA,aAAA;IAAA,iBAAA;IAAA;EAAA,CAAA,EAgBtB,iBAhBsB;EACC,IAAA,MAAA,CAAA,CAAA,EA6CZ,gBA7CY;EACD,KAgDpB,mCAAA,GAhDoB,EAAA,MAAA;EAQvB,KA4CG,sCAAA,GA5CH,EAAA,MAAA;EACA,IAAA,cAAA,CAAA,CAAA,EA+CoB,qBA/CpB,CA+C0C,sBA/C1C,CAAA;EACA,KAAA,CAAA,CAAA,EAkDO,OAlDP,CAAA,IAAA,CAAA;EACA,mBAAA,CAAA,CAAA,EAqD2B,OArD3B,CAAA,OAAA,CAAA;EACA,iBAAA,CAAA,UA0D0B,SA1D1B,CAAA,CAAA,MAAA,EA0D6C,CA1D7C,EAAA,SAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EA0D2E,kBA1D3E;EACA,gBAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAsEyC,OAtEzC,CAAA,MAAA,GAAA,SAAA,CAAA;EACC,iBAAA,CAAA,UAkGyB,SAlGzB,CAAA,CAAA,MAAA,EAmGO,CAnGP,EAAA,SAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EAqGA,oBArGA,CAqGqB,CArGrB,EAqGwB,gBArGxB,CAAA"}
@@ -1,16 +1,17 @@
1
- import { RequestContextStorage } from "../../packages/fragno/dist/api/request-context-storage.js";
2
- import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "../adapters.js";
3
- import { SqlDriverAdapter } from "../../sql-driver/sql-driver-adapter.js";
4
- import { sql } from "../../sql-driver/sql.js";
1
+ import { createNamingResolver } from "../../naming/sql-naming.js";
2
+ import { getOutboxConfigForAdapter } from "../../internal/outbox-state.js";
5
3
  import { sqliteStorageDefault, sqliteStoragePrisma } from "./sqlite-storage.js";
6
4
  import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
7
- import { createNamingResolver } from "../../naming/sql-naming.js";
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";
8
10
  import { createExecutor } from "./generic-sql-uow-executor.js";
9
- import { UnitOfWorkDecoder } from "./uow-decoder.js";
10
11
  import { createPreparedMigrations } from "./migration/prepared-migrations.js";
11
- import { createUOWCompilerFromOperationCompiler } from "../shared/uow-operation-compiler.js";
12
12
  import { GenericSQLUOWOperationCompiler } from "./query/generic-sql-uow-operation-compiler.js";
13
- 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";
14
15
 
15
16
  //#region src/adapters/generic-sql/generic-sql-adapter.ts
16
17
  const sqliteProfiles = {
@@ -21,7 +22,6 @@ var SqlAdapter = class {
21
22
  dialect;
22
23
  driverConfig;
23
24
  uowConfig;
24
- outbox;
25
25
  sqliteStorageMode;
26
26
  sqliteProfile;
27
27
  adapterMetadata;
@@ -29,11 +29,10 @@ var SqlAdapter = class {
29
29
  #schemaNamespaceMap = /* @__PURE__ */ new WeakMap();
30
30
  #contextStorage;
31
31
  #driver;
32
- constructor({ dialect, driverConfig, uowConfig, outbox, sqliteProfile, sqliteStorageMode, namingStrategy }) {
32
+ constructor({ dialect, driverConfig, uowConfig, sqliteProfile, sqliteStorageMode, namingStrategy }) {
33
33
  this.dialect = dialect;
34
34
  this.driverConfig = driverConfig;
35
35
  this.uowConfig = uowConfig;
36
- this.outbox = outbox;
37
36
  this.namingStrategy = namingStrategy ?? driverConfig.defaultNamingStrategy;
38
37
  const resolvedProfile = sqliteProfile ?? "default";
39
38
  if (sqliteStorageMode && sqliteProfile) throw new Error("sqliteStorageMode cannot be used together with sqliteProfile.");
@@ -101,7 +100,7 @@ var SqlAdapter = class {
101
100
  executor: createExecutor(this.#driver, this.driverConfig, {
102
101
  dialect: this.dialect,
103
102
  dryRun: false,
104
- outbox: this.outbox,
103
+ outbox: getOutboxConfigForAdapter(this),
105
104
  namingStrategy: this.namingStrategy
106
105
  }),
107
106
  decoder: new UnitOfWorkDecoder(this.driverConfig, this.sqliteStorageMode, resolver),
@@ -1 +1 @@
1
- {"version":3,"file":"generic-sql-adapter.js","names":["sqliteProfiles: Record<SQLiteProfile, SQLiteStorageMode>","#schemaNamespaceMap","#contextStorage","#driver","result: QueryResult<Record<string, unknown>>"],"sources":["../../../src/adapters/generic-sql/generic-sql-adapter.ts"],"sourcesContent":["import { RequestContextStorage } from \"@fragno-dev/core/internal/request-context-storage\";\nimport {\n fragnoDatabaseAdapterNameFakeSymbol,\n fragnoDatabaseAdapterVersionFakeSymbol,\n type DatabaseAdapter,\n type DatabaseContextStorage,\n type DatabaseAdapterMetadata,\n type SQLiteProfile,\n} from \"../adapters\";\nimport type { CompiledQuery, Dialect, QueryResult } from \"../../sql-driver/sql-driver\";\nimport { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport { sql } from \"../../sql-driver/sql\";\nimport type { AnyColumn, AnySchema } from \"../../schema/create\";\nimport type { SimpleQueryInterface } from \"../../query/simple-query-interface\";\nimport { createExecutor } from \"./generic-sql-uow-executor\";\nimport { UnitOfWorkDecoder } from \"./uow-decoder\";\nimport { createPreparedMigrations, type PreparedMigrations } from \"./migration/prepared-migrations\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { GenericSQLUOWOperationCompiler } from \"./query/generic-sql-uow-operation-compiler\";\nimport { createUOWCompilerFromOperationCompiler } from \"../shared/uow-operation-compiler\";\nimport {\n fromUnitOfWorkCompiler,\n type UnitOfWorkFactory,\n} from \"../shared/from-unit-of-work-compiler\";\nimport type { UOWInstrumentation } from \"../../query/unit-of-work/unit-of-work\";\nimport type { SQLiteStorageMode } from \"./sqlite-storage\";\nimport { sqliteStorageDefault, sqliteStoragePrisma } from \"./sqlite-storage\";\nimport type { OutboxConfig } from \"../../outbox/outbox\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport {\n createNamingResolver,\n type NamingResolver,\n type SqlNamingStrategy,\n} from \"../../naming/sql-naming\";\n\nexport interface UnitOfWorkConfig {\n onQuery?: (query: CompiledQuery) => void;\n dryRun?: boolean;\n instrumentation?: UOWInstrumentation;\n}\n\nexport interface SqlAdapterOptions {\n dialect: Dialect;\n driverConfig: DriverConfig;\n uowConfig?: UnitOfWorkConfig;\n outbox?: OutboxConfig;\n sqliteProfile?: SQLiteProfile;\n sqliteStorageMode?: SQLiteStorageMode;\n namingStrategy?: SqlNamingStrategy;\n}\n\nexport const sqliteProfiles: Record<SQLiteProfile, SQLiteStorageMode> = {\n default: sqliteStorageDefault,\n prisma: sqliteStoragePrisma,\n};\n\nexport class SqlAdapter implements DatabaseAdapter<UnitOfWorkConfig> {\n readonly dialect: Dialect;\n readonly driverConfig: DriverConfig;\n readonly uowConfig?: UnitOfWorkConfig;\n readonly outbox?: OutboxConfig;\n readonly sqliteStorageMode?: SQLiteStorageMode;\n readonly sqliteProfile?: SQLiteProfile;\n readonly adapterMetadata: DatabaseAdapterMetadata;\n readonly namingStrategy: SqlNamingStrategy;\n\n #schemaNamespaceMap = new WeakMap<AnySchema, string | null>();\n #contextStorage: RequestContextStorage<DatabaseContextStorage>;\n\n #driver: SqlDriverAdapter;\n\n constructor({\n dialect,\n driverConfig,\n uowConfig,\n outbox,\n sqliteProfile,\n sqliteStorageMode,\n namingStrategy,\n }: SqlAdapterOptions) {\n this.dialect = dialect;\n this.driverConfig = driverConfig;\n this.uowConfig = uowConfig;\n this.outbox = outbox;\n this.namingStrategy = namingStrategy ?? driverConfig.defaultNamingStrategy;\n const resolvedProfile = sqliteProfile ?? \"default\";\n\n if (sqliteStorageMode && sqliteProfile) {\n throw new Error(\"sqliteStorageMode cannot be used together with sqliteProfile.\");\n }\n\n this.sqliteStorageMode =\n driverConfig.databaseType === \"sqlite\"\n ? (sqliteStorageMode ?? sqliteProfiles[resolvedProfile])\n : undefined;\n this.sqliteProfile =\n driverConfig.databaseType === \"sqlite\" && !sqliteStorageMode ? resolvedProfile : undefined;\n\n this.adapterMetadata = {\n databaseType: driverConfig.databaseType,\n sqliteProfile: this.sqliteProfile,\n sqliteStorageMode: this.sqliteStorageMode,\n };\n\n this.#schemaNamespaceMap = new WeakMap<AnySchema, string | null>();\n this.#contextStorage = new RequestContextStorage();\n\n this.#driver = new SqlDriverAdapter(dialect);\n }\n\n get driver(): SqlDriverAdapter {\n return this.#driver;\n }\n\n get [fragnoDatabaseAdapterNameFakeSymbol](): string {\n return \"sql\";\n }\n\n get [fragnoDatabaseAdapterVersionFakeSymbol](): number {\n return 1;\n }\n\n get contextStorage(): RequestContextStorage<DatabaseContextStorage> {\n return this.#contextStorage;\n }\n\n close(): Promise<void> {\n return this.#driver.destroy();\n }\n\n async isConnectionHealthy(): Promise<boolean> {\n const result = await this.#driver.executeQuery(sql`SELECT 1 as healthy`.compile(this.dialect));\n const healthyValue = result.rows[0]?.[\"healthy\"];\n return healthyValue === 1 || healthyValue === 1n || healthyValue === \"1\";\n }\n\n prepareMigrations<T extends AnySchema>(schema: T, namespace: string | null): PreparedMigrations {\n const resolver = createNamingResolver(schema, namespace, this.namingStrategy);\n return createPreparedMigrations({\n schema,\n namespace: namespace ?? schema.name,\n database: this.driverConfig.databaseType,\n driverConfig: this.driverConfig,\n sqliteStorageMode: this.sqliteStorageMode,\n resolver,\n driver: this.#driver,\n });\n }\n\n async getSchemaVersion(namespace: string): Promise<string | undefined> {\n const key = `${namespace}.schema_version`;\n const query = sql`SELECT value FROM fragno_db_settings WHERE key = ${key};`.compile(\n this.dialect,\n );\n\n let result: QueryResult<Record<string, unknown>>;\n try {\n result = await this.#driver.executeQuery(query);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"fragno_db_settings\")) {\n return undefined;\n }\n throw error;\n }\n\n const value = result.rows[0][\"value\"];\n\n if (!value) {\n return undefined;\n }\n\n if (typeof value !== \"string\") {\n throw new Error(`Schema version for namespace ${namespace} is not a string`);\n }\n\n return value;\n }\n\n createQueryEngine<T extends AnySchema>(\n schema: T,\n namespace: string | null,\n ): SimpleQueryInterface<T, UnitOfWorkConfig> {\n this.#schemaNamespaceMap.set(schema, namespace);\n const resolver = createNamingResolver(schema, namespace, this.namingStrategy);\n\n const operationCompiler = new GenericSQLUOWOperationCompiler(\n this.driverConfig,\n this.sqliteStorageMode,\n (schemaForResolver, namespaceForResolver): NamingResolver =>\n createNamingResolver(schemaForResolver, namespaceForResolver, this.namingStrategy),\n );\n\n const factory: UnitOfWorkFactory = {\n compiler: createUOWCompilerFromOperationCompiler(operationCompiler),\n executor: createExecutor(this.#driver, this.driverConfig, {\n dialect: this.dialect,\n dryRun: false,\n outbox: this.outbox,\n namingStrategy: this.namingStrategy,\n }),\n decoder: new UnitOfWorkDecoder(this.driverConfig, this.sqliteStorageMode, resolver),\n uowConfig: this.uowConfig,\n schemaNamespaceMap: this.#schemaNamespaceMap,\n };\n\n const queryEngine = fromUnitOfWorkCompiler(schema, factory) as SimpleQueryInterface<\n T,\n UnitOfWorkConfig\n >;\n\n const serializer = createSQLSerializer(this.driverConfig, this.sqliteStorageMode);\n const timestampColumn = { type: \"timestamp\" } as AnyColumn;\n\n return {\n ...queryEngine,\n now: async () => {\n const result = await this.#driver.executeQuery(\n sql`SELECT CURRENT_TIMESTAMP as now`.compile(this.dialect),\n );\n const rawValue = result.rows[0]?.[\"now\"];\n if (rawValue === undefined || rawValue === null) {\n throw new Error(\"Failed to fetch database time\");\n }\n return serializer.deserialize(rawValue, timestampColumn) as Date;\n },\n };\n }\n}\n\nexport type { SQLiteStorageMode } from \"./sqlite-storage\";\nexport { sqliteStorageDefault, sqliteStoragePrisma } from \"./sqlite-storage\";\nexport type { OutboxConfig } from \"../../outbox/outbox\";\n"],"mappings":"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"}
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,11 +1,11 @@
1
- import { sql } from "../../sql-driver/sql.js";
2
- import { ResultInterpreter } from "./result-interpreter.js";
3
1
  import { createId } from "../../id.js";
4
- import { createColdKysely } from "./migration/cold-kysely.js";
2
+ import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
3
+ import { sql } from "../../sql-driver/sql.js";
5
4
  import { SETTINGS_NAMESPACE, internalSchema } from "../../fragments/internal-fragment.schema.js";
6
5
  import { encodeVersionstamp, parseOutboxVersionValue, versionstampToHex } from "../../outbox/outbox.js";
7
6
  import { buildOutboxPlan, finalizeOutboxPayload } from "../../outbox/outbox-builder.js";
8
- import { createSQLSerializer } from "../../query/serialize/create-sql-serializer.js";
7
+ import { createColdKysely } from "./migration/cold-kysely.js";
8
+ import { ResultInterpreter } from "./result-interpreter.js";
9
9
  import superjson from "superjson";
10
10
 
11
11
  //#region src/adapters/generic-sql/generic-sql-uow-executor.ts
@@ -28,8 +28,14 @@ async function executeMutation(adapter, driverConfig, mutationBatch, options) {
28
28
  const createdInternalIds = [];
29
29
  const resultInterpreter = new ResultInterpreter(driverConfig);
30
30
  const outboxEnabled = options.outbox?.enabled ?? false;
31
+ const shouldInclude = options.outbox?.shouldInclude;
31
32
  const namingStrategy = options.namingStrategy ?? driverConfig.defaultNamingStrategy;
32
- const outboxOperations = outboxEnabled ? mutationBatch.flatMap((mutation) => mutation.operation ? [mutation.operation] : []) : [];
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
+ }) : [];
33
39
  const outboxPlan = outboxOperations.length > 0 ? buildOutboxPlan(outboxOperations) : null;
34
40
  const shouldWriteOutbox = outboxEnabled && outboxPlan !== null && outboxPlan.drafts.length > 0;
35
41
  try {
@@ -58,6 +64,11 @@ async function executeMutation(adapter, driverConfig, mutationBatch, options) {
58
64
  const payload = finalizeOutboxPayload(outboxPlan, outboxVersion);
59
65
  const payloadSerialized = superjson.serialize(payload);
60
66
  const versionstamp = versionstampToHex(encodeVersionstamp(outboxVersion, 0));
67
+ await insertOutboxMutationRows(tx, driverConfig, {
68
+ entryVersionstamp: versionstamp,
69
+ uowId,
70
+ mutations: payload.mutations
71
+ });
61
72
  await insertOutboxRow(tx, driverConfig, {
62
73
  id: createId(),
63
74
  versionstamp,
@@ -177,7 +188,7 @@ async function insertOutboxRow(tx, driverConfig, options) {
177
188
  };
178
189
  const serializedValues = {};
179
190
  for (const [key, value] of Object.entries(values)) {
180
- const col = outboxTable.columns[key];
191
+ const col = outboxTable.getColumnByName(key);
181
192
  if (!col) {
182
193
  serializedValues[key] = value;
183
194
  continue;
@@ -187,6 +198,35 @@ async function insertOutboxRow(tx, driverConfig, options) {
187
198
  const query = createColdKysely(driverConfig.databaseType).insertInto("fragno_db_outbox").values(serializedValues).compile();
188
199
  await tx.executeQuery(query);
189
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
+ }
190
230
 
191
231
  //#endregion
192
232
  export { createExecutor };
@@ -1 +1 @@
1
- {"version":3,"file":"generic-sql-uow-executor.js","names":["retrievalResults: unknown[]","createdInternalIds: (bigint | null)[]","outboxVersion: bigint | null","refMap: OutboxRefMap","serializedValues: Record<string, unknown>"],"sources":["../../../src/adapters/generic-sql/generic-sql-uow-executor.ts"],"sourcesContent":["import type {\n CompiledMutation,\n MutationResult,\n UOWExecutor,\n} from \"../../query/unit-of-work/unit-of-work\";\nimport type { CompiledQuery, Dialect } from \"../../sql-driver/sql-driver\";\nimport type { SqlDriverAdapter } from \"../../sql-driver/sql-driver-adapter\";\nimport type { DriverConfig } from \"./driver-config\";\nimport { ResultInterpreter } from \"./result-interpreter\";\nimport { sql } from \"../../sql-driver/sql\";\nimport { createId } from \"../../id\";\nimport superjson from \"superjson\";\nimport { createColdKysely } from \"./migration/cold-kysely\";\nimport { SETTINGS_NAMESPACE, internalSchema } from \"../../fragments/internal-fragment.schema\";\nimport {\n type OutboxConfig,\n type OutboxRefLookup,\n type OutboxRefMap,\n encodeVersionstamp,\n parseOutboxVersionValue,\n versionstampToHex,\n} from \"../../outbox/outbox\";\nimport { buildOutboxPlan, finalizeOutboxPayload } from \"../../outbox/outbox-builder\";\nimport { createSQLSerializer } from \"../../query/serialize/create-sql-serializer\";\nimport { type SqlNamingStrategy } from \"../../naming/sql-naming\";\n\nexport interface ExecutorOptions {\n dryRun?: boolean;\n dialect: Dialect;\n outbox?: OutboxConfig;\n namingStrategy?: SqlNamingStrategy;\n}\n\nexport async function executeRetrieval(\n adapter: SqlDriverAdapter,\n retrievalBatch: CompiledQuery[],\n): Promise<unknown[]> {\n if (retrievalBatch.length === 0) {\n return [];\n }\n\n const retrievalResults: unknown[] = [];\n\n await adapter.transaction(async (tx) => {\n for (const compiledQuery of retrievalBatch) {\n const result = await tx.executeQuery(compiledQuery);\n retrievalResults.push(result.rows);\n }\n });\n\n return retrievalResults;\n}\n\nexport async function executeMutation(\n adapter: SqlDriverAdapter,\n driverConfig: DriverConfig,\n mutationBatch: CompiledMutation<CompiledQuery>[],\n options: ExecutorOptions,\n): Promise<MutationResult> {\n if (mutationBatch.length === 0) {\n return { success: true, createdInternalIds: [] };\n }\n\n const createdInternalIds: (bigint | null)[] = [];\n const resultInterpreter = new ResultInterpreter(driverConfig);\n const outboxEnabled = options.outbox?.enabled ?? false;\n const namingStrategy = options.namingStrategy ?? driverConfig.defaultNamingStrategy;\n\n const outboxOperations = outboxEnabled\n ? mutationBatch.flatMap((mutation) => (mutation.operation ? [mutation.operation] : []))\n : [];\n\n const outboxPlan = outboxOperations.length > 0 ? buildOutboxPlan(outboxOperations) : null;\n const shouldWriteOutbox = outboxEnabled && outboxPlan !== null && outboxPlan.drafts.length > 0;\n\n try {\n await adapter.transaction(async (tx) => {\n let outboxVersion: bigint | null = null;\n\n if (shouldWriteOutbox) {\n outboxVersion = await reserveOutboxVersion(tx, driverConfig, options.dialect);\n }\n\n for (const compiledMutation of mutationBatch) {\n const result = await tx.executeQuery(compiledMutation.query);\n\n // Extract internal ID for INSERT operations\n if (compiledMutation.op === \"create\") {\n // Only try to extract internal ID if driver supports RETURNING\n // If not supported, push null (expected case - system falls back to subqueries)\n if (driverConfig.supportsReturning && driverConfig.internalIdColumn) {\n const internalId = resultInterpreter.getCreatedInternalId(result);\n createdInternalIds.push(internalId);\n } else {\n // Driver doesn't support RETURNING - this is expected, push null\n createdInternalIds.push(null);\n }\n } else if (\n (compiledMutation.op === \"update\" || compiledMutation.op === \"delete\") &&\n compiledMutation.expectedAffectedRows !== null\n ) {\n // Check affected rows for updates/deletes\n const affectedRows = resultInterpreter.getAffectedRows(result);\n\n if (affectedRows !== compiledMutation.expectedAffectedRows) {\n // Version conflict detected - the UPDATE/DELETE didn't affect the expected number of rows\n // This means either the row doesn't exist or the version has changed\n throw new Error(\n `Version conflict: expected ${compiledMutation.expectedAffectedRows} rows affected, but got ${affectedRows}`,\n );\n }\n }\n // \"check\" operations are handled below via expectedReturnedRows\n\n if (compiledMutation.expectedReturnedRows !== null) {\n // For SELECT queries (check operations), verify row count\n const returnedRowCount = resultInterpreter.getReturnedRowCount(result);\n\n if (returnedRowCount !== BigInt(compiledMutation.expectedReturnedRows)) {\n // Version conflict detected - the SELECT didn't return the expected number of rows\n // This means either the row doesn't exist or the version has changed\n throw new Error(\n `Version conflict: expected ${compiledMutation.expectedReturnedRows} rows returned, but got ${returnedRowCount}`,\n );\n }\n }\n }\n\n if (shouldWriteOutbox && outboxPlan && outboxVersion !== null) {\n const uowId = mutationBatch[0]?.uowId;\n if (!uowId) {\n throw new Error(\"Outbox mutation batch is missing uowId.\");\n }\n\n const refMap = await resolveOutboxRefMap(\n tx,\n driverConfig,\n outboxPlan.lookups,\n namingStrategy,\n );\n const payload = finalizeOutboxPayload(outboxPlan, outboxVersion);\n const payloadSerialized = superjson.serialize(payload);\n const versionstamp = versionstampToHex(encodeVersionstamp(outboxVersion, 0));\n\n await insertOutboxRow(tx, driverConfig, {\n id: createId(),\n versionstamp,\n uowId,\n payload: payloadSerialized,\n refMap,\n });\n }\n });\n\n return { success: true, createdInternalIds };\n } catch (error) {\n // Transaction failed - could be version conflict or other constraint violation\n // Return success=false to indicate the UOW should be retried\n if (error instanceof Error && error.message.includes(\"Version conflict\")) {\n return { success: false };\n }\n\n const errorCode =\n typeof error === \"object\" && error !== null && \"code\" in error\n ? (error as { code?: unknown }).code\n : undefined;\n\n if (errorCode === \"40001\" || errorCode === \"40P01\") {\n return { success: false };\n }\n\n // Other database errors should be thrown\n throw error;\n }\n}\n\nexport function createExecutor(\n adapter: SqlDriverAdapter,\n driverConfig: DriverConfig,\n options: ExecutorOptions,\n): UOWExecutor<CompiledQuery, unknown> {\n const dryRun = options.dryRun ?? false;\n\n return {\n async executeRetrievalPhase(retrievalBatch: CompiledQuery[]) {\n // In dryRun mode, skip execution and return empty results\n if (dryRun) {\n return retrievalBatch.map(() => []);\n }\n\n return executeRetrieval(adapter, retrievalBatch);\n },\n async executeMutationPhase(mutationBatch: CompiledMutation<CompiledQuery>[]) {\n // In dryRun mode, skip execution and return success with mock internal IDs\n if (dryRun) {\n return {\n success: true,\n createdInternalIds: mutationBatch.map(() => null),\n };\n }\n\n return executeMutation(adapter, driverConfig, mutationBatch, options);\n },\n };\n}\n\nasync function reserveOutboxVersion(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n dialect: Dialect,\n): Promise<bigint> {\n const key = `${SETTINGS_NAMESPACE}.outbox_version`;\n const id = createId();\n\n switch (driverConfig.outboxVersionstampStrategy) {\n case \"insert-on-conflict-returning\": {\n const query =\n driverConfig.databaseType === \"postgresql\"\n ? sql`\n insert into fragno_db_settings (id, key, value)\n values (${id}, ${key}, '0')\n on conflict (key) do update\n set value = (fragno_db_settings.value::bigint + 1)::text\n returning value;\n `\n : sql`\n insert into fragno_db_settings (id, key, value)\n values (${id}, ${key}, '0')\n on conflict (key) do update\n set value = cast(fragno_db_settings.value as integer) + 1\n returning value;\n `;\n\n const result = await tx.executeQuery(query.compile(dialect));\n const value = result.rows[0]?.[\"value\"];\n return parseOutboxVersionValue(value);\n }\n case \"update-returning\": {\n const query =\n driverConfig.databaseType === \"postgresql\"\n ? sql`\n update fragno_db_settings\n set value = (fragno_db_settings.value::bigint + 1)::text\n where key = ${key}\n returning value;\n `\n : sql`\n update fragno_db_settings\n set value = cast(fragno_db_settings.value as integer) + 1\n where key = ${key}\n returning value;\n `;\n\n const result = await tx.executeQuery(query.compile(dialect));\n const value = result.rows[0]?.[\"value\"];\n if (value === undefined) {\n throw new Error(\"Outbox version row was not found for update-returning strategy.\");\n }\n return parseOutboxVersionValue(value);\n }\n case \"insert-on-duplicate-last-insert-id\": {\n const insertQuery = sql`\n insert into fragno_db_settings (id, key, value)\n values (${id}, ${key}, LAST_INSERT_ID(0))\n on duplicate key update value = LAST_INSERT_ID(cast(value as unsigned) + 1);\n `;\n\n await tx.executeQuery(insertQuery.compile(dialect));\n\n const selectQuery = sql`select LAST_INSERT_ID() as value;`;\n const result = await tx.executeQuery(selectQuery.compile(dialect));\n const value = result.rows[0]?.[\"value\"];\n return parseOutboxVersionValue(value);\n }\n }\n}\n\nasync function resolveOutboxRefMap(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n lookups: OutboxRefLookup[],\n namingStrategy: SqlNamingStrategy,\n): Promise<OutboxRefMap | undefined> {\n if (lookups.length === 0) {\n return undefined;\n }\n\n const refMap: OutboxRefMap = {};\n const db = createColdKysely(driverConfig.databaseType);\n\n for (const lookup of lookups) {\n const namespace = lookup.namespace ?? null;\n const logicalTable = lookup.table.name;\n const schemaName =\n namingStrategy.namespaceScope === \"schema\" && namespace && namespace.length > 0\n ? namingStrategy.namespaceToSchema(namespace)\n : null;\n const scopedDb = schemaName ? db.withSchema(schemaName) : db;\n const tableName = namingStrategy.tableName(logicalTable, namespace);\n const internalColumn = namingStrategy.columnName(\n lookup.table.getInternalIdColumn().name,\n logicalTable,\n );\n const externalColumn = namingStrategy.columnName(lookup.table.getIdColumn().name, logicalTable);\n\n const query = scopedDb\n .selectFrom(tableName)\n .select(externalColumn)\n .where(internalColumn, \"=\", lookup.internalId)\n .compile();\n\n const result = await tx.executeQuery(query);\n const row = result.rows[0] as Record<string, unknown> | undefined;\n const externalId = row?.[externalColumn];\n\n if (typeof externalId !== \"string\") {\n throw new Error(\n `Failed to resolve outbox reference for ${tableName}.${internalColumn}=${String(lookup.internalId)}`,\n );\n }\n\n refMap[lookup.key] = externalId;\n }\n\n return Object.keys(refMap).length > 0 ? refMap : undefined;\n}\n\nasync function insertOutboxRow(\n tx: SqlDriverAdapter,\n driverConfig: DriverConfig,\n options: {\n id: string;\n versionstamp: string;\n uowId: string;\n payload: { json: unknown; meta?: Record<string, unknown> };\n refMap?: OutboxRefMap;\n },\n): Promise<void> {\n const { id, versionstamp, uowId, payload, refMap } = options;\n const refMapValue = refMap ?? null;\n const serializer = createSQLSerializer(driverConfig);\n const outboxTable = internalSchema.tables.fragno_db_outbox;\n const values = { id, versionstamp, uowId, payload, refMap: refMapValue };\n const serializedValues: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(values)) {\n const col = outboxTable.columns[key];\n if (!col) {\n serializedValues[key] = value;\n continue;\n }\n serializedValues[col.name] = serializer.serialize(value, col);\n }\n const db = createColdKysely(driverConfig.databaseType);\n\n const query = db.insertInto(\"fragno_db_outbox\").values(serializedValues).compile();\n\n await tx.executeQuery(query);\n}\n"],"mappings":"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"}
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":";;;;;;;;;;;AAkCA,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,eACA,SACyB;AACzB,KAAI,cAAc,WAAW,EAC3B,QAAO;EAAE,SAAS;EAAM,oBAAoB,EAAE;EAAE;CAGlD,MAAMC,qBAAwC,EAAE;CAChD,MAAM,oBAAoB,IAAI,kBAAkB,aAAa;CAC7D,MAAM,gBAAgB,QAAQ,QAAQ,WAAW;CACjD,MAAM,gBAAgB,QAAQ,QAAQ;CACtC,MAAM,iBAAiB,QAAQ,kBAAkB,aAAa;CAE9D,MAAM,mBAAmB,gBACrB,cAAc,SAAS,aAAa;EAClC,MAAM,YAAY,SAAS;AAC3B,MAAI,CAAC,UACH,QAAO,EAAE;AAEX,MAAI,iBAAiB,CAAC,cAAc,UAAU,CAC5C,QAAO,EAAE;AAEX,SAAO,CAAC,UAAU;GAClB,GACF,EAAE;CAEN,MAAM,aAAa,iBAAiB,SAAS,IAAI,gBAAgB,iBAAiB,GAAG;CACrF,MAAM,oBAAoB,iBAAiB,eAAe,QAAQ,WAAW,OAAO,SAAS;AAE7F,KAAI;AACF,QAAM,QAAQ,YAAY,OAAO,OAAO;GACtC,IAAIC,gBAA+B;AAEnC,OAAI,kBACF,iBAAgB,MAAM,qBAAqB,IAAI,cAAc,QAAQ,QAAQ;AAG/E,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;;;AAKP,OAAI,qBAAqB,cAAc,kBAAkB,MAAM;IAC7D,MAAM,QAAQ,cAAc,IAAI;AAChC,QAAI,CAAC,MACH,OAAM,IAAI,MAAM,0CAA0C;IAG5D,MAAM,SAAS,MAAM,oBACnB,IACA,cACA,WAAW,SACX,eACD;IACD,MAAM,UAAU,sBAAsB,YAAY,cAAc;IAChE,MAAM,oBAAoB,UAAU,UAAU,QAAQ;IACtD,MAAM,eAAe,kBAAkB,mBAAmB,eAAe,EAAE,CAAC;AAE5E,UAAM,yBAAyB,IAAI,cAAc;KAC/C,mBAAmB;KACnB;KACA,WAAW,QAAQ;KACpB,CAAC;AACF,UAAM,gBAAgB,IAAI,cAAc;KACtC,IAAI,UAAU;KACd;KACA;KACA,SAAS;KACT;KACD,CAAC;;IAEJ;AAEF,SAAO;GAAE,SAAS;GAAM;GAAoB;UACrC,OAAO;AAGd,MAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,mBAAmB,CACtE,QAAO,EAAE,SAAS,OAAO;EAG3B,MAAM,YACJ,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,QACpD,MAA6B,OAC9B;AAEN,MAAI,cAAc,WAAW,cAAc,QACzC,QAAO,EAAE,SAAS,OAAO;AAI3B,QAAM;;;AAIV,SAAgB,eACd,SACA,cACA,SACqC;CACrC,MAAM,SAAS,QAAQ,UAAU;AAEjC,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,eAAe,QAAQ;;EAExE;;AAGH,eAAe,qBACb,IACA,cACA,SACiB;CACjB,MAAM,MAAM,GAAG,mBAAmB;CAClC,MAAM,KAAK,UAAU;AAErB,SAAQ,aAAa,4BAArB;EACE,KAAK,gCAAgC;GACnC,MAAM,QACJ,aAAa,iBAAiB,eAC1B,GAAG;;wBAES,GAAG,IAAI,IAAI;;;;gBAKvB,GAAG;;wBAES,GAAG,IAAI,IAAI;;;;;GAO7B,MAAM,SADS,MAAM,GAAG,aAAa,MAAM,QAAQ,QAAQ,CAAC,EACvC,KAAK,KAAK;AAC/B,UAAO,wBAAwB,MAAM;;EAEvC,KAAK,oBAAoB;GACvB,MAAM,QACJ,aAAa,iBAAiB,eAC1B,GAAG;;;4BAGa,IAAI;;gBAGpB,GAAG;;;4BAGa,IAAI;;;GAK1B,MAAM,SADS,MAAM,GAAG,aAAa,MAAM,QAAQ,QAAQ,CAAC,EACvC,KAAK,KAAK;AAC/B,OAAI,UAAU,OACZ,OAAM,IAAI,MAAM,kEAAkE;AAEpF,UAAO,wBAAwB,MAAM;;EAEvC,KAAK,sCAAsC;GACzC,MAAM,cAAc,GAAG;;kBAEX,GAAG,IAAI,IAAI;;;AAIvB,SAAM,GAAG,aAAa,YAAY,QAAQ,QAAQ,CAAC;GAEnD,MAAM,cAAc,GAAG;GAEvB,MAAM,SADS,MAAM,GAAG,aAAa,YAAY,QAAQ,QAAQ,CAAC,EAC7C,KAAK,KAAK;AAC/B,UAAO,wBAAwB,MAAM;;;;AAK3C,eAAe,oBACb,IACA,cACA,SACA,gBACmC;AACnC,KAAI,QAAQ,WAAW,EACrB;CAGF,MAAMC,SAAuB,EAAE;CAC/B,MAAM,KAAK,iBAAiB,aAAa,aAAa;AAEtD,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,YAAY,OAAO,aAAa;EACtC,MAAM,eAAe,OAAO,MAAM;EAClC,MAAM,aACJ,eAAe,mBAAmB,YAAY,aAAa,UAAU,SAAS,IAC1E,eAAe,kBAAkB,UAAU,GAC3C;EACN,MAAM,WAAW,aAAa,GAAG,WAAW,WAAW,GAAG;EAC1D,MAAM,YAAY,eAAe,UAAU,cAAc,UAAU;EACnE,MAAM,iBAAiB,eAAe,WACpC,OAAO,MAAM,qBAAqB,CAAC,MACnC,aACD;EACD,MAAM,iBAAiB,eAAe,WAAW,OAAO,MAAM,aAAa,CAAC,MAAM,aAAa;EAE/F,MAAM,QAAQ,SACX,WAAW,UAAU,CACrB,OAAO,eAAe,CACtB,MAAM,gBAAgB,KAAK,OAAO,WAAW,CAC7C,SAAS;EAIZ,MAAM,cAFS,MAAM,GAAG,aAAa,MAAM,EACxB,KAAK,KACC;AAEzB,MAAI,OAAO,eAAe,SACxB,OAAM,IAAI,MACR,0CAA0C,UAAU,GAAG,eAAe,GAAG,OAAO,OAAO,WAAW,GACnG;AAGH,SAAO,OAAO,OAAO;;AAGvB,QAAO,OAAO,KAAK,OAAO,CAAC,SAAS,IAAI,SAAS;;AAGnD,eAAe,gBACb,IACA,cACA,SAOe;CACf,MAAM,EAAE,IAAI,cAAc,OAAO,SAAS,WAAW;CACrD,MAAM,cAAc,UAAU;CAC9B,MAAM,aAAa,oBAAoB,aAAa;CACpD,MAAM,cAAc,eAAe,OAAO;CAC1C,MAAM,SAAS;EAAE;EAAI;EAAc;EAAO;EAAS,QAAQ;EAAa;CACxE,MAAMC,mBAA4C,EAAE;AACpD,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,EAAE;EACjD,MAAM,MAAM,YAAY,gBAAgB,IAAI;AAC5C,MAAI,CAAC,KAAK;AACR,oBAAiB,OAAO;AACxB;;AAEF,mBAAiB,IAAI,QAAQ,WAAW,UAAU,OAAO,IAAI;;CAI/D,MAAM,QAFK,iBAAiB,aAAa,aAAa,CAErC,WAAW,mBAAmB,CAAC,OAAO,iBAAiB,CAAC,SAAS;AAElF,OAAM,GAAG,aAAa,MAAM;;AAG9B,eAAe,yBACb,IACA,cACA,SAWe;AACf,KAAI,QAAQ,UAAU,WAAW,EAC/B;CAGF,MAAM,aAAa,oBAAoB,aAAa;CACpD,MAAM,iBAAiB,eAAe,OAAO;CAC7C,MAAM,KAAK,iBAAiB,aAAa,aAAa;AAEtD,MAAK,MAAM,YAAY,QAAQ,WAAW;EACxC,MAAM,SAAS;GACb,IAAI,UAAU;GACd,mBAAmB,QAAQ;GAC3B,sBAAsB,SAAS;GAC/B,OAAO,QAAQ;GACf,QAAQ,SAAS;GACjB,OAAO,SAAS;GAChB,YAAY,SAAS;GACrB,IAAI,SAAS;GACd;EACD,MAAMA,mBAA4C,EAAE;AAEpD,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,EAAE;GACjD,MAAM,MAAM,eAAe,gBAAgB,IAAI;AAC/C,OAAI,CAAC,KAAK;AACR,qBAAiB,OAAO;AACxB;;AAEF,oBAAiB,IAAI,QAAQ,WAAW,UAAU,OAAO,IAAI;;EAG/D,MAAM,QAAQ,GAAG,WAAW,6BAA6B,CAAC,OAAO,iBAAiB,CAAC,SAAS;AAC5F,QAAM,GAAG,aAAa,MAAM"}
@@ -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
@@ -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 { NamingResolver } from \"../../../../naming/sql-naming\";\nimport { SQLGenerator } from \"../sql-generator\";\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n} as const;\n\n/**\n * MySQL-specific SQL generator.\n * Uses modifyColumn for updates and wraps migrations with FK checks disabled.\n */\nexport class MySQLSQLGenerator extends SQLGenerator {\n /**\n * MySQL preprocessing: wrap operations with SET FOREIGN_KEY_CHECKS = 0/1.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n if (operations.length === 0) {\n return operations;\n }\n\n return [\n { type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 0\" },\n ...operations,\n { type: \"custom\", sql: \"SET FOREIGN_KEY_CHECKS = 1\" },\n ];\n }\n\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder.autoIncrement();\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n // MySQL doesn't support default values for TEXT columns\n if (column.type === \"string\") {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * MySQL update-column uses modifyColumn which requires the full column definition.\n */\n protected override compileUpdateColumn(\n tableName: string,\n logicalTableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n\n if (!isUpdated(operation)) {\n return [];\n }\n\n // MySQL: Use modifyColumn which requires the full column definition\n return this.getSchemaBuilder(resolver)\n .alterTable(tableName)\n .modifyColumn(\n this.getColumnName(operation.name, logicalTableName, resolver),\n sql.raw(this.getDBType(col)),\n (b) => this.buildColumn(col, b),\n )\n .compile();\n }\n\n /**\n * MySQL doesn't support IF EXISTS for dropping constraints.\n */\n protected override compileDropForeignKey(\n operation: Extract<MigrationOperation, { type: \"drop-foreign-key\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery {\n const { table, name, referencedTable } = operation;\n return this.getSchemaBuilder(resolver)\n .alterTable(this.getTableName(table, resolver))\n .dropConstraint(this.getForeignKeyName(name, table, referencedTable, resolver))\n .compile();\n }\n\n /**\n * MySQL: add a named primary key constraint for the internal ID column to align naming.\n */\n protected override compileCreateTable(\n operation: Extract<MigrationOperation, { type: \"create-table\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery {\n const compiled = super.compileCreateTable(operation, resolver);\n const tableName = this.getTableName(operation.name, resolver);\n const internalIdColumn = operation.columns.find((col) => col.role === \"internal-id\");\n\n if (!internalIdColumn) {\n return compiled;\n }\n\n const pkColumn = this.getColumnName(internalIdColumn.name, operation.name, resolver);\n const pkName = `${tableName}__${pkColumn.replace(/^_+/, \"\")}`;\n const escapedPkColumn = pkColumn.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const columnRegex = new RegExp(\"`\" + escapedPkColumn + \"`([^,]*?)\\\\bprimary key\\\\b\", \"i\");\n\n let sqlText = compiled.sql.replace(columnRegex, \"`\" + pkColumn + \"`$1\");\n sqlText = sqlText.replace(\n /\\)\\s*$/,\n \", constraint `\" + pkName + \"` primary key (`\" + pkColumn + \"`))\",\n );\n\n return {\n ...compiled,\n sql: sqlText,\n };\n }\n}\n"],"mappings":";;;;;AAUA,MAAM,SAAS,EACb,gBACE,mHACH;;;;;AAMD,IAAa,oBAAb,cAAuC,aAAa;;;;CAIlD,AAAS,WAAW,YAAwD;AAC1E,MAAI,WAAW,WAAW,EACxB,QAAO;AAGT,SAAO;GACL;IAAE,MAAM;IAAU,KAAK;IAA8B;GACrD,GAAG;GACH;IAAE,MAAM;IAAU,KAAK;IAA8B;GACtD;;CAGH,AAAS,mBAAmB,SAA2D;AACrF,SAAO,QAAQ,eAAe;;CAGhC,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAIF,MAAI,OAAO,SAAS,SAClB;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,oBACjB,WACA,kBACA,WACA,UACiC;EACjC,MAAM,MAAM,UAAU;AAEtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAGxC,MAAI,CAAC,UAAU,UAAU,CACvB,QAAO,EAAE;AAIX,SAAO,KAAK,iBAAiB,SAAS,CACnC,WAAW,UAAU,CACrB,aACC,KAAK,cAAc,UAAU,MAAM,kBAAkB,SAAS,EAC9D,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,GAC3B,MAAM,KAAK,YAAY,KAAK,EAAE,CAChC,CACA,SAAS;;;;;CAMd,AAAmB,sBACjB,WACA,UACe;EACf,MAAM,EAAE,OAAO,MAAM,oBAAoB;AACzC,SAAO,KAAK,iBAAiB,SAAS,CACnC,WAAW,KAAK,aAAa,OAAO,SAAS,CAAC,CAC9C,eAAe,KAAK,kBAAkB,MAAM,OAAO,iBAAiB,SAAS,CAAC,CAC9E,SAAS;;;;;CAMd,AAAmB,mBACjB,WACA,UACe;EACf,MAAM,WAAW,MAAM,mBAAmB,WAAW,SAAS;EAC9D,MAAM,YAAY,KAAK,aAAa,UAAU,MAAM,SAAS;EAC7D,MAAM,mBAAmB,UAAU,QAAQ,MAAM,QAAQ,IAAI,SAAS,cAAc;AAEpF,MAAI,CAAC,iBACH,QAAO;EAGT,MAAM,WAAW,KAAK,cAAc,iBAAiB,MAAM,UAAU,MAAM,SAAS;EACpF,MAAM,SAAS,GAAG,UAAU,IAAI,SAAS,QAAQ,OAAO,GAAG;EAC3D,MAAM,kBAAkB,SAAS,QAAQ,uBAAuB,OAAO;EACvE,MAAM,cAAc,IAAI,OAAO,MAAM,kBAAkB,8BAA8B,IAAI;EAEzF,IAAI,UAAU,SAAS,IAAI,QAAQ,aAAa,MAAM,WAAW,MAAM;AACvE,YAAU,QAAQ,QAChB,UACA,mBAAmB,SAAS,qBAAqB,WAAW,MAC7D;AAED,SAAO;GACL,GAAG;GACH,KAAK;GACN"}
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
@@ -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\";\nimport type { NamingResolver } from \"../../../../naming/sql-naming\";\n\nconst errors = {\n IdColumnUpdate:\n \"ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.\",\n} as const;\n\n/**\n * PostgreSQL-specific SQL generator.\n * Uses USING clauses for type conversion and SERIAL for auto-increment.\n */\nexport class PostgresSQLGenerator extends SQLGenerator {\n /**\n * PostgreSQL doesn't need preprocessing - it handles FKs normally.\n */\n override preprocess(operations: MigrationOperation[]): MigrationOperation[] {\n return operations;\n }\n\n /**\n * PostgreSQL uses SERIAL/BIGSERIAL types for auto-increment,\n * which is already handled in PostgreSQLTypeMapper. No builder modification needed.\n */\n override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {\n return builder;\n }\n\n override getDefaultValue(column: ColumnInfo): RawBuilder<unknown> | undefined {\n const value = column.default;\n if (!value) {\n return undefined;\n }\n\n if (\"value\" in value && value.value !== undefined) {\n return sql.lit(value.value);\n }\n\n if (\"dbSpecial\" in value && value.dbSpecial === \"now\") {\n return sql`CURRENT_TIMESTAMP`;\n }\n\n // Runtime defaults are handled in application code, not SQL\n if (\"runtime\" in value) {\n return undefined;\n }\n\n return undefined;\n }\n\n /**\n * PostgreSQL update-column uses USING clause for type conversion.\n */\n protected override compileUpdateColumn(\n tableName: string,\n logicalTableName: string,\n operation: Extract<ColumnOperation, { type: \"update-column\" }>,\n resolver?: NamingResolver,\n ): CompiledQuery | CompiledQuery[] {\n const col = operation.value;\n\n if (col.role === \"external-id\" || col.role === \"internal-id\") {\n throw new Error(errors.IdColumnUpdate);\n }\n\n if (!isUpdated(operation)) {\n return [];\n }\n\n const queries: CompiledQuery[] = [];\n const alter = () => this.getSchemaBuilder(resolver).alterTable(tableName);\n const physicalColumnName = this.getColumnName(operation.name, logicalTableName, resolver);\n\n // PostgreSQL: Use explicit USING clause for type conversion\n if (operation.updateDataType) {\n const dbType = sql.raw(this.getDBType(col));\n queries.push(\n sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(physicalColumnName)} TYPE ${dbType} USING (${sql.ref(physicalColumnName)}::${dbType})`.compile(\n this.db,\n ),\n );\n }\n\n if (operation.updateNullable) {\n queries.push(\n alter()\n .alterColumn(physicalColumnName, (build) =>\n col.isNullable ? build.dropNotNull() : build.setNotNull(),\n )\n .compile(),\n );\n }\n\n if (operation.updateDefault) {\n const defaultValue = this.getDefaultValue(col);\n queries.push(\n alter()\n .alterColumn(physicalColumnName, (build) => {\n if (!defaultValue) {\n return build.dropDefault();\n }\n return build.setDefault(defaultValue);\n })\n .compile(),\n );\n }\n\n return queries;\n }\n}\n"],"mappings":";;;;;AAUA,MAAM,SAAS,EACb,gBACE,mHACH;;;;;AAMD,IAAa,uBAAb,cAA0C,aAAa;;;;CAIrD,AAAS,WAAW,YAAwD;AAC1E,SAAO;;;;;;CAOT,AAAS,mBAAmB,SAA2D;AACrF,SAAO;;CAGT,AAAS,gBAAgB,QAAqD;EAC5E,MAAM,QAAQ,OAAO;AACrB,MAAI,CAAC,MACH;AAGF,MAAI,WAAW,SAAS,MAAM,UAAU,OACtC,QAAO,IAAI,IAAI,MAAM,MAAM;AAG7B,MAAI,eAAe,SAAS,MAAM,cAAc,MAC9C,QAAO,GAAG;AAIZ,MAAI,aAAa,MACf;;;;;CASJ,AAAmB,oBACjB,WACA,kBACA,WACA,UACiC;EACjC,MAAM,MAAM,UAAU;AAEtB,MAAI,IAAI,SAAS,iBAAiB,IAAI,SAAS,cAC7C,OAAM,IAAI,MAAM,OAAO,eAAe;AAGxC,MAAI,CAAC,UAAU,UAAU,CACvB,QAAO,EAAE;EAGX,MAAMA,UAA2B,EAAE;EACnC,MAAM,cAAc,KAAK,iBAAiB,SAAS,CAAC,WAAW,UAAU;EACzE,MAAM,qBAAqB,KAAK,cAAc,UAAU,MAAM,kBAAkB,SAAS;AAGzF,MAAI,UAAU,gBAAgB;GAC5B,MAAM,SAAS,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAC3C,WAAQ,KACN,GAAG,eAAe,IAAI,IAAI,UAAU,CAAC,gBAAgB,IAAI,IAAI,mBAAmB,CAAC,QAAQ,OAAO,UAAU,IAAI,IAAI,mBAAmB,CAAC,IAAI,OAAO,GAAG,QAClJ,KAAK,GACN,CACF;;AAGH,MAAI,UAAU,eACZ,SAAQ,KACN,OAAO,CACJ,YAAY,qBAAqB,UAChC,IAAI,aAAa,MAAM,aAAa,GAAG,MAAM,YAAY,CAC1D,CACA,SAAS,CACb;AAGH,MAAI,UAAU,eAAe;GAC3B,MAAM,eAAe,KAAK,gBAAgB,IAAI;AAC9C,WAAQ,KACN,OAAO,CACJ,YAAY,qBAAqB,UAAU;AAC1C,QAAI,CAAC,aACH,QAAO,MAAM,aAAa;AAE5B,WAAO,MAAM,WAAW,aAAa;KACrC,CACD,SAAS,CACb;;AAGH,SAAO"}
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"}