@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
@@ -3,9 +3,9 @@ import { DummyDriver, MysqlAdapter, PostgresAdapter, SqliteAdapter } from "kysel
3
3
  import {
4
4
  postProcessMigrationFilenames,
5
5
  type GenerationInternalResult,
6
- generateMigrationsOrSchema,
6
+ generateSchemaArtifacts,
7
7
  } from "./generation-engine";
8
- import { KyselyAdapter } from "../adapters/kysely/kysely-adapter";
8
+ import { SqlAdapter } from "../adapters/generic-sql/generic-sql-adapter";
9
9
  import { column, idColumn, schema, type AnySchema } from "../schema/create";
10
10
  import { FragnoDatabase } from "../mod";
11
11
  import {
@@ -14,12 +14,33 @@ import {
14
14
  SQLocalDriverConfig,
15
15
  } from "../adapters/generic-sql/driver-config";
16
16
 
17
- describe("generateMigrationsOrSchema - kysely", () => {
17
+ const buildFile = (
18
+ overrides: Partial<GenerationInternalResult> &
19
+ Pick<GenerationInternalResult, "schema" | "namespace" | "fromVersion" | "toVersion">,
20
+ ): GenerationInternalResult => {
21
+ const namespace = overrides.namespace ?? null;
22
+ const schemaName = overrides.schemaName ?? "test";
23
+ const namespaceKey = overrides.namespaceKey ?? namespace ?? schemaName;
24
+ const isSettings = overrides.isSettings ?? false;
25
+
26
+ return {
27
+ schema: overrides.schema,
28
+ path: overrides.path ?? "placeholder.sql",
29
+ namespace,
30
+ namespaceKey,
31
+ schemaName,
32
+ isSettings,
33
+ fromVersion: overrides.fromVersion,
34
+ toVersion: overrides.toVersion,
35
+ };
36
+ };
37
+
38
+ describe("generateSchemaArtifacts - sql", () => {
18
39
  const mockDate = new Date("2025-10-24T12:00:00Z");
19
- let adapter: KyselyAdapter;
40
+ let adapter: SqlAdapter;
20
41
 
21
42
  beforeAll(() => {
22
- adapter = new KyselyAdapter({
43
+ adapter = new SqlAdapter({
23
44
  dialect: {
24
45
  createAdapter: () => new PostgresAdapter(),
25
46
  createDriver: () => new DummyDriver(),
@@ -48,7 +69,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
48
69
  });
49
70
 
50
71
  it("should generate migration for single database from version 0", async () => {
51
- const testSchema: AnySchema = schema((s) => {
72
+ const testSchema: AnySchema = schema("test", (s) => {
52
73
  return s.addTable("users", (t) => {
53
74
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
54
75
  });
@@ -60,10 +81,10 @@ describe("generateMigrationsOrSchema - kysely", () => {
60
81
  adapter,
61
82
  });
62
83
 
63
- const results = await generateMigrationsOrSchema([fragnoDb]);
84
+ const results = await generateSchemaArtifacts([fragnoDb]);
64
85
 
65
86
  expect(results).toHaveLength(2); // Settings + test-db
66
- expect(results[0].namespace).toBe(""); // Empty namespace for settings table
87
+ expect(results[0].namespace).toBeNull();
67
88
  expect(results[0].path).toMatch(/^20251024_001_f000_t00\d_fragno_db_settings.sql$/);
68
89
  expect(results[0].schema).toContain("create table");
69
90
  expect(results[0].schema).toContain("fragno_db_settings");
@@ -71,23 +92,23 @@ describe("generateMigrationsOrSchema - kysely", () => {
71
92
  expect(results[1].namespace).toBe("test-db");
72
93
  expect(results[1].path).toBe("20251024_002_f000_t001_test-db.sql");
73
94
  expect(results[1].schema).toContain("create table");
74
- expect(results[1].schema).toContain("users_test-db");
95
+ expect(results[1].schema).toContain('"test-db"."users"');
75
96
  });
76
97
 
77
98
  it("should generate migrations for multiple databases in alphabetical order", async () => {
78
- const schema1: AnySchema = schema((s) => {
99
+ const schema1: AnySchema = schema("schema1", (s) => {
79
100
  return s.addTable("users", (t) => {
80
101
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
81
102
  });
82
103
  });
83
104
 
84
- const schema2: AnySchema = schema((s) => {
105
+ const schema2: AnySchema = schema("schema2", (s) => {
85
106
  return s.addTable("posts", (t) => {
86
107
  return t.addColumn("id", idColumn()).addColumn("title", column("string"));
87
108
  });
88
109
  });
89
110
 
90
- const schema3: AnySchema = schema((s) => {
111
+ const schema3: AnySchema = schema("schema3", (s) => {
91
112
  return s.addTable("comments", (t) => {
92
113
  return t.addColumn("id", idColumn()).addColumn("text", column("string"));
93
114
  });
@@ -111,27 +132,27 @@ describe("generateMigrationsOrSchema - kysely", () => {
111
132
  adapter,
112
133
  });
113
134
 
114
- const results = await generateMigrationsOrSchema([fragnoDb1, fragnoDb2, fragnoDb3]);
135
+ const results = await generateSchemaArtifacts([fragnoDb1, fragnoDb2, fragnoDb3]);
115
136
 
116
137
  expect(results).toHaveLength(4); // Settings + 3 databases
117
- expect(results[0].namespace).toBe(""); // Empty namespace for settings table
138
+ expect(results[0].namespace).toBeNull();
118
139
  expect(results[0].path).toMatch(/^20251024_001_f000_t00\d_fragno_db_settings.sql$/);
119
140
 
120
141
  expect(results[1].namespace).toBe("apple-db");
121
142
  expect(results[1].path).toBe("20251024_002_f000_t001_apple-db.sql");
122
- expect(results[1].schema).toContain("posts_apple-db");
143
+ expect(results[1].schema).toContain('"apple-db"."posts"');
123
144
 
124
145
  expect(results[2].namespace).toBe("mango-db");
125
146
  expect(results[2].path).toBe("20251024_003_f000_t001_mango-db.sql");
126
- expect(results[2].schema).toContain("comments_mango-db");
147
+ expect(results[2].schema).toContain('"mango-db"."comments"');
127
148
 
128
149
  expect(results[3].namespace).toBe("zebra-db");
129
150
  expect(results[3].path).toBe("20251024_004_f000_t001_zebra-db.sql");
130
- expect(results[3].schema).toContain("users_zebra-db");
151
+ expect(results[3].schema).toContain('"zebra-db"."users"');
131
152
  });
132
153
 
133
154
  it("should handle existing settings version and generate both settings and fragment migrations", async () => {
134
- const testSchema: AnySchema = schema((s) => {
155
+ const testSchema: AnySchema = schema("test", (s) => {
135
156
  return s
136
157
  .addTable("users", (t) => {
137
158
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
@@ -150,12 +171,12 @@ describe("generateMigrationsOrSchema - kysely", () => {
150
171
  adapter,
151
172
  });
152
173
 
153
- const results = await generateMigrationsOrSchema([fragnoDb]);
174
+ const results = await generateSchemaArtifacts([fragnoDb]);
154
175
 
155
176
  // Settings table already at version 1, so no settings migration needed
156
177
  // But fragment migration is still generated
157
178
  expect(results).toHaveLength(2);
158
- expect(results[0].namespace).toBe(""); // Empty namespace for settings table
179
+ expect(results[0].namespace).toBeNull();
159
180
  expect(results[1].namespace).toBe("test-db");
160
181
  expect(results[1].path).toBe("20251024_002_f000_t002_test-db.sql");
161
182
  expect(results[1].schema).toContain("create table");
@@ -163,7 +184,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
163
184
  });
164
185
 
165
186
  it("should generate settings migration even with no fragment changes", async () => {
166
- const testSchema: AnySchema = schema((s) => {
187
+ const testSchema: AnySchema = schema("test", (s) => {
167
188
  return s.addTable("users", (t) => {
168
189
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
169
190
  });
@@ -176,24 +197,26 @@ describe("generateMigrationsOrSchema - kysely", () => {
176
197
  });
177
198
 
178
199
  // Generate with toVersion = 0, fromVersion = 0 (no fragment changes)
179
- const results = await generateMigrationsOrSchema([fragnoDb], {
200
+ const results = await generateSchemaArtifacts([fragnoDb], {
180
201
  toVersion: 0,
181
202
  fromVersion: 0,
182
203
  });
183
204
 
184
- // Settings migration is generated, but no fragment migration (since toVersion=0)
185
- expect(results).toHaveLength(1);
186
- expect(results[0].namespace).toBe(""); // Empty namespace for settings table
205
+ // Settings migration is generated, and fragment migration creates schema (toVersion=0)
206
+ expect(results).toHaveLength(2);
207
+ expect(results[0].namespace).toBeNull();
208
+ expect(results[1].namespace).toBe("test-db");
209
+ expect(results[1].schema).toContain('CREATE SCHEMA IF NOT EXISTS "test-db"');
187
210
  });
188
211
 
189
212
  it("should throw error when no databases provided", async () => {
190
- await expect(generateMigrationsOrSchema([])).rejects.toThrow(
213
+ await expect(generateSchemaArtifacts([])).rejects.toThrow(
191
214
  "No databases provided for schema generation",
192
215
  );
193
216
  });
194
217
 
195
218
  it("should throw error when database connection is unhealthy", async () => {
196
- const testSchema: AnySchema = schema((s) => {
219
+ const testSchema: AnySchema = schema("test", (s) => {
197
220
  return s.addTable("users", (t) => {
198
221
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
199
222
  });
@@ -208,13 +231,13 @@ describe("generateMigrationsOrSchema - kysely", () => {
208
231
  adapter,
209
232
  });
210
233
 
211
- await expect(generateMigrationsOrSchema([fragnoDb])).rejects.toThrow(
234
+ await expect(generateSchemaArtifacts([fragnoDb])).rejects.toThrow(
212
235
  "Database connection is not healthy",
213
236
  );
214
237
  });
215
238
 
216
239
  it("should generate SQL with correct version tracking in settings", async () => {
217
- const testSchema: AnySchema = schema((s) => {
240
+ const testSchema: AnySchema = schema("test", (s) => {
218
241
  return s.addTable("users", (t) => {
219
242
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
220
243
  });
@@ -226,7 +249,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
226
249
  adapter,
227
250
  });
228
251
 
229
- const results = await generateMigrationsOrSchema([fragnoDb]);
252
+ const results = await generateSchemaArtifacts([fragnoDb]);
230
253
 
231
254
  // Check settings migration includes version tracking
232
255
  expect(results[0].schema).toContain("fragno_db_settings");
@@ -239,7 +262,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
239
262
  });
240
263
 
241
264
  it("should generate INSERT for version 0->N and UPDATE for version N->M", async () => {
242
- const testSchema: AnySchema = schema((s) => {
265
+ const testSchema: AnySchema = schema("test", (s) => {
243
266
  return s
244
267
  .addTable("users", (t) => {
245
268
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
@@ -257,7 +280,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
257
280
 
258
281
  // First migration: 0 -> 1 (should use INSERT)
259
282
  vi.spyOn(adapter, "getSchemaVersion").mockResolvedValueOnce(undefined);
260
- const resultsV1 = await generateMigrationsOrSchema([fragnoDb], {
283
+ const resultsV1 = await generateSchemaArtifacts([fragnoDb], {
261
284
  fromVersion: 0,
262
285
  toVersion: 1,
263
286
  });
@@ -268,14 +291,16 @@ describe("generateMigrationsOrSchema - kysely", () => {
268
291
  expect(resultsV1[1].schema).toContain("test-db.schema_version");
269
292
  expect(resultsV1[1].schema).toContain("'1'");
270
293
  expect(resultsV1[1].schema).toMatchInlineSnapshot(`
271
- "create table "users_test-db" ("id" varchar(30) not null unique, "name" text not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
294
+ "CREATE SCHEMA IF NOT EXISTS "test-db";
295
+
296
+ create table "test-db"."users" ("id" varchar(30) not null unique, "name" text not null, "_internalId" bigserial not null primary key, "_version" integer default 0 not null);
272
297
 
273
298
  insert into "fragno_db_settings" ("id", "key", "value") values ('6_U2SCfiaNG9VyYmQ_JwzQ', 'test-db.schema_version', '1');"
274
299
  `);
275
300
 
276
301
  // Second migration: 1 -> 2 (should use UPDATE)
277
302
  vi.spyOn(adapter, "getSchemaVersion").mockResolvedValueOnce("1");
278
- const resultsV2 = await generateMigrationsOrSchema([fragnoDb], {
303
+ const resultsV2 = await generateSchemaArtifacts([fragnoDb], {
279
304
  fromVersion: 1,
280
305
  toVersion: 2,
281
306
  });
@@ -287,14 +312,16 @@ describe("generateMigrationsOrSchema - kysely", () => {
287
312
  expect(resultsV2[1].schema).toContain("test-db.schema_version");
288
313
  expect(resultsV2[1].schema).toContain("'2'");
289
314
  expect(resultsV2[1].schema).toMatchInlineSnapshot(`
290
- "alter table "users_test-db" add column "email" text;
315
+ "CREATE SCHEMA IF NOT EXISTS "test-db";
316
+
317
+ alter table "test-db"."users" add column "email" text;
291
318
 
292
319
  update "fragno_db_settings" set "value" = '2' where "key" = 'test-db.schema_version';"
293
320
  `);
294
321
  });
295
322
 
296
323
  it("should include MySQL-specific foreign key checks in generated SQL", async () => {
297
- const mysqlAdapter = new KyselyAdapter({
324
+ const mysqlAdapter = new SqlAdapter({
298
325
  dialect: {
299
326
  createAdapter: () => new MysqlAdapter(),
300
327
  createDriver: () => new DummyDriver(),
@@ -311,7 +338,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
311
338
  vi.spyOn(mysqlAdapter, "isConnectionHealthy").mockResolvedValue(true);
312
339
  vi.spyOn(mysqlAdapter, "getSchemaVersion").mockResolvedValue(undefined);
313
340
 
314
- const testSchema: AnySchema = schema((s) => {
341
+ const testSchema: AnySchema = schema("test", (s) => {
315
342
  return s.addTable("users", (t) => {
316
343
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
317
344
  });
@@ -323,7 +350,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
323
350
  adapter: mysqlAdapter,
324
351
  });
325
352
 
326
- const results = await generateMigrationsOrSchema([fragnoDb]);
353
+ const results = await generateSchemaArtifacts([fragnoDb]);
327
354
 
328
355
  expect(results).toHaveLength(2);
329
356
  // Check that MySQL foreign key checks are included
@@ -339,7 +366,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
339
366
  });
340
367
 
341
368
  it("should include SQLite-specific pragma in generated SQL", async () => {
342
- const sqliteAdapter = new KyselyAdapter({
369
+ const sqliteAdapter = new SqlAdapter({
343
370
  dialect: {
344
371
  createAdapter: () => new SqliteAdapter(),
345
372
  createDriver: () => new DummyDriver(),
@@ -356,7 +383,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
356
383
  vi.spyOn(sqliteAdapter, "isConnectionHealthy").mockResolvedValue(true);
357
384
  vi.spyOn(sqliteAdapter, "getSchemaVersion").mockResolvedValue(undefined);
358
385
 
359
- const testSchema: AnySchema = schema((s) => {
386
+ const testSchema: AnySchema = schema("test", (s) => {
360
387
  return s.addTable("users", (t) => {
361
388
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
362
389
  });
@@ -368,7 +395,7 @@ describe("generateMigrationsOrSchema - kysely", () => {
368
395
  adapter: sqliteAdapter,
369
396
  });
370
397
 
371
- const results = await generateMigrationsOrSchema([fragnoDb]);
398
+ const results = await generateSchemaArtifacts([fragnoDb]);
372
399
 
373
400
  expect(results).toHaveLength(2);
374
401
  // Check that SQLite pragma is included
@@ -381,6 +408,111 @@ describe("generateMigrationsOrSchema - kysely", () => {
381
408
  });
382
409
  });
383
410
 
411
+ describe("generateSchemaArtifacts - schema outputs", () => {
412
+ it("should generate drizzle schema without requiring a healthy connection", async () => {
413
+ const adapter = new SqlAdapter({
414
+ dialect: {
415
+ createAdapter: () => new PostgresAdapter(),
416
+ createDriver: () => new DummyDriver(),
417
+ createQueryCompiler: () => ({
418
+ compileQuery: () => ({
419
+ sql: "",
420
+ parameters: [],
421
+ }),
422
+ }),
423
+ },
424
+ driverConfig: new NodePostgresDriverConfig(),
425
+ });
426
+
427
+ const testSchema: AnySchema = schema("test", (s) => {
428
+ return s.addTable("users", (t) => {
429
+ return t.addColumn("id", idColumn()).addColumn("name", column("string"));
430
+ });
431
+ });
432
+
433
+ const fragnoDb = new FragnoDatabase({
434
+ namespace: "drizzle-db",
435
+ schema: testSchema,
436
+ adapter,
437
+ });
438
+
439
+ const healthSpy = vi.spyOn(adapter, "isConnectionHealthy").mockResolvedValue(false);
440
+ const [result] = await generateSchemaArtifacts([fragnoDb], { format: "drizzle" });
441
+
442
+ expect(result.path).toBe("fragno-schema.ts");
443
+ expect(result.schema).toContain("schemaVersion");
444
+ expect(healthSpy).not.toHaveBeenCalled();
445
+ });
446
+
447
+ it("should reject from/to versions for prisma output", async () => {
448
+ const adapter = new SqlAdapter({
449
+ dialect: {
450
+ createAdapter: () => new SqliteAdapter(),
451
+ createDriver: () => new DummyDriver(),
452
+ createQueryCompiler: () => ({
453
+ compileQuery: () => ({
454
+ sql: "",
455
+ parameters: [],
456
+ }),
457
+ }),
458
+ },
459
+ driverConfig: new SQLocalDriverConfig(),
460
+ sqliteProfile: "prisma",
461
+ });
462
+
463
+ const testSchema: AnySchema = schema("test", (s) => {
464
+ return s.addTable("events", (t) => {
465
+ return t.addColumn("id", idColumn()).addColumn("createdAt", column("timestamp"));
466
+ });
467
+ });
468
+
469
+ const fragnoDb = new FragnoDatabase({
470
+ namespace: "prisma-db",
471
+ schema: testSchema,
472
+ adapter,
473
+ });
474
+
475
+ await expect(
476
+ generateSchemaArtifacts([fragnoDb], { format: "prisma", fromVersion: 0 }),
477
+ ).rejects.toThrow("--from and --to are only supported when generating SQL migrations.");
478
+ });
479
+
480
+ it("should honor sqlite prisma profile for schema output", async () => {
481
+ const adapter = new SqlAdapter({
482
+ dialect: {
483
+ createAdapter: () => new SqliteAdapter(),
484
+ createDriver: () => new DummyDriver(),
485
+ createQueryCompiler: () => ({
486
+ compileQuery: () => ({
487
+ sql: "",
488
+ parameters: [],
489
+ }),
490
+ }),
491
+ },
492
+ driverConfig: new SQLocalDriverConfig(),
493
+ sqliteProfile: "prisma",
494
+ });
495
+
496
+ const testSchema: AnySchema = schema("test", (s) => {
497
+ return s.addTable("events", (t) => {
498
+ return t.addColumn("id", idColumn()).addColumn("createdAt", column("timestamp"));
499
+ });
500
+ });
501
+
502
+ const fragnoDb = new FragnoDatabase({
503
+ namespace: "prisma-db",
504
+ schema: testSchema,
505
+ adapter,
506
+ });
507
+
508
+ const [result] = await generateSchemaArtifacts([fragnoDb], { format: "prisma" });
509
+
510
+ expect(result.path).toBe("fragno.prisma");
511
+ expect(result.schema).toContain("model Events_prisma_db");
512
+ expect(result.schema).toContain("DateTime");
513
+ });
514
+ });
515
+
384
516
  describe("postProcessMigrationFilenames", () => {
385
517
  const mockDate = new Date("2025-10-24T12:00:00Z");
386
518
 
@@ -400,59 +532,56 @@ describe("postProcessMigrationFilenames", () => {
400
532
 
401
533
  it("should order settings namespace first", () => {
402
534
  const files: GenerationInternalResult[] = [
403
- {
535
+ buildFile({
404
536
  schema: "schema1",
405
- path: "placeholder.sql",
406
537
  namespace: "fragno-db-comment-db",
407
538
  fromVersion: 0,
408
539
  toVersion: 3,
409
- },
410
- {
540
+ }),
541
+ buildFile({
411
542
  schema: "schema2",
412
- path: "placeholder.sql",
413
- namespace: "", // Empty namespace for settings table
543
+ namespace: null,
544
+ namespaceKey: "fragno_db_settings",
545
+ schemaName: "fragno_internal",
546
+ isSettings: true,
414
547
  fromVersion: 0,
415
548
  toVersion: 1,
416
- },
417
- {
549
+ }),
550
+ buildFile({
418
551
  schema: "schema3",
419
- path: "placeholder.sql",
420
552
  namespace: "fragno-db-rating-db",
421
553
  fromVersion: 0,
422
554
  toVersion: 2,
423
- },
555
+ }),
424
556
  ];
425
557
 
426
558
  const result = postProcessMigrationFilenames(files);
427
559
 
428
560
  expect(result).toHaveLength(3);
429
- expect(result[0].namespace).toBe(""); // Empty namespace for settings table
561
+ expect(result[0].namespace).toBeNull();
430
562
  expect(result[0].path).toBe("20251024_001_f000_t001_fragno_db_settings.sql");
431
563
  });
432
564
 
433
565
  it("should sort non-settings namespaces alphabetically", () => {
434
566
  const files: GenerationInternalResult[] = [
435
- {
567
+ buildFile({
436
568
  schema: "schema1",
437
- path: "placeholder.sql",
438
569
  namespace: "zebra-db",
439
570
  fromVersion: 0,
440
571
  toVersion: 1,
441
- },
442
- {
572
+ }),
573
+ buildFile({
443
574
  schema: "schema2",
444
- path: "placeholder.sql",
445
575
  namespace: "apple-db",
446
576
  fromVersion: 0,
447
577
  toVersion: 1,
448
- },
449
- {
578
+ }),
579
+ buildFile({
450
580
  schema: "schema3",
451
- path: "placeholder.sql",
452
581
  namespace: "mango-db",
453
582
  fromVersion: 0,
454
583
  toVersion: 1,
455
- },
584
+ }),
456
585
  ];
457
586
 
458
587
  const result = postProcessMigrationFilenames(files);
@@ -465,20 +594,21 @@ describe("postProcessMigrationFilenames", () => {
465
594
 
466
595
  it("should format filename with correct ordering and version numbers", () => {
467
596
  const files: GenerationInternalResult[] = [
468
- {
597
+ buildFile({
469
598
  schema: "CREATE TABLE users;",
470
- path: "placeholder.sql",
471
- namespace: "", // Empty namespace for settings table
599
+ namespace: null,
600
+ namespaceKey: "fragno_db_settings",
601
+ schemaName: "fragno_internal",
602
+ isSettings: true,
472
603
  fromVersion: 0,
473
604
  toVersion: 5,
474
- },
475
- {
605
+ }),
606
+ buildFile({
476
607
  schema: "CREATE TABLE comments;",
477
- path: "placeholder.sql",
478
608
  namespace: "comment-db",
479
609
  fromVersion: 5,
480
610
  toVersion: 10,
481
- },
611
+ }),
482
612
  ];
483
613
 
484
614
  const result = postProcessMigrationFilenames(files);
@@ -489,13 +619,12 @@ describe("postProcessMigrationFilenames", () => {
489
619
 
490
620
  it("should pad numbers to 3 digits", () => {
491
621
  const files: GenerationInternalResult[] = [
492
- {
622
+ buildFile({
493
623
  schema: "schema",
494
- path: "placeholder.sql",
495
624
  namespace: "test-db",
496
625
  fromVersion: 99,
497
626
  toVersion: 999,
498
- },
627
+ }),
499
628
  ];
500
629
 
501
630
  const result = postProcessMigrationFilenames(files);
@@ -505,13 +634,12 @@ describe("postProcessMigrationFilenames", () => {
505
634
 
506
635
  it("should sanitize namespace with invalid characters", () => {
507
636
  const files: GenerationInternalResult[] = [
508
- {
637
+ buildFile({
509
638
  schema: "schema",
510
- path: "placeholder.sql",
511
639
  namespace: "test@db#special!chars",
512
640
  fromVersion: 0,
513
641
  toVersion: 1,
514
- },
642
+ }),
515
643
  ];
516
644
 
517
645
  const result = postProcessMigrationFilenames(files);
@@ -521,13 +649,12 @@ describe("postProcessMigrationFilenames", () => {
521
649
 
522
650
  it("should preserve schema content", () => {
523
651
  const files: GenerationInternalResult[] = [
524
- {
652
+ buildFile({
525
653
  schema: "CREATE TABLE users (id INT);",
526
- path: "placeholder.sql",
527
654
  namespace: "user-db",
528
655
  fromVersion: 0,
529
656
  toVersion: 1,
530
- },
657
+ }),
531
658
  ];
532
659
 
533
660
  const result = postProcessMigrationFilenames(files);
@@ -537,40 +664,39 @@ describe("postProcessMigrationFilenames", () => {
537
664
 
538
665
  it("should handle multiple files with settings first and others sorted", () => {
539
666
  const files: GenerationInternalResult[] = [
540
- {
667
+ buildFile({
541
668
  schema: "schema1",
542
- path: "placeholder.sql",
543
669
  namespace: "zoo-db",
544
670
  fromVersion: 1,
545
671
  toVersion: 2,
546
- },
547
- {
672
+ }),
673
+ buildFile({
548
674
  schema: "schema2",
549
- path: "placeholder.sql",
550
- namespace: "", // Empty namespace for settings table
675
+ namespace: null,
676
+ namespaceKey: "fragno_db_settings",
677
+ schemaName: "fragno_internal",
678
+ isSettings: true,
551
679
  fromVersion: 0,
552
680
  toVersion: 5,
553
- },
554
- {
681
+ }),
682
+ buildFile({
555
683
  schema: "schema3",
556
- path: "placeholder.sql",
557
684
  namespace: "apple-db",
558
685
  fromVersion: 3,
559
686
  toVersion: 4,
560
- },
561
- {
687
+ }),
688
+ buildFile({
562
689
  schema: "schema4",
563
- path: "placeholder.sql",
564
690
  namespace: "mango-db",
565
691
  fromVersion: 2,
566
692
  toVersion: 3,
567
- },
693
+ }),
568
694
  ];
569
695
 
570
696
  const result = postProcessMigrationFilenames(files);
571
697
 
572
698
  expect(result).toHaveLength(4);
573
- expect(result[0].namespace).toBe(""); // Empty namespace for settings table
699
+ expect(result[0].namespace).toBeNull();
574
700
  expect(result[0].path).toBe("20251024_001_f000_t005_fragno_db_settings.sql");
575
701
  expect(result[1].namespace).toBe("apple-db");
576
702
  expect(result[1].path).toBe("20251024_002_f003_t004_apple-db.sql");
@@ -581,13 +707,14 @@ describe("postProcessMigrationFilenames", () => {
581
707
  });
582
708
 
583
709
  it("should handle ordering numbers beyond 100", () => {
584
- const files: GenerationInternalResult[] = Array.from({ length: 150 }, (_, i) => ({
585
- schema: `schema${i}`,
586
- path: "placeholder.sql",
587
- namespace: `db-${String(i).padStart(3, "0")}`,
588
- fromVersion: 0,
589
- toVersion: 1,
590
- }));
710
+ const files: GenerationInternalResult[] = Array.from({ length: 150 }, (_, i) =>
711
+ buildFile({
712
+ schema: `schema${i}`,
713
+ namespace: `db-${String(i).padStart(3, "0")}`,
714
+ fromVersion: 0,
715
+ toVersion: 1,
716
+ }),
717
+ );
591
718
 
592
719
  const result = postProcessMigrationFilenames(files);
593
720
 
@@ -598,13 +725,12 @@ describe("postProcessMigrationFilenames", () => {
598
725
 
599
726
  it("should preserve hyphens in namespace", () => {
600
727
  const files: GenerationInternalResult[] = [
601
- {
728
+ buildFile({
602
729
  schema: "schema",
603
- path: "placeholder.sql",
604
730
  namespace: "my-awesome-db-fragment",
605
731
  fromVersion: 0,
606
732
  toVersion: 1,
607
- },
733
+ }),
608
734
  ];
609
735
 
610
736
  const result = postProcessMigrationFilenames(files);
@@ -614,13 +740,12 @@ describe("postProcessMigrationFilenames", () => {
614
740
 
615
741
  it("should use current date in YYYYMMDD format", () => {
616
742
  const files: GenerationInternalResult[] = [
617
- {
743
+ buildFile({
618
744
  schema: "schema",
619
- path: "placeholder.sql",
620
745
  namespace: "test-db",
621
746
  fromVersion: 0,
622
747
  toVersion: 1,
623
- },
748
+ }),
624
749
  ];
625
750
 
626
751
  const result = postProcessMigrationFilenames(files);