@fragno-dev/db 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/.turbo/turbo-build.log +202 -140
  2. package/CHANGELOG.md +35 -0
  3. package/README.md +30 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  19. package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  21. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  31. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +39 -29
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  41. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  42. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  43. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  44. package/dist/adapters/generic-sql/uow-decoder.js +7 -3
  45. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  46. package/dist/adapters/generic-sql/uow-encoder.js +28 -8
  47. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  48. package/dist/adapters/in-memory/condition-evaluator.js +131 -0
  49. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  50. package/dist/adapters/in-memory/errors.d.ts +13 -0
  51. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  52. package/dist/adapters/in-memory/errors.js +23 -0
  53. package/dist/adapters/in-memory/errors.js.map +1 -0
  54. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  55. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  56. package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
  57. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  58. package/dist/adapters/in-memory/in-memory-uow.js +648 -0
  59. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  60. package/dist/adapters/in-memory/index.d.ts +4 -0
  61. package/dist/adapters/in-memory/index.js +4 -0
  62. package/dist/adapters/in-memory/options.d.ts +28 -0
  63. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  64. package/dist/adapters/in-memory/options.js +61 -0
  65. package/dist/adapters/in-memory/options.js.map +1 -0
  66. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  67. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  68. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  69. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  70. package/dist/adapters/in-memory/store.js +71 -0
  71. package/dist/adapters/in-memory/store.js.map +1 -0
  72. package/dist/adapters/in-memory/value-comparison.js +28 -0
  73. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  74. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  75. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  76. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  77. package/dist/adapters/sql/index.d.ts +5 -0
  78. package/dist/adapters/sql/index.js +4 -0
  79. package/dist/db-fragment-definition-builder.d.ts +18 -7
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +116 -54
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
  84. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  85. package/dist/dispatchers/cloudflare-do/index.js +63 -0
  86. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  87. package/dist/dispatchers/node/index.d.ts +17 -0
  88. package/dist/dispatchers/node/index.d.ts.map +1 -0
  89. package/dist/dispatchers/node/index.js +59 -0
  90. package/dist/dispatchers/node/index.js.map +1 -0
  91. package/dist/fragments/internal-fragment.d.ts +79 -2
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +150 -32
  94. package/dist/fragments/internal-fragment.js.map +1 -1
  95. package/dist/fragments/internal-fragment.routes.js +29 -0
  96. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  97. package/dist/fragments/internal-fragment.schema.d.ts +9 -0
  98. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  99. package/dist/fragments/internal-fragment.schema.js +22 -0
  100. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  101. package/dist/hooks/durable-hooks-processor.d.ts +14 -0
  102. package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
  103. package/dist/hooks/durable-hooks-processor.js +32 -0
  104. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  105. package/dist/hooks/hooks.d.ts +42 -1
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +72 -6
  108. package/dist/hooks/hooks.js.map +1 -1
  109. package/dist/migration-engine/auto-from-schema.js +14 -11
  110. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  111. package/dist/migration-engine/generation-engine.d.ts +16 -10
  112. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  113. package/dist/migration-engine/generation-engine.js +72 -33
  114. package/dist/migration-engine/generation-engine.js.map +1 -1
  115. package/dist/migration-engine/shared.js.map +1 -1
  116. package/dist/mod.d.ts +15 -8
  117. package/dist/mod.d.ts.map +1 -1
  118. package/dist/mod.js +14 -8
  119. package/dist/mod.js.map +1 -1
  120. package/dist/naming/sql-naming.d.ts +19 -0
  121. package/dist/naming/sql-naming.d.ts.map +1 -0
  122. package/dist/naming/sql-naming.js +116 -0
  123. package/dist/naming/sql-naming.js.map +1 -0
  124. package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
  125. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
  126. package/dist/outbox/outbox-builder.js +156 -0
  127. package/dist/outbox/outbox-builder.js.map +1 -0
  128. package/dist/outbox/outbox.d.ts +52 -0
  129. package/dist/outbox/outbox.d.ts.map +1 -0
  130. package/dist/outbox/outbox.js +37 -0
  131. package/dist/outbox/outbox.js.map +1 -0
  132. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
  133. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
  134. package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
  135. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  136. package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
  137. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
  138. package/dist/packages/fragno/dist/api/route.js +14 -1
  139. package/dist/packages/fragno/dist/api/route.js.map +1 -1
  140. package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
  141. package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
  142. package/dist/query/column-defaults.js +20 -4
  143. package/dist/query/column-defaults.js.map +1 -1
  144. package/dist/query/cursor.d.ts +3 -1
  145. package/dist/query/cursor.d.ts.map +1 -1
  146. package/dist/query/cursor.js +45 -14
  147. package/dist/query/cursor.js.map +1 -1
  148. package/dist/query/db-now.d.ts +8 -0
  149. package/dist/query/db-now.d.ts.map +1 -0
  150. package/dist/query/db-now.js +7 -0
  151. package/dist/query/db-now.js.map +1 -0
  152. package/dist/query/serialize/create-sql-serializer.js +3 -2
  153. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  154. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  155. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  156. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  157. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  158. package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
  159. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  160. package/dist/query/serialize/sql-serializer.js +2 -2
  161. package/dist/query/serialize/sql-serializer.js.map +1 -1
  162. package/dist/query/simple-query-interface.d.ts +6 -1
  163. package/dist/query/simple-query-interface.d.ts.map +1 -1
  164. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  165. package/dist/query/unit-of-work/execute-unit-of-work.js +11 -6
  166. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  167. package/dist/query/unit-of-work/unit-of-work.d.ts +50 -14
  168. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  169. package/dist/query/unit-of-work/unit-of-work.js +86 -5
  170. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  171. package/dist/query/value-decoding.js +9 -6
  172. package/dist/query/value-decoding.js.map +1 -1
  173. package/dist/query/value-encoding.js +29 -9
  174. package/dist/query/value-encoding.js.map +1 -1
  175. package/dist/schema/create.d.ts +38 -14
  176. package/dist/schema/create.d.ts.map +1 -1
  177. package/dist/schema/create.js +81 -42
  178. package/dist/schema/create.js.map +1 -1
  179. package/dist/schema/generate-id.js +2 -2
  180. package/dist/schema/generate-id.js.map +1 -1
  181. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  182. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  183. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  184. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  185. package/dist/schema/validator.d.ts +10 -0
  186. package/dist/schema/validator.d.ts.map +1 -0
  187. package/dist/schema/validator.js +123 -0
  188. package/dist/schema/validator.js.map +1 -0
  189. package/dist/schema-output/drizzle.d.ts +30 -0
  190. package/dist/schema-output/drizzle.d.ts.map +1 -0
  191. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  192. package/dist/schema-output/drizzle.js.map +1 -0
  193. package/dist/schema-output/prisma.d.ts +17 -0
  194. package/dist/schema-output/prisma.d.ts.map +1 -0
  195. package/dist/schema-output/prisma.js +296 -0
  196. package/dist/schema-output/prisma.js.map +1 -0
  197. package/dist/util/default-database-adapter.js +61 -0
  198. package/dist/util/default-database-adapter.js.map +1 -0
  199. package/dist/with-database.d.ts +1 -1
  200. package/dist/with-database.d.ts.map +1 -1
  201. package/dist/with-database.js +12 -3
  202. package/dist/with-database.js.map +1 -1
  203. package/package.json +43 -28
  204. package/src/adapters/adapters.ts +30 -24
  205. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  206. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  207. package/src/adapters/drizzle/test-utils.ts +12 -8
  208. package/src/adapters/generic-sql/driver-config.ts +38 -0
  209. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  210. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  211. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  212. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  213. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  214. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  215. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  216. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  217. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  218. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  219. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  220. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  221. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  222. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  223. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  224. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  225. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  226. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  227. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  228. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  229. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  230. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  231. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  232. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  233. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  234. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  235. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  236. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  237. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +10 -10
  238. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +7 -7
  239. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  240. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  241. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  242. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  243. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  244. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  245. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  246. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  247. package/src/adapters/in-memory/errors.ts +20 -0
  248. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  249. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  250. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  251. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  252. package/src/adapters/in-memory/index.ts +3 -0
  253. package/src/adapters/in-memory/options.test.ts +41 -0
  254. package/src/adapters/in-memory/options.ts +87 -0
  255. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  256. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  257. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  258. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  259. package/src/adapters/in-memory/store.test.ts +68 -0
  260. package/src/adapters/in-memory/store.ts +145 -0
  261. package/src/adapters/in-memory/value-comparison.ts +53 -0
  262. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  263. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  264. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  265. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  266. package/src/adapters/sql/index.ts +12 -0
  267. package/src/db-fragment-definition-builder.test.ts +30 -12
  268. package/src/db-fragment-definition-builder.ts +142 -73
  269. package/src/db-fragment-instantiator.test.ts +105 -13
  270. package/src/db-fragment-integration.test.ts +9 -7
  271. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  272. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  273. package/src/dispatchers/node/index.test.ts +91 -0
  274. package/src/dispatchers/node/index.ts +87 -0
  275. package/src/fragments/internal-fragment.routes.ts +42 -0
  276. package/src/fragments/internal-fragment.schema.ts +51 -0
  277. package/src/fragments/internal-fragment.test.ts +458 -8
  278. package/src/fragments/internal-fragment.ts +322 -63
  279. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  280. package/src/hooks/durable-hooks-processor.ts +67 -0
  281. package/src/hooks/hooks.test.ts +165 -5
  282. package/src/hooks/hooks.ts +197 -9
  283. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  284. package/src/migration-engine/auto-from-schema.ts +5 -2
  285. package/src/migration-engine/create.test.ts +2 -2
  286. package/src/migration-engine/generation-engine.test.ts +229 -104
  287. package/src/migration-engine/generation-engine.ts +94 -64
  288. package/src/migration-engine/shared.ts +1 -0
  289. package/src/mod.ts +64 -26
  290. package/src/naming/sql-naming.ts +180 -0
  291. package/src/outbox/outbox-builder.ts +241 -0
  292. package/src/outbox/outbox.test.ts +253 -0
  293. package/src/outbox/outbox.ts +137 -0
  294. package/src/query/column-defaults.ts +41 -3
  295. package/src/query/condition-builder.test.ts +3 -3
  296. package/src/query/cursor.test.ts +116 -18
  297. package/src/query/cursor.ts +75 -26
  298. package/src/query/db-now.ts +6 -0
  299. package/src/query/query-type.test.ts +2 -2
  300. package/src/query/serialize/create-sql-serializer.ts +7 -2
  301. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  302. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  303. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  304. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  305. package/src/query/serialize/sql-serializer.ts +4 -4
  306. package/src/query/simple-query-interface.ts +5 -0
  307. package/src/query/unit-of-work/execute-unit-of-work.test.ts +25 -1
  308. package/src/query/unit-of-work/execute-unit-of-work.ts +25 -8
  309. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +12 -12
  310. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  311. package/src/query/unit-of-work/unit-of-work.test.ts +168 -37
  312. package/src/query/unit-of-work/unit-of-work.ts +203 -18
  313. package/src/query/value-decoding.test.ts +13 -2
  314. package/src/query/value-decoding.ts +17 -4
  315. package/src/query/value-encoding.test.ts +85 -2
  316. package/src/query/value-encoding.ts +56 -6
  317. package/src/schema/create.test.ts +129 -42
  318. package/src/schema/create.ts +185 -47
  319. package/src/schema/generate-id.test.ts +2 -2
  320. package/src/schema/generate-id.ts +2 -2
  321. package/src/schema/serialize.test.ts +14 -2
  322. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  323. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  324. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  325. package/src/schema/validator.test.ts +197 -0
  326. package/src/schema/validator.ts +231 -0
  327. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  328. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  329. package/src/schema-output/prisma.test.ts +536 -0
  330. package/src/schema-output/prisma.ts +573 -0
  331. package/src/util/default-database-adapter.ts +106 -0
  332. package/src/with-database.ts +22 -3
  333. package/tsdown.config.ts +6 -4
  334. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  335. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  337. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  338. package/dist/adapters/drizzle/generate.d.ts +0 -30
  339. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/generate.js.map +0 -1
  341. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  342. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  343. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  344. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  345. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  346. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  347. package/dist/adapters/shared/table-name-mapper.js +0 -43
  348. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  349. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  350. package/dist/schema-generator/schema-generator.d.ts +0 -15
  351. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  352. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  353. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  354. package/src/adapters/shared/table-name-mapper.ts +0 -50
  355. package/src/schema-generator/schema-generator.ts +0 -12
