@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
@@ -1,9 +1,14 @@
1
+ import { createHash } from "node:crypto";
2
+
1
3
  import { type ColumnDefinitionBuilder, type CompiledQuery, type RawBuilder, sql } from "kysely";
4
+
2
5
  import type {
3
6
  ColumnInfo,
4
7
  ColumnOperation,
5
- ForeignKeyInfo,
6
8
  MigrationOperation,
9
+ SqliteAlterTableMetadata,
10
+ SqliteCopyColumn,
11
+ SqliteCreateTableMetadata,
7
12
  } from "../../../../migration-engine/shared";
8
13
  import type { NamingResolver } from "../../../../naming/sql-naming";
9
14
  import { SQLGenerator } from "../sql-generator";
@@ -11,14 +16,6 @@ import { SQLGenerator } from "../sql-generator";
11
16
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
17
  type CreateTableBuilderAny = any;
13
18
 
14
- /**
15
- * Metadata attached to create-table operations for inline foreign keys.
16
- */
17
- interface SqliteCreateTableMetadata {
18
- [key: string]: unknown;
19
- inlineForeignKeys?: ForeignKeyInfo[];
20
- }
21
-
22
19
  const errors = {
23
20
  IdColumnUpdate:
24
21
  "ID columns cannot be updated. Not every database supports updating primary keys and often requires workarounds.",
@@ -27,6 +24,147 @@ const errors = {
27
24
  "SQLite doesn't support modifying foreign keys directly. Use `recreate-table` instead.",
28
25
  } as const;
29
26
 
27
+ type RenameOrDropColumnOperation = Extract<
28
+ ColumnOperation,
29
+ { type: "rename-column" } | { type: "drop-column" }
30
+ >;
31
+
32
+ type CopyColumnMapping = { from: string; to: string };
33
+ type SqliteRecreateTable = NonNullable<SqliteAlterTableMetadata["recreateTable"]>;
34
+ type SqliteRecreateIndex = SqliteRecreateTable["indexes"][number];
35
+ type SqliteRecreateForeignKey = SqliteRecreateTable["foreignKeys"][number];
36
+
37
+ function normalizeCopyColumns(copyColumns: SqliteCopyColumn[]): CopyColumnMapping[] {
38
+ return copyColumns.map((column) =>
39
+ typeof column === "string"
40
+ ? { from: column, to: column }
41
+ : { from: column.from, to: column.to },
42
+ );
43
+ }
44
+
45
+ function applyRenameDropToColumns(
46
+ columns: ColumnInfo[],
47
+ operations: RenameOrDropColumnOperation[],
48
+ ): ColumnInfo[] {
49
+ let next = columns.map((column) => ({ ...column }));
50
+
51
+ for (const op of operations) {
52
+ if (op.type === "rename-column") {
53
+ const column = next.find((col) => col.name === op.from);
54
+ if (column) {
55
+ column.name = op.to;
56
+ }
57
+ } else if (op.type === "drop-column") {
58
+ next = next.filter((column) => column.name !== op.name);
59
+ }
60
+ }
61
+
62
+ return next;
63
+ }
64
+
65
+ function applyRenameDropToCopyColumns(
66
+ copyColumns: CopyColumnMapping[],
67
+ operations: RenameOrDropColumnOperation[],
68
+ ): CopyColumnMapping[] {
69
+ let next = copyColumns.map((column) => ({ ...column }));
70
+
71
+ for (const op of operations) {
72
+ if (op.type === "rename-column") {
73
+ for (const mapping of next) {
74
+ if (mapping.to === op.from) {
75
+ mapping.to = op.to;
76
+ }
77
+ }
78
+ } else if (op.type === "drop-column") {
79
+ next = next.filter((mapping) => mapping.to !== op.name);
80
+ }
81
+ }
82
+
83
+ return next;
84
+ }
85
+
86
+ function applyRenameDropToIndexes(
87
+ indexes: SqliteRecreateIndex[],
88
+ operations: RenameOrDropColumnOperation[],
89
+ ): SqliteRecreateIndex[] {
90
+ const next: SqliteRecreateIndex[] = [];
91
+
92
+ for (const index of indexes) {
93
+ let columns = [...index.columns];
94
+ let dropped = false;
95
+
96
+ for (const op of operations) {
97
+ if (op.type === "rename-column") {
98
+ columns = columns.map((column) => (column === op.from ? op.to : column));
99
+ } else if (columns.includes(op.name)) {
100
+ dropped = true;
101
+ break;
102
+ }
103
+ }
104
+
105
+ if (!dropped) {
106
+ next.push({ ...index, columns });
107
+ }
108
+ }
109
+
110
+ return next;
111
+ }
112
+
113
+ function applyRenameDropToForeignKeys(
114
+ foreignKeys: SqliteRecreateForeignKey[],
115
+ operations: RenameOrDropColumnOperation[],
116
+ ): SqliteRecreateForeignKey[] {
117
+ const next: SqliteRecreateForeignKey[] = [];
118
+
119
+ for (const foreignKey of foreignKeys) {
120
+ let columns = [...foreignKey.columns];
121
+ let dropped = false;
122
+
123
+ for (const op of operations) {
124
+ if (op.type === "rename-column") {
125
+ columns = columns.map((column) => (column === op.from ? op.to : column));
126
+ } else if (columns.includes(op.name)) {
127
+ dropped = true;
128
+ break;
129
+ }
130
+ }
131
+
132
+ if (!dropped) {
133
+ next.push({
134
+ ...foreignKey,
135
+ columns,
136
+ });
137
+ }
138
+ }
139
+
140
+ return next;
141
+ }
142
+
143
+ function mergeRenameDropIntoRecreate(
144
+ recreate: SqliteRecreateTable,
145
+ operations: ColumnOperation[],
146
+ ): SqliteRecreateTable {
147
+ const renameDropOps = operations.filter(
148
+ (op): op is RenameOrDropColumnOperation =>
149
+ op.type === "rename-column" || op.type === "drop-column",
150
+ );
151
+
152
+ if (renameDropOps.length === 0) {
153
+ return recreate;
154
+ }
155
+
156
+ return {
157
+ ...recreate,
158
+ columns: applyRenameDropToColumns(recreate.columns, renameDropOps),
159
+ copyColumns: applyRenameDropToCopyColumns(
160
+ normalizeCopyColumns(recreate.copyColumns),
161
+ renameDropOps,
162
+ ),
163
+ indexes: applyRenameDropToIndexes(recreate.indexes, renameDropOps),
164
+ foreignKeys: applyRenameDropToForeignKeys(recreate.foreignKeys, renameDropOps),
165
+ };
166
+ }
167
+
30
168
  /**
31
169
  * SQLite-specific SQL generator.
32
170
  * Handles SQLite's limitations around foreign keys and column updates.
@@ -45,6 +183,7 @@ export class SQLiteSQLGenerator extends SQLGenerator {
45
183
 
46
184
  const result: MigrationOperation[] = [];
47
185
  const createTableIndices = new Map<string, number>();
186
+ const alterTableIndices = new Map<string, number[]>();
48
187
  const foreignKeysByTable = new Map<
49
188
  string,
50
189
  Extract<MigrationOperation, { type: "add-foreign-key" }>[]
@@ -55,6 +194,15 @@ export class SQLiteSQLGenerator extends SQLGenerator {
55
194
  if (op.type === "create-table") {
56
195
  createTableIndices.set(op.name, result.length);
57
196
  result.push(op);
197
+ } else if (op.type === "alter-table") {
198
+ const index = result.length;
199
+ result.push(op);
200
+ const existing = alterTableIndices.get(op.name);
201
+ if (existing) {
202
+ existing.push(index);
203
+ } else {
204
+ alterTableIndices.set(op.name, [index]);
205
+ }
58
206
  } else if (op.type === "add-foreign-key") {
59
207
  if (!foreignKeysByTable.has(op.table)) {
60
208
  foreignKeysByTable.set(op.table, []);
@@ -65,20 +213,81 @@ export class SQLiteSQLGenerator extends SQLGenerator {
65
213
  }
66
214
  }
67
215
 
216
+ const extractCreateColumn = (tableName: string, columnName: string): ColumnInfo | undefined => {
217
+ const indices = alterTableIndices.get(tableName);
218
+ if (!indices) {
219
+ return undefined;
220
+ }
221
+
222
+ for (const index of indices) {
223
+ const operation = result[index];
224
+ if (!operation || operation.type !== "alter-table") {
225
+ continue;
226
+ }
227
+
228
+ let extracted: ColumnInfo | undefined;
229
+ const nextValue = operation.value.filter((columnOp) => {
230
+ if (columnOp.type === "create-column" && columnOp.value.name === columnName) {
231
+ extracted = columnOp.value;
232
+ return false;
233
+ }
234
+ return true;
235
+ });
236
+
237
+ if (extracted) {
238
+ result[index] = { ...operation, value: nextValue };
239
+ return extracted;
240
+ }
241
+ }
242
+
243
+ return undefined;
244
+ };
245
+
68
246
  // Second pass: attach foreign keys as metadata to create-table ops
69
247
  for (const [tableName, fkOps] of foreignKeysByTable.entries()) {
70
248
  const createTableIdx = createTableIndices.get(tableName);
71
249
 
72
250
  if (createTableIdx !== undefined) {
73
- const createOp = result[createTableIdx];
251
+ let createOp = result[createTableIdx];
74
252
  if (createOp.type === "create-table") {
253
+ const columnNames = new Set(createOp.columns.map((column) => column.name));
254
+ const missingColumns = new Set<string>();
255
+
256
+ for (const fkOp of fkOps) {
257
+ for (const columnName of fkOp.value.columns) {
258
+ if (!columnNames.has(columnName)) {
259
+ missingColumns.add(columnName);
260
+ }
261
+ }
262
+ }
263
+
264
+ if (missingColumns.size > 0) {
265
+ for (const columnName of Array.from(missingColumns)) {
266
+ const column = extractCreateColumn(tableName, columnName);
267
+ if (column) {
268
+ createOp = { ...createOp, columns: [...createOp.columns, column] };
269
+ result[createTableIdx] = createOp;
270
+ columnNames.add(columnName);
271
+ missingColumns.delete(columnName);
272
+ }
273
+ }
274
+ }
275
+
276
+ if (missingColumns.size > 0) {
277
+ throw new Error(
278
+ `SQLite FK preprocessing failed for "${tableName}": missing column(s) ${Array.from(
279
+ missingColumns,
280
+ ).join(", ")} required by foreign keys.`,
281
+ );
282
+ }
283
+
284
+ const existingInline = (createOp.metadata as SqliteCreateTableMetadata | undefined)
285
+ ?.inlineForeignKeys;
75
286
  const metadata: SqliteCreateTableMetadata = {
76
- inlineForeignKeys: fkOps.map((fkOp) => fkOp.value),
77
- };
78
- result[createTableIdx] = {
79
- ...createOp,
80
- metadata,
287
+ ...createOp.metadata,
288
+ inlineForeignKeys: [...(existingInline ?? []), ...fkOps.map((fkOp) => fkOp.value)],
81
289
  };
290
+ result[createTableIdx] = { ...createOp, metadata };
82
291
  }
83
292
  } else {
84
293
  // Table already exists - keep add-foreign-key operations (will throw error during compile)
@@ -87,7 +296,13 @@ export class SQLiteSQLGenerator extends SQLGenerator {
87
296
  }
88
297
 
89
298
  // Add pragma at the beginning for deferred foreign key checking
90
- return [{ type: "custom", sql: "PRAGMA defer_foreign_keys = ON" }, ...result];
299
+ const pruned = result.filter((op) => {
300
+ if (op.type !== "alter-table") {
301
+ return true;
302
+ }
303
+ return op.value.length > 0;
304
+ });
305
+ return [{ type: "custom", sql: "PRAGMA defer_foreign_keys = ON" }, ...pruned];
91
306
  }
92
307
 
93
308
  override applyAutoIncrement(builder: ColumnDefinitionBuilder): ColumnDefinitionBuilder {
@@ -128,42 +343,14 @@ export class SQLiteSQLGenerator extends SQLGenerator {
128
343
  resolver?: NamingResolver,
129
344
  ): CompiledQuery {
130
345
  const tableName = this.getTableName(operation.name, resolver);
131
- let builder: CreateTableBuilderAny = this.getSchemaBuilder(resolver).createTable(tableName);
132
-
133
- // Add columns
134
- for (const col of operation.columns) {
135
- const columnName = this.getColumnName(col.name, operation.name, resolver);
136
- builder = builder.addColumn(
137
- columnName,
138
- sql.raw(this.getDBType(col)),
139
- (b: ColumnDefinitionBuilder) => this.buildColumn(col, b),
140
- );
141
- }
142
-
143
- // Add inline foreign keys from metadata
144
346
  const metadata = operation.metadata as SqliteCreateTableMetadata | undefined;
145
- if (metadata?.inlineForeignKeys) {
146
- for (const fk of metadata.inlineForeignKeys) {
147
- builder = builder.addForeignKeyConstraint(
148
- this.getForeignKeyName(fk.name, operation.name, fk.referencedTable, resolver),
149
- fk.columns.map((columnName) => this.getColumnName(columnName, operation.name, resolver)),
150
- this.getTableName(fk.referencedTable, resolver),
151
- fk.referencedColumns.map((columnName) =>
152
- this.getColumnName(columnName, fk.referencedTable, resolver),
153
- ),
154
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
155
- (cb: any) => cb.onUpdate("restrict").onDelete("restrict"),
156
- );
157
- }
158
- }
159
-
160
- const compiled = builder.compile();
161
- // SQLite constraint names are ignored by Drizzle migrations; strip them for parity.
162
- const sqlText = compiled.sql.replace(/\bconstraint\s+"[^"]+"\s+foreign key\b/gi, "foreign key");
163
- return {
164
- ...compiled,
165
- sql: sqlText,
166
- };
347
+ return this.compileCreateTableForName(
348
+ tableName,
349
+ operation.name,
350
+ operation.columns,
351
+ metadata,
352
+ resolver,
353
+ );
167
354
  }
168
355
 
169
356
  /**
@@ -187,18 +374,159 @@ export class SQLiteSQLGenerator extends SQLGenerator {
187
374
  }
188
375
 
189
376
  /**
190
- * SQLite doesn't support updating columns.
377
+ * SQLite doesn't support updating columns directly. Use table recreation when metadata is provided.
191
378
  */
379
+ protected override compileAlterTable(
380
+ operation: Extract<MigrationOperation, { type: "alter-table" }>,
381
+ resolver?: NamingResolver,
382
+ ): CompiledQuery[] {
383
+ const hasUpdateColumn = operation.value.some((columnOp) => columnOp.type === "update-column");
384
+
385
+ if (!hasUpdateColumn) {
386
+ return super.compileAlterTable(operation, resolver);
387
+ }
388
+
389
+ for (const columnOp of operation.value) {
390
+ if (columnOp.type !== "update-column") {
391
+ continue;
392
+ }
393
+ const col = columnOp.value;
394
+ if (col.role === "external-id" || col.role === "internal-id") {
395
+ throw new Error(errors.IdColumnUpdate);
396
+ }
397
+ }
398
+
399
+ const metadata = operation.metadata as SqliteAlterTableMetadata | undefined;
400
+ const recreate = metadata?.recreateTable;
401
+ if (!recreate) {
402
+ throw new Error(errors.SQLiteUpdateColumn);
403
+ }
404
+
405
+ const mergedRecreate = mergeRenameDropIntoRecreate(recreate, operation.value);
406
+ return this.compileRecreateTable(operation.name, mergedRecreate, resolver);
407
+ }
408
+
192
409
  protected override compileUpdateColumn(
193
410
  _tableName: string,
194
411
  _logicalTableName: string,
195
- operation: Extract<ColumnOperation, { type: "update-column" }>,
412
+ _operation: Extract<ColumnOperation, { type: "update-column" }>,
196
413
  _resolver?: NamingResolver,
197
414
  ): CompiledQuery | CompiledQuery[] {
198
- const col = operation.value;
199
- if (col.role === "external-id" || col.role === "internal-id") {
200
- throw new Error(errors.IdColumnUpdate);
201
- }
202
415
  throw new Error(errors.SQLiteUpdateColumn);
203
416
  }
417
+
418
+ private compileRecreateTable(
419
+ logicalTableName: string,
420
+ recreate: NonNullable<SqliteAlterTableMetadata["recreateTable"]>,
421
+ resolver?: NamingResolver,
422
+ ): CompiledQuery[] {
423
+ const queries: CompiledQuery[] = [];
424
+ const tableName = this.getTableName(logicalTableName, resolver);
425
+ const tempTableName = `${tableName}__fragno_tmp_${createHash("md5")
426
+ .update(tableName)
427
+ .digest("hex")
428
+ .slice(0, 6)}`;
429
+
430
+ queries.push(this.compileRaw(sql.raw("PRAGMA foreign_keys = OFF")));
431
+
432
+ queries.push(
433
+ this.compileCreateTableForName(
434
+ tempTableName,
435
+ logicalTableName,
436
+ recreate.columns,
437
+ {
438
+ inlineForeignKeys: recreate.foreignKeys,
439
+ },
440
+ resolver,
441
+ ),
442
+ );
443
+
444
+ const copyColumns = normalizeCopyColumns(recreate.copyColumns);
445
+ if (copyColumns.length > 0) {
446
+ const targetRefs = copyColumns.map((column) =>
447
+ sql.ref(this.getColumnName(column.to, logicalTableName, resolver)),
448
+ );
449
+ const sourceRefs = copyColumns.map((column) =>
450
+ sql.ref(this.getColumnName(column.from, logicalTableName, resolver)),
451
+ );
452
+ const targetList = sql.join(targetRefs);
453
+ const sourceList = sql.join(sourceRefs);
454
+ queries.push(
455
+ sql`insert into ${sql.ref(tempTableName)} (${targetList}) select ${sourceList} from ${sql.ref(
456
+ tableName,
457
+ )}`.compile(this.db),
458
+ );
459
+ }
460
+
461
+ queries.push(this.getSchemaBuilder(resolver).dropTable(tableName).compile());
462
+ queries.push(
463
+ this.getSchemaBuilder(resolver).alterTable(tempTableName).renameTo(tableName).compile(),
464
+ );
465
+
466
+ for (const index of recreate.indexes) {
467
+ const compiled = this.compileAddIndex(
468
+ {
469
+ type: "add-index",
470
+ table: logicalTableName,
471
+ name: index.name,
472
+ columns: index.columns,
473
+ unique: index.unique,
474
+ },
475
+ resolver,
476
+ );
477
+ if (Array.isArray(compiled)) {
478
+ queries.push(...compiled);
479
+ } else {
480
+ queries.push(compiled);
481
+ }
482
+ }
483
+
484
+ queries.push(this.compileRaw(sql.raw("PRAGMA foreign_keys = ON")));
485
+
486
+ return queries;
487
+ }
488
+
489
+ private compileCreateTableForName(
490
+ physicalTableName: string,
491
+ logicalTableName: string,
492
+ columns: ColumnInfo[],
493
+ metadata: SqliteCreateTableMetadata | undefined,
494
+ resolver?: NamingResolver,
495
+ ): CompiledQuery {
496
+ let builder: CreateTableBuilderAny =
497
+ this.getSchemaBuilder(resolver).createTable(physicalTableName);
498
+
499
+ for (const col of columns) {
500
+ const columnName = this.getColumnName(col.name, logicalTableName, resolver);
501
+ builder = builder.addColumn(
502
+ columnName,
503
+ sql.raw(this.getDBType(col)),
504
+ (b: ColumnDefinitionBuilder) => this.buildColumn(col, b),
505
+ );
506
+ }
507
+
508
+ if (metadata?.inlineForeignKeys) {
509
+ for (const fk of metadata.inlineForeignKeys) {
510
+ builder = builder.addForeignKeyConstraint(
511
+ this.getForeignKeyName(fk.name, logicalTableName, fk.referencedTable, resolver),
512
+ fk.columns.map((columnName) =>
513
+ this.getColumnName(columnName, logicalTableName, resolver),
514
+ ),
515
+ this.getTableName(fk.referencedTable, resolver),
516
+ fk.referencedColumns.map((columnName) =>
517
+ this.getColumnName(columnName, fk.referencedTable, resolver),
518
+ ),
519
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
520
+ (cb: any) => cb.onUpdate("restrict").onDelete("restrict"),
521
+ );
522
+ }
523
+ }
524
+
525
+ const compiled = builder.compile();
526
+ const sqlText = compiled.sql.replace(/\bconstraint\s+"[^"]+"\s+foreign key\b/gi, "foreign key");
527
+ return {
528
+ ...compiled,
529
+ sql: sqlText,
530
+ };
531
+ }
204
532
  }