@@ -0,0 +1,118 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ DummyDriver,
4
+ MysqlAdapter,
5
+ MysqlQueryCompiler,
6
+ PostgresAdapter,
7
+ PostgresQueryCompiler,
8
+ SqliteAdapter,
9
+ SqliteQueryCompiler,
10
+ } from "kysely";
11
+ import { SqlAdapter } from "../generic-sql-adapter";
12
+ import type { Dialect } from "../../../sql-driver/sql-driver";
13
+ import {
14
+ MySQL2DriverConfig,
15
+ NodePostgresDriverConfig,
16
+ SQLocalDriverConfig,
17
+ } from "../driver-config";
18
+ import { column, idColumn, referenceColumn, schema } from "../../../schema/create";
19
+
20
+ const paritySchema = schema("parity", (s) => {
21
+ return s
22
+ .addTable("users", (t) => {
23
+ return t
24
+ .addColumn("id", idColumn())
25
+ .addColumn("email", column("string"))
26
+ .addColumn(
27
+ "createdAt",
28
+ column("timestamp").defaultTo((b) => b.now()),
29
+ )
30
+ .createIndex("users_email_idx", ["email"], { unique: true });
31
+ })
32
+ .alterTable("users", (t) => {
33
+ return t.addColumn("age", column("integer").nullable()).createIndex("users_age_idx", ["age"]);
34
+ })
35
+ .addTable("posts", (t) => {
36
+ return t
37
+ .addColumn("id", idColumn())
38
+ .addColumn("authorId", referenceColumn())
39
+ .addColumn("title", column("string"))
40
+ .addColumn("isPublished", column("bool").defaultTo(false))
41
+ .createIndex("posts_author_idx", ["authorId"]);
42
+ })
43
+ .addReference("author", {
44
+ type: "one",
45
+ from: { table: "posts", column: "authorId" },
46
+ to: { table: "users", column: "id" },
47
+ });
48
+ });
49
+
50
+ function createDummyDialect(database: "postgresql" | "mysql" | "sqlite"): Dialect {
51
+ switch (database) {
52
+ case "postgresql":
53
+ return {
54
+ createAdapter: () => new PostgresAdapter(),
55
+ createDriver: () => new DummyDriver(),
56
+ createQueryCompiler: () => new PostgresQueryCompiler(),
57
+ };
58
+ case "mysql":
59
+ return {
60
+ createAdapter: () => new MysqlAdapter(),
61
+ createDriver: () => new DummyDriver(),
62
+ createQueryCompiler: () => new MysqlQueryCompiler(),
63
+ };
64
+ case "sqlite":
65
+ return {
66
+ createAdapter: () => new SqliteAdapter(),
67
+ createDriver: () => new DummyDriver(),
68
+ createQueryCompiler: () => new SqliteQueryCompiler(),
69
+ };
70
+ }
71
+ }
72
+
73
+ function getMigrationSql(adapter: SqlAdapter, namespace: string): string[] {
74
+ const prepared = adapter.prepareMigrations(paritySchema, namespace);
75
+ const migration = prepared.compile(0, paritySchema.version, {
76
+ updateVersionInMigration: false,
77
+ });
78
+ return migration.statements.map((statement) => statement.sql);
79
+ }
80
+
81
+ describe("migration SQL parity across SqlAdapter instances", () => {
82
+ const cases = [
83
+ {
84
+ name: "postgresql",
85
+ driverConfig: new NodePostgresDriverConfig(),
86
+ },
87
+ {
88
+ name: "sqlite",
89
+ driverConfig: new SQLocalDriverConfig(),
90
+ },
91
+ {
92
+ name: "mysql",
93
+ driverConfig: new MySQL2DriverConfig(),
94
+ },
95
+ ] as const;
96
+
97
+ for (const testCase of cases) {
98
+ it(`generates identical SQL for ${testCase.name}`, () => {
99
+ const dialect = createDummyDialect(testCase.name);
100
+ const namespace = "parity";
101
+
102
+ const firstAdapter = new SqlAdapter({
103
+ dialect,
104
+ driverConfig: testCase.driverConfig,
105
+ });
106
+
107
+ const secondAdapter = new SqlAdapter({
108
+ dialect,
109
+ driverConfig: testCase.driverConfig,
110
+ });
111
+
112
+ const firstSql = getMigrationSql(firstAdapter, namespace);
113
+ const secondSql = getMigrationSql(secondAdapter, namespace);
114
+
115
+ expect(firstSql).toEqual(secondSql);
116
+ });
117
+ }
118
+ });
@@ -2,6 +2,8 @@ import { describe, expect, it } from "vitest";
2
2
  import type { MigrationOperation } from "../../../../migration-engine/shared";
3
3
  import { createColdKysely } from "../cold-kysely";
4
4
  import { MySQLSQLGenerator } from "./mysql";
5
+ import { column, idColumn, schema } from "../../../../schema/create";
6
+ import { createNamingResolver, type SqlNamingStrategy } from "../../../../naming/sql-naming";
5
7
 
6
8
  describe("MySQLSQLGenerator", () => {
7
9
  const coldKysely = createColdKysely("mysql");
@@ -194,7 +196,7 @@ describe("MySQLSQLGenerator", () => {
194
196
 
195
197
  const sql = compileOne(operation);
196
198
  expect(sql).toMatchInlineSnapshot(
197
- `"create table \`users\` (\`_internalId\` bigint not null primary key auto_increment, \`name\` text not null)"`,
199
+ `"create table \`users\` (\`_internalId\` bigint not null auto_increment, \`name\` text not null, constraint \`users__internalId\` primary key (\`_internalId\`))"`,
198
200
  );
199
201
  });
200
202
  });
@@ -628,6 +630,7 @@ describe("MySQLSQLGenerator", () => {
628
630
  type: "drop-foreign-key",
629
631
  table: "posts",
630
632
  name: "posts_user_id_fk",
633
+ referencedTable: "users",
631
634
  };
632
635
 
633
636
  const sql = compileOne(operation);
@@ -893,10 +896,25 @@ describe("MySQLSQLGenerator", () => {
893
896
  });
894
897
 
895
898
  describe("table name mapping", () => {
896
- const mapper = {
897
- toPhysical: (name: string) => `prefix_${name}`,
898
- toLogical: (name: string) => name.replace("prefix_", ""),
899
+ const mappingSchema = schema("mapping", (s) =>
900
+ s
901
+ .addTable("users", (t) =>
902
+ t.addColumn("id", idColumn()).addColumn("email", column("string")),
903
+ )
904
+ .addTable("posts", (t) =>
905
+ t.addColumn("id", idColumn()).addColumn("user_id", column("string")),
906
+ ),
907
+ );
908
+ const namingStrategy: SqlNamingStrategy = {
909
+ namespaceScope: "suffix",
910
+ namespaceToSchema: (namespace) => namespace,
911
+ tableName: (logicalTable) => `prefix_${logicalTable}`,
912
+ columnName: (logicalColumn) => logicalColumn,
913
+ indexName: (logicalIndex) => `idx_${logicalIndex}`,
914
+ uniqueIndexName: (logicalIndex) => `uidx_${logicalIndex}`,
915
+ foreignKeyName: ({ referenceName }) => referenceName,
899
916
  };
917
+ const resolver = createNamingResolver(mappingSchema, null, namingStrategy);
900
918
 
901
919
  it("should apply table name mapping to create-table", () => {
902
920
  const operation: MigrationOperation = {
@@ -905,7 +923,7 @@ describe("MySQLSQLGenerator", () => {
905
923
  columns: [{ name: "id", type: "integer", isNullable: false, role: "external-id" }],
906
924
  };
907
925
 
908
- const statements = generator.compile([operation], mapper);
926
+ const statements = generator.compile([operation], resolver);
909
927
  expect(statements[1].sql).toMatchInlineSnapshot(
910
928
  `"create table \`prefix_users\` (\`id\` integer not null unique)"`,
911
929
  );
@@ -923,7 +941,7 @@ describe("MySQLSQLGenerator", () => {
923
941
  },
924
942
  };
925
943
 
926
- const statements = generator.compile([operation], mapper);
944
+ const statements = generator.compile([operation], resolver);
927
945
  expect(statements[1].sql).toMatchInlineSnapshot(
928
946
  `"alter table \`prefix_posts\` add constraint \`posts_user_id_fk\` foreign key (\`user_id\`) references \`prefix_users\` (\`id\`) on delete restrict on update restrict"`,
929
947
  );
@@ -938,9 +956,9 @@ describe("MySQLSQLGenerator", () => {
938
956
  unique: true,
939
957
  };
940
958
 
941
- const statements = generator.compile([operation], mapper);
959
+ const statements = generator.compile([operation], resolver);
942
960
  expect(statements[1].sql).toMatchInlineSnapshot(
943
- `"create unique index \`idx_email_prefix_users\` on \`prefix_users\` (\`email\`)"`,
961
+ `"create unique index \`uidx_idx_email\` on \`prefix_users\` (\`email\`)"`,
944
962
  );
945
963
  });
946
964
  });
@@ -5,7 +5,7 @@ import type {
5
5
  MigrationOperation,
6
6
  } from "../../../../migration-engine/shared";
7
7
  import { isUpdated } from "../../../../migration-engine/shared";
8
- import type { TableNameMapper } from "../../../shared/table-name-mapper";
8
+ import type { NamingResolver } from "../../../../naming/sql-naming";
9
9
  import { SQLGenerator } from "../sql-generator";
10
10
 
11
11
  const errors = {
@@ -69,7 +69,9 @@ export class MySQLSQLGenerator extends SQLGenerator {
69
69
  */
70
70
  protected override compileUpdateColumn(
71
71
  tableName: string,
72
+ logicalTableName: string,
72
73
  operation: Extract<ColumnOperation, { type: "update-column" }>,
74
+ resolver?: NamingResolver,
73
75
  ): CompiledQuery | CompiledQuery[] {
74
76
  const col = operation.value;
75
77
 
@@ -82,9 +84,13 @@ export class MySQLSQLGenerator extends SQLGenerator {
82
84
  }
83
85
 
84
86
  // MySQL: Use modifyColumn which requires the full column definition
85
- return this.db.schema
87
+ return this.getSchemaBuilder(resolver)
86
88
  .alterTable(tableName)
87
- .modifyColumn(operation.name, sql.raw(this.getDBType(col)), (b) => this.buildColumn(col, b))
89
+ .modifyColumn(
90
+ this.getColumnName(operation.name, logicalTableName, resolver),
91
+ sql.raw(this.getDBType(col)),
92
+ (b) => this.buildColumn(col, b),
93
+ )
88
94
  .compile();
89
95
  }
90
96
 
@@ -93,12 +99,44 @@ export class MySQLSQLGenerator extends SQLGenerator {
93
99
  */
94
100
  protected override compileDropForeignKey(
95
101
  operation: Extract<MigrationOperation, { type: "drop-foreign-key" }>,
96
- mapper?: TableNameMapper,
102
+ resolver?: NamingResolver,
97
103
  ): CompiledQuery {
98
- const { table, name } = operation;
99
- return this.db.schema
100
- .alterTable(this.getTableName(table, mapper))
101
- .dropConstraint(name)
104
+ const { table, name, referencedTable } = operation;
105
+ return this.getSchemaBuilder(resolver)
106
+ .alterTable(this.getTableName(table, resolver))
107
+ .dropConstraint(this.getForeignKeyName(name, table, referencedTable, resolver))
102
108
  .compile();
103
109
  }
110
+
111
+ /**
112
+ * MySQL: add a named primary key constraint for the internal ID column to align naming.
113
+ */
114
+ protected override compileCreateTable(
115
+ operation: Extract<MigrationOperation, { type: "create-table" }>,
116
+ resolver?: NamingResolver,
117
+ ): CompiledQuery {
118
+ const compiled = super.compileCreateTable(operation, resolver);
119
+ const tableName = this.getTableName(operation.name, resolver);
120
+ const internalIdColumn = operation.columns.find((col) => col.role === "internal-id");
121
+
122
+ if (!internalIdColumn) {
123
+ return compiled;
124
+ }
125
+
126
+ const pkColumn = this.getColumnName(internalIdColumn.name, operation.name, resolver);
127
+ const pkName = `${tableName}__${pkColumn.replace(/^_+/, "")}`;
128
+ const escapedPkColumn = pkColumn.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
129
+ const columnRegex = new RegExp("`" + escapedPkColumn + "`([^,]*?)\\bprimary key\\b", "i");
130
+
131
+ let sqlText = compiled.sql.replace(columnRegex, "`" + pkColumn + "`$1");
132
+ sqlText = sqlText.replace(
133
+ /\)\s*$/,
134
+ ", constraint `" + pkName + "` primary key (`" + pkColumn + "`))",
135
+ );
136
+
137
+ return {
138
+ ...compiled,
139
+ sql: sqlText,
140
+ };
141
+ }
104
142
  }
@@ -2,6 +2,8 @@ import { describe, expect, it } from "vitest";
2
2
  import type { MigrationOperation } from "../../../../migration-engine/shared";
3
3
  import { createColdKysely } from "../cold-kysely";
4
4
  import { PostgresSQLGenerator } from "./postgres";
5
+ import { column, idColumn, schema } from "../../../../schema/create";
6
+ import { createNamingResolver, type SqlNamingStrategy } from "../../../../naming/sql-naming";
5
7
 
6
8
  describe("PostgresSQLGenerator", () => {
7
9
  const coldKysely = createColdKysely("postgresql");
@@ -646,6 +648,7 @@ describe("PostgresSQLGenerator", () => {
646
648
  type: "drop-foreign-key",
647
649
  table: "posts",
648
650
  name: "posts_user_id_fk",
651
+ referencedTable: "users",
649
652
  };
650
653
 
651
654
  const sql = compileOne(operation);
@@ -890,10 +893,25 @@ describe("PostgresSQLGenerator", () => {
890
893
  });
891
894
 
892
895
  describe("table name mapping", () => {
893
- const mapper = {
894
- toPhysical: (name: string) => `prefix_${name}`,
895
- toLogical: (name: string) => name.replace("prefix_", ""),
896
+ const mappingSchema = schema("mapping", (s) =>
897
+ s
898
+ .addTable("users", (t) =>
899
+ t.addColumn("id", idColumn()).addColumn("email", column("string")),
900
+ )
901
+ .addTable("posts", (t) =>
902
+ t.addColumn("id", idColumn()).addColumn("user_id", column("string")),
903
+ ),
904
+ );
905
+ const namingStrategy: SqlNamingStrategy = {
906
+ namespaceScope: "suffix",
907
+ namespaceToSchema: (namespace) => namespace,
908
+ tableName: (logicalTable) => `prefix_${logicalTable}`,
909
+ columnName: (logicalColumn) => logicalColumn,
910
+ indexName: (logicalIndex) => `idx_${logicalIndex}`,
911
+ uniqueIndexName: (logicalIndex) => `uidx_${logicalIndex}`,
912
+ foreignKeyName: ({ referenceName }) => referenceName,
896
913
  };
914
+ const resolver = createNamingResolver(mappingSchema, null, namingStrategy);
897
915
 
898
916
  it("should apply table name mapping to create-table", () => {
899
917
  const operation: MigrationOperation = {
@@ -902,7 +920,7 @@ describe("PostgresSQLGenerator", () => {
902
920
  columns: [{ name: "id", type: "integer", isNullable: false, role: "external-id" }],
903
921
  };
904
922
 
905
- const statements = generator.compile([operation], mapper);
923
+ const statements = generator.compile([operation], resolver);
906
924
  expect(statements[0].sql).toMatchInlineSnapshot(
907
925
  `"create table "prefix_users" ("id" integer not null unique)"`,
908
926
  );
@@ -920,7 +938,7 @@ describe("PostgresSQLGenerator", () => {
920
938
  },
921
939
  };
922
940
 
923
- const statements = generator.compile([operation], mapper);
941
+ const statements = generator.compile([operation], resolver);
924
942
  expect(statements[0].sql).toMatchInlineSnapshot(
925
943
  `"alter table "prefix_posts" add constraint "posts_user_id_fk" foreign key ("user_id") references "prefix_users" ("id") on delete restrict on update restrict"`,
926
944
  );
@@ -935,9 +953,9 @@ describe("PostgresSQLGenerator", () => {
935
953
  unique: true,
936
954
  };
937
955
 
938
- const statements = generator.compile([operation], mapper);
956
+ const statements = generator.compile([operation], resolver);
939
957
  expect(statements[0].sql).toMatchInlineSnapshot(
940
- `"create unique index "idx_email_prefix_users" on "prefix_users" ("email")"`,
958
+ `"create unique index "uidx_idx_email" on "prefix_users" ("email")"`,
941
959
  );
942
960
  });
943
961
  });
@@ -6,6 +6,7 @@ import type {
6
6
  } from "../../../../migration-engine/shared";
7
7
  import { isUpdated } from "../../../../migration-engine/shared";
8
8
  import { SQLGenerator } from "../sql-generator";
9
+ import type { NamingResolver } from "../../../../naming/sql-naming";
9
10
 
10
11
  const errors = {
11
12
  IdColumnUpdate:
@@ -59,7 +60,9 @@ export class PostgresSQLGenerator extends SQLGenerator {
59
60
  */
60
61
  protected override compileUpdateColumn(
61
62
  tableName: string,
63
+ logicalTableName: string,
62
64
  operation: Extract<ColumnOperation, { type: "update-column" }>,
65
+ resolver?: NamingResolver,
63
66
  ): CompiledQuery | CompiledQuery[] {
64
67
  const col = operation.value;
65
68
 
@@ -72,13 +75,14 @@ export class PostgresSQLGenerator extends SQLGenerator {
72
75
  }
73
76
 
74
77
  const queries: CompiledQuery[] = [];
75
- const alter = () => this.db.schema.alterTable(tableName);
78
+ const alter = () => this.getSchemaBuilder(resolver).alterTable(tableName);
79
+ const physicalColumnName = this.getColumnName(operation.name, logicalTableName, resolver);
76
80
 
77
81
  // PostgreSQL: Use explicit USING clause for type conversion
78
82
  if (operation.updateDataType) {
79
83
  const dbType = sql.raw(this.getDBType(col));
80
84
  queries.push(
81
- sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(operation.name)} TYPE ${dbType} USING (${sql.ref(operation.name)}::${dbType})`.compile(
85
+ sql`ALTER TABLE ${sql.ref(tableName)} ALTER COLUMN ${sql.ref(physicalColumnName)} TYPE ${dbType} USING (${sql.ref(physicalColumnName)}::${dbType})`.compile(
82
86
  this.db,
83
87
  ),
84
88
  );
@@ -87,7 +91,7 @@ export class PostgresSQLGenerator extends SQLGenerator {
87
91
  if (operation.updateNullable) {
88
92
  queries.push(
89
93
  alter()
90
- .alterColumn(operation.name, (build) =>
94
+ .alterColumn(physicalColumnName, (build) =>
91
95
  col.isNullable ? build.dropNotNull() : build.setNotNull(),
92
96
  )
93
97
  .compile(),
@@ -98,7 +102,7 @@ export class PostgresSQLGenerator extends SQLGenerator {
98
102
  const defaultValue = this.getDefaultValue(col);
99
103
  queries.push(
100
104
  alter()
101
- .alterColumn(operation.name, (build) => {
105
+ .alterColumn(physicalColumnName, (build) => {
102
106
  if (!defaultValue) {
103
107
  return build.dropDefault();
104
108
  }
@@ -2,11 +2,21 @@ import { describe, expect, it } from "vitest";
2
2
  import type { MigrationOperation } from "../../../../migration-engine/shared";
3
3
  import { createColdKysely } from "../cold-kysely";
4
4
  import { SQLiteSQLGenerator } from "./sqlite";
5
+ import { sqliteStoragePrisma } from "../../sqlite-storage";
6
+ import { column, idColumn, schema } from "../../../../schema/create";
7
+ import { createNamingResolver, type SqlNamingStrategy } from "../../../../naming/sql-naming";
5
8
 
6
9
  describe("SQLiteSQLGenerator", () => {
7
10
  const coldKysely = createColdKysely("sqlite");
8
11
  const generator = new SQLiteSQLGenerator(coldKysely, "sqlite");
9
12
 
13
+ const prismaGenerator = new SQLiteSQLGenerator(
14
+ coldKysely,
15
+ "sqlite",
16
+ undefined,
17
+ sqliteStoragePrisma,
18
+ );
19
+
10
20
  /**
11
21
  * Helper to compile a single operation and extract the main SQL statement.
12
22
  * SQLite preprocessing adds PRAGMA statement, so main statement is at index 1.
@@ -158,7 +168,25 @@ describe("SQLiteSQLGenerator", () => {
158
168
 
159
169
  const sql = compileOne(operation);
160
170
  expect(sql).toMatchInlineSnapshot(
161
- `"create table "timestamps_test" ("id" integer not null unique, "created_at" integer default CURRENT_TIMESTAMP not null)"`,
171
+ `"create table "timestamps_test" ("id" integer not null unique, "created_at" integer default (cast((julianday('now') - 2440587.5)*86400000 as integer)) not null)"`,
172
+ );
173
+ });
174
+
175
+ it("should use text for timestamp/date in prisma storage", () => {
176
+ const operation: MigrationOperation = {
177
+ type: "create-table",
178
+ name: "prisma_timestamps",
179
+ columns: [
180
+ { name: "id", type: "integer", isNullable: false, role: "external-id" },
181
+ { name: "created_at", type: "timestamp", isNullable: false, role: "regular" },
182
+ { name: "published_on", type: "date", isNullable: false, role: "regular" },
183
+ ],
184
+ };
185
+
186
+ const statements = prismaGenerator.compile([operation]);
187
+ expect(statements[0].sql).toBe("PRAGMA defer_foreign_keys = ON");
188
+ expect(statements[1].sql).toMatchInlineSnapshot(
189
+ `"create table "prisma_timestamps" ("id" integer not null unique, "created_at" text not null, "published_on" text not null)"`,
162
190
  );
163
191
  });
164
192
 
@@ -504,6 +532,7 @@ describe("SQLiteSQLGenerator", () => {
504
532
  type: "drop-foreign-key",
505
533
  table: "posts",
506
534
  name: "posts_user_id_fk",
535
+ referencedTable: "users",
507
536
  };
508
537
 
509
538
  expect(() => generator.compile([operation])).toThrow(
@@ -949,7 +978,6 @@ describe("SQLiteSQLGenerator", () => {
949
978
 
950
979
  // Posts table should contain inline FK constraint
951
980
  const postsSql = statements[2].sql;
952
- expect(postsSql).toContain("posts_users_author_fk");
953
981
  expect(postsSql).toContain("foreign key");
954
982
  expect(postsSql).toContain("author_id");
955
983
  expect(postsSql).toContain("references");
@@ -1053,10 +1081,21 @@ describe("SQLiteSQLGenerator", () => {
1053
1081
  });
1054
1082
 
1055
1083
  describe("table name mapping", () => {
1056
- const mapper = {
1057
- toPhysical: (name: string) => `prefix_${name}`,
1058
- toLogical: (name: string) => name.replace("prefix_", ""),
1084
+ const mappingSchema = schema("mapping", (s) =>
1085
+ s.addTable("users", (t) =>
1086
+ t.addColumn("id", idColumn()).addColumn("email", column("string")),
1087
+ ),
1088
+ );
1089
+ const namingStrategy: SqlNamingStrategy = {
1090
+ namespaceScope: "suffix",
1091
+ namespaceToSchema: (namespace) => namespace,
1092
+ tableName: (logicalTable) => `prefix_${logicalTable}`,
1093
+ columnName: (logicalColumn) => logicalColumn,
1094
+ indexName: (logicalIndex) => `idx_${logicalIndex}`,
1095
+ uniqueIndexName: (logicalIndex) => `uidx_${logicalIndex}`,
1096
+ foreignKeyName: ({ referenceName }) => referenceName,
1059
1097
  };
1098
+ const resolver = createNamingResolver(mappingSchema, null, namingStrategy);
1060
1099
 
1061
1100
  it("should apply table name mapping to create-table", () => {
1062
1101
  const operation: MigrationOperation = {
@@ -1065,7 +1104,7 @@ describe("SQLiteSQLGenerator", () => {
1065
1104
  columns: [{ name: "id", type: "integer", isNullable: false, role: "external-id" }],
1066
1105
  };
1067
1106
 
1068
- const statements = generator.compile([operation], mapper);
1107
+ const statements = generator.compile([operation], resolver);
1069
1108
  expect(statements[1].sql).toMatchInlineSnapshot(
1070
1109
  `"create table "prefix_users" ("id" integer not null unique)"`,
1071
1110
  );
@@ -1080,9 +1119,9 @@ describe("SQLiteSQLGenerator", () => {
1080
1119
  unique: true,
1081
1120
  };
1082
1121
 
1083
- const statements = generator.compile([operation], mapper);
1122
+ const statements = generator.compile([operation], resolver);
1084
1123
  expect(statements[1].sql).toMatchInlineSnapshot(
1085
- `"create unique index "idx_email_prefix_users" on "prefix_users" ("email")"`,
1124
+ `"create unique index "uidx_idx_email" on "prefix_users" ("email")"`,
1086
1125
  );
1087
1126
  });
1088
1127
  });
@@ -5,7 +5,7 @@ import type {
5
5
  ForeignKeyInfo,
6
6
  MigrationOperation,
7
7
  } from "../../../../migration-engine/shared";
8
- import type { TableNameMapper } from "../../../shared/table-name-mapper";
8
+ import type { NamingResolver } from "../../../../naming/sql-naming";
9
9
  import { SQLGenerator } from "../sql-generator";
10
10
 
11
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -105,6 +105,10 @@ export class SQLiteSQLGenerator extends SQLGenerator {
105
105
  }
106
106
 
107
107
  if ("dbSpecial" in value && value.dbSpecial === "now") {
108
+ const dbType = this.typeMapper.getDatabaseType(column);
109
+ if (dbType === "integer" && (column.type === "timestamp" || column.type === "date")) {
110
+ return sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`;
111
+ }
108
112
  return sql`CURRENT_TIMESTAMP`;
109
113
  }
110
114
 
@@ -121,15 +125,16 @@ export class SQLiteSQLGenerator extends SQLGenerator {
121
125
  */
122
126
  protected override compileCreateTable(
123
127
  operation: Extract<MigrationOperation, { type: "create-table" }>,
124
- mapper?: TableNameMapper,
128
+ resolver?: NamingResolver,
125
129
  ): CompiledQuery {
126
- const tableName = this.getTableName(operation.name, mapper);
127
- let builder: CreateTableBuilderAny = this.db.schema.createTable(tableName);
130
+ const tableName = this.getTableName(operation.name, resolver);
131
+ let builder: CreateTableBuilderAny = this.getSchemaBuilder(resolver).createTable(tableName);
128
132
 
129
133
  // Add columns
130
134
  for (const col of operation.columns) {
135
+ const columnName = this.getColumnName(col.name, operation.name, resolver);
131
136
  builder = builder.addColumn(
132
- col.name,
137
+ columnName,
133
138
  sql.raw(this.getDBType(col)),
134
139
  (b: ColumnDefinitionBuilder) => this.buildColumn(col, b),
135
140
  );
@@ -140,17 +145,25 @@ export class SQLiteSQLGenerator extends SQLGenerator {
140
145
  if (metadata?.inlineForeignKeys) {
141
146
  for (const fk of metadata.inlineForeignKeys) {
142
147
  builder = builder.addForeignKeyConstraint(
143
- fk.name,
144
- fk.columns,
145
- this.getTableName(fk.referencedTable, mapper),
146
- fk.referencedColumns,
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
+ ),
147
154
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
155
  (cb: any) => cb.onUpdate("restrict").onDelete("restrict"),
149
156
  );
150
157
  }
151
158
  }
152
159
 
153
- return builder.compile();
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
+ };
154
167
  }
155
168
 
156
169
  /**
@@ -158,7 +171,7 @@ export class SQLiteSQLGenerator extends SQLGenerator {
158
171
  */
159
172
  protected override compileAddForeignKey(
160
173
  _operation: Extract<MigrationOperation, { type: "add-foreign-key" }>,
161
- _mapper?: TableNameMapper,
174
+ _resolver?: NamingResolver,
162
175
  ): CompiledQuery {
163
176
  throw new Error(errors.SQLiteUpdateForeignKeys);
164
177
  }
@@ -168,7 +181,7 @@ export class SQLiteSQLGenerator extends SQLGenerator {
168
181
  */
169
182
  protected override compileDropForeignKey(
170
183
  _operation: Extract<MigrationOperation, { type: "drop-foreign-key" }>,
171
- _mapper?: TableNameMapper,
184
+ _resolver?: NamingResolver,
172
185
  ): CompiledQuery {
173
186
  throw new Error(errors.SQLiteUpdateForeignKeys);
174
187
  }
@@ -178,7 +191,9 @@ export class SQLiteSQLGenerator extends SQLGenerator {
178
191
  */
179
192
  protected override compileUpdateColumn(
180
193
  _tableName: string,
194
+ _logicalTableName: string,
181
195
  operation: Extract<ColumnOperation, { type: "update-column" }>,
196
+ _resolver?: NamingResolver,
182
197
  ): CompiledQuery | CompiledQuery[] {
183
198
  const col = operation.value;
184
199
  if (col.role === "external-id" || col.role === "internal-id") {