@@ -0,0 +1,52 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import type { CompiledQuery } from "kysely";
4
+
5
+ import type { SqlDriverAdapter } from "../../../sql-driver/sql-driver-adapter";
6
+ import { executeMigration } from "./executor";
7
+
8
+ function query(sql: string): CompiledQuery {
9
+ return { sql, parameters: [] } as unknown as CompiledQuery;
10
+ }
11
+
12
+ describe("executeMigration", () => {
13
+ it("runs foreign_keys pragmas outside the transaction", async () => {
14
+ const calls: string[] = [];
15
+
16
+ const driver = {
17
+ executeQuery: async (statement: CompiledQuery) => {
18
+ calls.push(`exec:${statement.sql}`);
19
+ return { rows: [] };
20
+ },
21
+ transaction: async (callback: (trx: SqlDriverAdapter) => Promise<void>) => {
22
+ calls.push("tx:begin");
23
+ const tx = {
24
+ executeQuery: async (statement: CompiledQuery) => {
25
+ calls.push(`tx:${statement.sql}`);
26
+ return { rows: [] };
27
+ },
28
+ } as unknown as SqlDriverAdapter;
29
+ await callback(tx);
30
+ calls.push("tx:commit");
31
+ },
32
+ } as unknown as SqlDriverAdapter;
33
+
34
+ await executeMigration(driver, {
35
+ statements: [
36
+ query("PRAGMA foreign_keys = OFF"),
37
+ query("alter table users rename to users_tmp"),
38
+ query("PRAGMA foreign_keys = ON"),
39
+ ],
40
+ fromVersion: 0,
41
+ toVersion: 1,
42
+ });
43
+
44
+ expect(calls).toEqual([
45
+ "exec:PRAGMA foreign_keys = OFF",
46
+ "tx:begin",
47
+ "tx:alter table users rename to users_tmp",
48
+ "tx:commit",
49
+ "exec:PRAGMA foreign_keys = ON",
50
+ ]);
51
+ });
52
+ });
@@ -1,4 +1,5 @@
1
1
  import type { CompiledQuery } from "kysely";
2
+
2
3
  import type { SqlDriverAdapter } from "../../../sql-driver/sql-driver-adapter";
3
4
 
4
5
  /**
@@ -25,9 +26,51 @@ export async function executeMigration(
25
26
  return;
26
27
  }
27
28
 
28
- await driver.transaction(async (tx) => {
29
- for (const statement of migration.statements) {
30
- await tx.executeQuery(statement);
29
+ const isForeignKeysOff = (statement: CompiledQuery) =>
30
+ /^\s*pragma\s+foreign_keys\s*=\s*off\s*;?\s*$/i.test(statement.sql.trim());
31
+ const isForeignKeysOn = (statement: CompiledQuery) =>
32
+ /^\s*pragma\s+foreign_keys\s*=\s*on\s*;?\s*$/i.test(statement.sql.trim());
33
+
34
+ const preStatements: CompiledQuery[] = [];
35
+ const postStatements: CompiledQuery[] = [];
36
+ const transactionalStatements: CompiledQuery[] = [];
37
+
38
+ for (const statement of migration.statements) {
39
+ if (isForeignKeysOff(statement)) {
40
+ preStatements.push(statement);
41
+ continue;
42
+ }
43
+ if (isForeignKeysOn(statement)) {
44
+ postStatements.push(statement);
45
+ continue;
46
+ }
47
+ transactionalStatements.push(statement);
48
+ }
49
+
50
+ if (preStatements.length === 0 && postStatements.length === 0) {
51
+ await driver.transaction(async (tx) => {
52
+ for (const statement of migration.statements) {
53
+ await tx.executeQuery(statement);
54
+ }
55
+ });
56
+ return;
57
+ }
58
+
59
+ for (const statement of preStatements) {
60
+ await driver.executeQuery(statement);
61
+ }
62
+
63
+ try {
64
+ if (transactionalStatements.length > 0) {
65
+ await driver.transaction(async (tx) => {
66
+ for (const statement of transactionalStatements) {
67
+ await tx.executeQuery(statement);
68
+ }
69
+ });
70
+ }
71
+ } finally {
72
+ for (const statement of postStatements) {
73
+ await driver.executeQuery(statement);
31
74
  }
32
- });
75
+ }
33
76
  }