@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
@@ -1,10 +1,10 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { column, idColumn, referenceColumn, schema } from "../../schema/create";
3
- import { generateSchema } from "./generate";
4
- import { internalSchema } from "../../fragments/internal-fragment";
2
+ import { column, idColumn, referenceColumn, schema } from "../schema/create";
3
+ import { generateDrizzleSchema } from "./drizzle";
4
+ import { internalSchema } from "../fragments/internal-fragment";
5
5
 
6
- describe("generateSchema", () => {
7
- const testSchema = schema((s) => {
6
+ describe("generateDrizzleSchema", () => {
7
+ const testSchema = schema("test", (s) => {
8
8
  return s
9
9
  .addTable("users", (t) => {
10
10
  return t
@@ -34,9 +34,12 @@ describe("generateSchema", () => {
34
34
 
35
35
  describe("postgresql", () => {
36
36
  it("should generate PostgreSQL schema", () => {
37
- const generated = generateSchema([{ namespace: "test", schema: testSchema }], "postgresql");
37
+ const generated = generateDrizzleSchema(
38
+ [{ namespace: "test", schema: testSchema }],
39
+ "postgresql",
40
+ );
38
41
  expect(generated).toMatchInlineSnapshot(`
39
- "import { pgTable, varchar, text, integer, bigserial, uniqueIndex, index, bigint, foreignKey } from "drizzle-orm/pg-core"
42
+ "import { pgSchema, varchar, text, integer, bigserial, uniqueIndex, index, bigint, foreignKey } from "drizzle-orm/pg-core"
40
43
  import { createId } from "@fragno-dev/db/id"
41
44
  import { relations } from "drizzle-orm"
42
45
 
@@ -44,20 +47,22 @@ describe("generateSchema", () => {
44
47
  // Fragment: test
45
48
  // ============================================================================
46
49
 
47
- export const users_test = pgTable("users_test", {
48
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
50
+ const schema_test = pgSchema("test");
51
+
52
+ export const users_test = schema_test.table("users", {
53
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
49
54
  name: text("name").notNull(),
50
55
  email: text("email").notNull(),
51
56
  age: integer("age"),
52
57
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
53
58
  _version: integer("_version").notNull().default(0)
54
59
  }, (table) => [
55
- uniqueIndex("idx_email_test").on(table.email),
56
- index("idx_name_test").on(table.name)
60
+ uniqueIndex("idx_email").on(table.email),
61
+ index("idx_name").on(table.name)
57
62
  ])
58
63
 
59
- export const posts_test = pgTable("posts_test", {
60
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
64
+ export const posts_test = schema_test.table("posts", {
65
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
61
66
  title: text("title").notNull(),
62
67
  content: text("content").notNull(),
63
68
  userId: bigint("userId", { mode: "number" }).notNull(),
@@ -68,10 +73,10 @@ describe("generateSchema", () => {
68
73
  foreignKey({
69
74
  columns: [table.userId],
70
75
  foreignColumns: [users_test._internalId],
71
- name: "fk_posts_users_author_test"
76
+ name: "fk_posts_users_author"
72
77
  }),
73
- index("idx_user_test").on(table.userId),
74
- index("idx_title_test").on(table.title)
78
+ index("idx_user").on(table.userId),
79
+ index("idx_title").on(table.title)
75
80
  ])
76
81
 
77
82
  export const users_testRelations = relations(users_test, ({ many }) => ({
@@ -105,7 +110,7 @@ describe("generateSchema", () => {
105
110
 
106
111
  describe("mysql", () => {
107
112
  it("should generate MySQL schema", () => {
108
- const generated = generateSchema([{ namespace: "test", schema: testSchema }], "mysql");
113
+ const generated = generateDrizzleSchema([{ namespace: "test", schema: testSchema }], "mysql");
109
114
  expect(generated).toMatchInlineSnapshot(`
110
115
  "import { mysqlTable, varchar, text, int, bigint, uniqueIndex, index, foreignKey } from "drizzle-orm/mysql-core"
111
116
  import { createId } from "@fragno-dev/db/id"
@@ -116,19 +121,19 @@ describe("generateSchema", () => {
116
121
  // ============================================================================
117
122
 
118
123
  export const users_test = mysqlTable("users_test", {
119
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
124
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
120
125
  name: text("name").notNull(),
121
126
  email: text("email").notNull(),
122
127
  age: int("age"),
123
128
  _internalId: bigint("_internalId", { mode: "number" }).primaryKey().autoincrement().notNull(),
124
129
  _version: int("_version").notNull().default(0)
125
130
  }, (table) => [
126
- uniqueIndex("idx_email_test").on(table.email),
127
- index("idx_name_test").on(table.name)
131
+ uniqueIndex("uidx_users_idx_email_test_3d974845").on(table.email),
132
+ index("idx_users_idx_name_test_7f36c497").on(table.name)
128
133
  ])
129
134
 
130
135
  export const posts_test = mysqlTable("posts_test", {
131
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
136
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
132
137
  title: text("title").notNull(),
133
138
  content: text("content").notNull(),
134
139
  userId: bigint("userId", { mode: "number" }).notNull(),
@@ -139,10 +144,10 @@ describe("generateSchema", () => {
139
144
  foreignKey({
140
145
  columns: [table.userId],
141
146
  foreignColumns: [users_test._internalId],
142
- name: "fk_posts_users_author_test"
147
+ name: "fk_posts_users_author_test_8d48035c"
143
148
  }),
144
- index("idx_user_test").on(table.userId),
145
- index("idx_title_test").on(table.title)
149
+ index("idx_posts_idx_user_test_4a5c5c19").on(table.userId),
150
+ index("idx_posts_idx_title_test_00e97ff4").on(table.title)
146
151
  ])
147
152
 
148
153
  export const users_testRelations = relations(users_test, ({ many }) => ({
@@ -176,7 +181,10 @@ describe("generateSchema", () => {
176
181
 
177
182
  describe("sqlite", () => {
178
183
  it("should generate SQLite schema", () => {
179
- const generated = generateSchema([{ namespace: "test", schema: testSchema }], "sqlite");
184
+ const generated = generateDrizzleSchema(
185
+ [{ namespace: "test", schema: testSchema }],
186
+ "sqlite",
187
+ );
180
188
  expect(generated).toMatchInlineSnapshot(`
181
189
  "import { sqliteTable, text, integer, uniqueIndex, index, foreignKey } from "drizzle-orm/sqlite-core"
182
190
  import { createId } from "@fragno-dev/db/id"
@@ -187,19 +195,20 @@ describe("generateSchema", () => {
187
195
  // ============================================================================
188
196
 
189
197
  export const users_test = sqliteTable("users_test", {
190
- id: text("id").notNull().$defaultFn(() => createId()),
198
+ id: text("id").notNull().unique().$defaultFn(() => createId()),
191
199
  name: text("name").notNull(),
192
200
  email: text("email").notNull(),
193
201
  age: integer("age"),
194
202
  _internalId: integer("_internalId").primaryKey({ autoIncrement: true }).notNull(),
195
203
  _version: integer("_version").notNull().default(0)
196
204
  }, (table) => [
197
- uniqueIndex("idx_email_test").on(table.email),
198
- index("idx_name_test").on(table.name)
205
+ uniqueIndex("uidx_users_idx_email_test_3d974845").on(table.email),
206
+ index("idx_users_idx_name_test_7f36c497").on(table.name),
207
+ uniqueIndex("uidx_users_idx_users_external_id_test_8eaf053f").on(table.id)
199
208
  ])
200
209
 
201
210
  export const posts_test = sqliteTable("posts_test", {
202
- id: text("id").notNull().$defaultFn(() => createId()),
211
+ id: text("id").notNull().unique().$defaultFn(() => createId()),
203
212
  title: text("title").notNull(),
204
213
  content: text("content").notNull(),
205
214
  userId: integer("userId").notNull(),
@@ -210,10 +219,11 @@ describe("generateSchema", () => {
210
219
  foreignKey({
211
220
  columns: [table.userId],
212
221
  foreignColumns: [users_test._internalId],
213
- name: "fk_posts_users_author_test"
222
+ name: "fk_posts_users_author_test_8d48035c"
214
223
  }),
215
- index("idx_user_test").on(table.userId),
216
- index("idx_title_test").on(table.title)
224
+ index("idx_posts_idx_user_test_4a5c5c19").on(table.userId),
225
+ index("idx_posts_idx_title_test_00e97ff4").on(table.title),
226
+ uniqueIndex("uidx_posts_idx_posts_external_id_test_80487638").on(table.id)
217
227
  ])
218
228
 
219
229
  export const users_testRelations = relations(users_test, ({ many }) => ({
@@ -247,7 +257,7 @@ describe("generateSchema", () => {
247
257
 
248
258
  describe("default values", () => {
249
259
  it("should handle runtime default values", () => {
250
- const timestampSchema = schema((s) => {
260
+ const timestampSchema = schema("timestamp", (s) => {
251
261
  return s.addTable("events", (t) => {
252
262
  return t.addColumn("id", idColumn()).addColumn(
253
263
  "createdAt",
@@ -256,20 +266,22 @@ describe("generateSchema", () => {
256
266
  });
257
267
  });
258
268
 
259
- const generated = generateSchema(
269
+ const generated = generateDrizzleSchema(
260
270
  [{ namespace: "test", schema: timestampSchema }],
261
271
  "postgresql",
262
272
  );
263
273
  expect(generated).toMatchInlineSnapshot(`
264
- "import { pgTable, varchar, timestamp, bigserial, integer } from "drizzle-orm/pg-core"
274
+ "import { pgSchema, varchar, timestamp, bigserial, integer } from "drizzle-orm/pg-core"
265
275
  import { createId } from "@fragno-dev/db/id"
266
276
 
267
277
  // ============================================================================
268
278
  // Fragment: test
269
279
  // ============================================================================
270
280
 
271
- export const events_test = pgTable("events_test", {
272
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
281
+ const schema_test = pgSchema("test");
282
+
283
+ export const events_test = schema_test.table("events", {
284
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
273
285
  createdAt: timestamp("createdAt").notNull().$defaultFn(() => new Date()),
274
286
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
275
287
  _version: integer("_version").notNull().default(0)
@@ -284,7 +296,7 @@ describe("generateSchema", () => {
284
296
  });
285
297
 
286
298
  it("should handle database-level default values", () => {
287
- const timestampSchema = schema((s) => {
299
+ const timestampSchema = schema("timestamp", (s) => {
288
300
  return s.addTable("events", (t) => {
289
301
  return t.addColumn("id", idColumn()).addColumn(
290
302
  "createdAt",
@@ -293,20 +305,22 @@ describe("generateSchema", () => {
293
305
  });
294
306
  });
295
307
 
296
- const generated = generateSchema(
308
+ const generated = generateDrizzleSchema(
297
309
  [{ namespace: "test", schema: timestampSchema }],
298
310
  "postgresql",
299
311
  );
300
312
  expect(generated).toMatchInlineSnapshot(`
301
- "import { pgTable, varchar, timestamp, bigserial, integer } from "drizzle-orm/pg-core"
313
+ "import { pgSchema, varchar, timestamp, bigserial, integer } from "drizzle-orm/pg-core"
302
314
  import { createId } from "@fragno-dev/db/id"
303
315
 
304
316
  // ============================================================================
305
317
  // Fragment: test
306
318
  // ============================================================================
307
319
 
308
- export const events_test = pgTable("events_test", {
309
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
320
+ const schema_test = pgSchema("test");
321
+
322
+ export const events_test = schema_test.table("events", {
323
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
310
324
  createdAt: timestamp("createdAt").notNull().defaultNow(),
311
325
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
312
326
  _version: integer("_version").notNull().default(0)
@@ -323,15 +337,18 @@ describe("generateSchema", () => {
323
337
 
324
338
  describe("binary columns", () => {
325
339
  it("should generate custom type for binary columns", () => {
326
- const binarySchema = schema((s) => {
340
+ const binarySchema = schema("binary", (s) => {
327
341
  return s.addTable("files", (t) => {
328
342
  return t.addColumn("id", idColumn()).addColumn("data", column("binary"));
329
343
  });
330
344
  });
331
345
 
332
- const generated = generateSchema([{ namespace: "test", schema: binarySchema }], "postgresql");
346
+ const generated = generateDrizzleSchema(
347
+ [{ namespace: "test", schema: binarySchema }],
348
+ "postgresql",
349
+ );
333
350
  expect(generated).toMatchInlineSnapshot(`
334
- "import { pgTable, varchar, customType, bigserial, integer } from "drizzle-orm/pg-core"
351
+ "import { pgSchema, varchar, customType, bigserial, integer } from "drizzle-orm/pg-core"
335
352
  import { createId } from "@fragno-dev/db/id"
336
353
  const customBinary = customType<
337
354
  {
@@ -354,8 +371,10 @@ describe("generateSchema", () => {
354
371
  // Fragment: test
355
372
  // ============================================================================
356
373
 
357
- export const files_test = pgTable("files_test", {
358
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
374
+ const schema_test = pgSchema("test");
375
+
376
+ export const files_test = schema_test.table("files", {
377
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
359
378
  data: customBinary("data").notNull(),
360
379
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
361
380
  _version: integer("_version").notNull().default(0)
@@ -371,7 +390,7 @@ describe("generateSchema", () => {
371
390
  });
372
391
 
373
392
  describe("many relations", () => {
374
- const oneToManySchema = schema((s) => {
393
+ const oneToManySchema = schema("onetomany", (s) => {
375
394
  return s
376
395
  .addTable("users", (t) => {
377
396
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
@@ -396,12 +415,12 @@ describe("generateSchema", () => {
396
415
  });
397
416
 
398
417
  it("should generate PostgreSQL schema with many relations", () => {
399
- const generated = generateSchema(
418
+ const generated = generateDrizzleSchema(
400
419
  [{ namespace: "test", schema: oneToManySchema }],
401
420
  "postgresql",
402
421
  );
403
422
  expect(generated).toMatchInlineSnapshot(`
404
- "import { pgTable, varchar, text, bigserial, integer, bigint, foreignKey, index } from "drizzle-orm/pg-core"
423
+ "import { pgSchema, varchar, text, bigserial, integer, bigint, foreignKey, index } from "drizzle-orm/pg-core"
405
424
  import { createId } from "@fragno-dev/db/id"
406
425
  import { relations } from "drizzle-orm"
407
426
 
@@ -409,15 +428,17 @@ describe("generateSchema", () => {
409
428
  // Fragment: test
410
429
  // ============================================================================
411
430
 
412
- export const users_test = pgTable("users_test", {
413
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
431
+ const schema_test = pgSchema("test");
432
+
433
+ export const users_test = schema_test.table("users", {
434
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
414
435
  name: text("name").notNull(),
415
436
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
416
437
  _version: integer("_version").notNull().default(0)
417
438
  })
418
439
 
419
- export const posts_test = pgTable("posts_test", {
420
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
440
+ export const posts_test = schema_test.table("posts", {
441
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
421
442
  title: text("title").notNull(),
422
443
  userId: bigint("userId", { mode: "number" }).notNull(),
423
444
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
@@ -426,9 +447,9 @@ describe("generateSchema", () => {
426
447
  foreignKey({
427
448
  columns: [table.userId],
428
449
  foreignColumns: [users_test._internalId],
429
- name: "fk_posts_users_author_test"
450
+ name: "fk_posts_users_author"
430
451
  }),
431
- index("idx_user_test").on(table.userId)
452
+ index("idx_user").on(table.userId)
432
453
  ])
433
454
 
434
455
  export const users_testRelations = relations(users_test, ({ many }) => ({
@@ -463,7 +484,10 @@ describe("generateSchema", () => {
463
484
  });
464
485
 
465
486
  it("should generate MySQL schema with many relations", () => {
466
- const generated = generateSchema([{ namespace: "test", schema: oneToManySchema }], "mysql");
487
+ const generated = generateDrizzleSchema(
488
+ [{ namespace: "test", schema: oneToManySchema }],
489
+ "mysql",
490
+ );
467
491
  expect(generated).toMatchInlineSnapshot(`
468
492
  "import { mysqlTable, varchar, text, bigint, int, foreignKey, index } from "drizzle-orm/mysql-core"
469
493
  import { createId } from "@fragno-dev/db/id"
@@ -474,14 +498,14 @@ describe("generateSchema", () => {
474
498
  // ============================================================================
475
499
 
476
500
  export const users_test = mysqlTable("users_test", {
477
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
501
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
478
502
  name: text("name").notNull(),
479
503
  _internalId: bigint("_internalId", { mode: "number" }).primaryKey().autoincrement().notNull(),
480
504
  _version: int("_version").notNull().default(0)
481
505
  })
482
506
 
483
507
  export const posts_test = mysqlTable("posts_test", {
484
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
508
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
485
509
  title: text("title").notNull(),
486
510
  userId: bigint("userId", { mode: "number" }).notNull(),
487
511
  _internalId: bigint("_internalId", { mode: "number" }).primaryKey().autoincrement().notNull(),
@@ -490,9 +514,9 @@ describe("generateSchema", () => {
490
514
  foreignKey({
491
515
  columns: [table.userId],
492
516
  foreignColumns: [users_test._internalId],
493
- name: "fk_posts_users_author_test"
517
+ name: "fk_posts_users_author_test_8d48035c"
494
518
  }),
495
- index("idx_user_test").on(table.userId)
519
+ index("idx_posts_idx_user_test_4a5c5c19").on(table.userId)
496
520
  ])
497
521
 
498
522
  export const users_testRelations = relations(users_test, ({ many }) => ({
@@ -527,9 +551,12 @@ describe("generateSchema", () => {
527
551
  });
528
552
 
529
553
  it("should generate SQLite schema with many relations", () => {
530
- const generated = generateSchema([{ namespace: "test", schema: oneToManySchema }], "sqlite");
554
+ const generated = generateDrizzleSchema(
555
+ [{ namespace: "test", schema: oneToManySchema }],
556
+ "sqlite",
557
+ );
531
558
  expect(generated).toMatchInlineSnapshot(`
532
- "import { sqliteTable, text, integer, foreignKey, index } from "drizzle-orm/sqlite-core"
559
+ "import { sqliteTable, text, integer, uniqueIndex, foreignKey, index } from "drizzle-orm/sqlite-core"
533
560
  import { createId } from "@fragno-dev/db/id"
534
561
  import { relations } from "drizzle-orm"
535
562
 
@@ -538,14 +565,16 @@ describe("generateSchema", () => {
538
565
  // ============================================================================
539
566
 
540
567
  export const users_test = sqliteTable("users_test", {
541
- id: text("id").notNull().$defaultFn(() => createId()),
568
+ id: text("id").notNull().unique().$defaultFn(() => createId()),
542
569
  name: text("name").notNull(),
543
570
  _internalId: integer("_internalId").primaryKey({ autoIncrement: true }).notNull(),
544
571
  _version: integer("_version").notNull().default(0)
545
- })
572
+ }, (table) => [
573
+ uniqueIndex("uidx_users_idx_users_external_id_test_8eaf053f").on(table.id)
574
+ ])
546
575
 
547
576
  export const posts_test = sqliteTable("posts_test", {
548
- id: text("id").notNull().$defaultFn(() => createId()),
577
+ id: text("id").notNull().unique().$defaultFn(() => createId()),
549
578
  title: text("title").notNull(),
550
579
  userId: integer("userId").notNull(),
551
580
  _internalId: integer("_internalId").primaryKey({ autoIncrement: true }).notNull(),
@@ -554,9 +583,10 @@ describe("generateSchema", () => {
554
583
  foreignKey({
555
584
  columns: [table.userId],
556
585
  foreignColumns: [users_test._internalId],
557
- name: "fk_posts_users_author_test"
586
+ name: "fk_posts_users_author_test_8d48035c"
558
587
  }),
559
- index("idx_user_test").on(table.userId)
588
+ index("idx_posts_idx_user_test_4a5c5c19").on(table.userId),
589
+ uniqueIndex("uidx_posts_idx_posts_external_id_test_80487638").on(table.id)
560
590
  ])
561
591
 
562
592
  export const users_testRelations = relations(users_test, ({ many }) => ({
@@ -591,7 +621,7 @@ describe("generateSchema", () => {
591
621
  });
592
622
 
593
623
  it("should handle table with only many relations (no foreign keys)", () => {
594
- const manyOnlySchema = schema((s) => {
624
+ const manyOnlySchema = schema("manyonly", (s) => {
595
625
  return s
596
626
  .addTable("categories", (t) => {
597
627
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
@@ -609,14 +639,14 @@ describe("generateSchema", () => {
609
639
  });
610
640
  });
611
641
 
612
- const generated = generateSchema(
642
+ const generated = generateDrizzleSchema(
613
643
  [{ namespace: "test", schema: manyOnlySchema }],
614
644
  "postgresql",
615
645
  );
616
646
 
617
647
  // Categories table should NOT have a constraint callback (no foreign keys, no indexes)
618
648
  const categoriesTableMatch = generated.match(
619
- /export const categories_test = pgTable\("categories_test", \{[^}]+\}\)/,
649
+ /export const categories_test = schema_test\.table\("categories", \{[^}]+\}\)/,
620
650
  );
621
651
  expect(categoriesTableMatch).toBeTruthy();
622
652
 
@@ -629,7 +659,7 @@ describe("generateSchema", () => {
629
659
  // Should have schema export
630
660
  expect(generated).toContain("export const test_schema = {");
631
661
  expect(generated).toMatchInlineSnapshot(`
632
- "import { pgTable, varchar, text, bigserial, integer, bigint } from "drizzle-orm/pg-core"
662
+ "import { pgSchema, varchar, text, bigserial, integer, bigint } from "drizzle-orm/pg-core"
633
663
  import { createId } from "@fragno-dev/db/id"
634
664
  import { relations } from "drizzle-orm"
635
665
 
@@ -637,15 +667,17 @@ describe("generateSchema", () => {
637
667
  // Fragment: test
638
668
  // ============================================================================
639
669
 
640
- export const categories_test = pgTable("categories_test", {
641
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
670
+ const schema_test = pgSchema("test");
671
+
672
+ export const categories_test = schema_test.table("categories", {
673
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
642
674
  name: text("name").notNull(),
643
675
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
644
676
  _version: integer("_version").notNull().default(0)
645
677
  })
646
678
 
647
- export const products_test = pgTable("products_test", {
648
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
679
+ export const products_test = schema_test.table("products", {
680
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
649
681
  name: text("name").notNull(),
650
682
  categoryId: bigint("categoryId", { mode: "number" }).notNull(),
651
683
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
@@ -671,7 +703,7 @@ describe("generateSchema", () => {
671
703
  });
672
704
 
673
705
  it("should handle self-referencing many relations", () => {
674
- const selfManySchema = schema((s) => {
706
+ const selfManySchema = schema("selfmany", (s) => {
675
707
  return s
676
708
  .addTable("category", (t) => {
677
709
  return t
@@ -691,7 +723,7 @@ describe("generateSchema", () => {
691
723
  });
692
724
  });
693
725
 
694
- const generated = generateSchema(
726
+ const generated = generateDrizzleSchema(
695
727
  [{ namespace: "test", schema: selfManySchema }],
696
728
  "postgresql",
697
729
  );
@@ -705,7 +737,7 @@ describe("generateSchema", () => {
705
737
  expect(fkMatches).toHaveLength(1);
706
738
 
707
739
  expect(generated).toMatchInlineSnapshot(`
708
- "import { pgTable, varchar, text, bigint, bigserial, integer, foreignKey } from "drizzle-orm/pg-core"
740
+ "import { pgSchema, varchar, text, bigint, bigserial, integer, foreignKey } from "drizzle-orm/pg-core"
709
741
  import { createId } from "@fragno-dev/db/id"
710
742
  import { relations } from "drizzle-orm"
711
743
 
@@ -713,8 +745,10 @@ describe("generateSchema", () => {
713
745
  // Fragment: test
714
746
  // ============================================================================
715
747
 
716
- export const category_test = pgTable("category_test", {
717
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
748
+ const schema_test = pgSchema("test");
749
+
750
+ export const category_test = schema_test.table("category", {
751
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
718
752
  name: text("name").notNull(),
719
753
  parentId: bigint("parentId", { mode: "number" }),
720
754
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
@@ -723,7 +757,7 @@ describe("generateSchema", () => {
723
757
  foreignKey({
724
758
  columns: [table.parentId],
725
759
  foreignColumns: [table._internalId],
726
- name: "fk_category_category_parent_test"
760
+ name: "fk_category_category_parent"
727
761
  })
728
762
  ])
729
763
 
@@ -753,7 +787,7 @@ describe("generateSchema", () => {
753
787
  });
754
788
 
755
789
  describe("self-referencing foreign keys", () => {
756
- const selfRefSchema = schema((s) => {
790
+ const selfRefSchema = schema("selfref", (s) => {
757
791
  return s
758
792
  .addTable("comment", (t) => {
759
793
  return t
@@ -770,12 +804,12 @@ describe("generateSchema", () => {
770
804
  });
771
805
 
772
806
  it("should generate PostgreSQL self-referencing foreign key using table parameter", () => {
773
- const generated = generateSchema(
807
+ const generated = generateDrizzleSchema(
774
808
  [{ namespace: "test", schema: selfRefSchema }],
775
809
  "postgresql",
776
810
  );
777
811
  expect(generated).toMatchInlineSnapshot(`
778
- "import { pgTable, varchar, text, bigint, bigserial, integer, foreignKey, index } from "drizzle-orm/pg-core"
812
+ "import { pgSchema, varchar, text, bigint, bigserial, integer, foreignKey, index } from "drizzle-orm/pg-core"
779
813
  import { createId } from "@fragno-dev/db/id"
780
814
  import { relations } from "drizzle-orm"
781
815
 
@@ -783,8 +817,10 @@ describe("generateSchema", () => {
783
817
  // Fragment: test
784
818
  // ============================================================================
785
819
 
786
- export const comment_test = pgTable("comment_test", {
787
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
820
+ const schema_test = pgSchema("test");
821
+
822
+ export const comment_test = schema_test.table("comment", {
823
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
788
824
  content: text("content").notNull(),
789
825
  parentId: bigint("parentId", { mode: "number" }),
790
826
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
@@ -793,9 +829,9 @@ describe("generateSchema", () => {
793
829
  foreignKey({
794
830
  columns: [table.parentId],
795
831
  foreignColumns: [table._internalId],
796
- name: "fk_comment_comment_parent_test"
832
+ name: "fk_comment_comment_parent"
797
833
  }),
798
- index("idx_parent_test").on(table.parentId)
834
+ index("idx_parent").on(table.parentId)
799
835
  ])
800
836
 
801
837
  export const comment_testRelations = relations(comment_test, ({ one, many }) => ({
@@ -820,7 +856,10 @@ describe("generateSchema", () => {
820
856
  });
821
857
 
822
858
  it("should generate MySQL self-referencing foreign key using table parameter", () => {
823
- const generated = generateSchema([{ namespace: "test", schema: selfRefSchema }], "mysql");
859
+ const generated = generateDrizzleSchema(
860
+ [{ namespace: "test", schema: selfRefSchema }],
861
+ "mysql",
862
+ );
824
863
  expect(generated).toMatchInlineSnapshot(`
825
864
  "import { mysqlTable, varchar, text, bigint, int, foreignKey, index } from "drizzle-orm/mysql-core"
826
865
  import { createId } from "@fragno-dev/db/id"
@@ -831,7 +870,7 @@ describe("generateSchema", () => {
831
870
  // ============================================================================
832
871
 
833
872
  export const comment_test = mysqlTable("comment_test", {
834
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
873
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
835
874
  content: text("content").notNull(),
836
875
  parentId: bigint("parentId", { mode: "number" }),
837
876
  _internalId: bigint("_internalId", { mode: "number" }).primaryKey().autoincrement().notNull(),
@@ -840,9 +879,9 @@ describe("generateSchema", () => {
840
879
  foreignKey({
841
880
  columns: [table.parentId],
842
881
  foreignColumns: [table._internalId],
843
- name: "fk_comment_comment_parent_test"
882
+ name: "fk_comment_comment_parent_test_af0d05a4"
844
883
  }),
845
- index("idx_parent_test").on(table.parentId)
884
+ index("idx_comment_idx_parent_test_3c264dbc").on(table.parentId)
846
885
  ])
847
886
 
848
887
  export const comment_testRelations = relations(comment_test, ({ one, many }) => ({
@@ -867,9 +906,12 @@ describe("generateSchema", () => {
867
906
  });
868
907
 
869
908
  it("should generate SQLite self-referencing foreign key using table parameter", () => {
870
- const generated = generateSchema([{ namespace: "test", schema: selfRefSchema }], "sqlite");
909
+ const generated = generateDrizzleSchema(
910
+ [{ namespace: "test", schema: selfRefSchema }],
911
+ "sqlite",
912
+ );
871
913
  expect(generated).toMatchInlineSnapshot(`
872
- "import { sqliteTable, text, integer, foreignKey, index } from "drizzle-orm/sqlite-core"
914
+ "import { sqliteTable, text, integer, foreignKey, index, uniqueIndex } from "drizzle-orm/sqlite-core"
873
915
  import { createId } from "@fragno-dev/db/id"
874
916
  import { relations } from "drizzle-orm"
875
917
 
@@ -878,7 +920,7 @@ describe("generateSchema", () => {
878
920
  // ============================================================================
879
921
 
880
922
  export const comment_test = sqliteTable("comment_test", {
881
- id: text("id").notNull().$defaultFn(() => createId()),
923
+ id: text("id").notNull().unique().$defaultFn(() => createId()),
882
924
  content: text("content").notNull(),
883
925
  parentId: integer("parentId"),
884
926
  _internalId: integer("_internalId").primaryKey({ autoIncrement: true }).notNull(),
@@ -887,9 +929,10 @@ describe("generateSchema", () => {
887
929
  foreignKey({
888
930
  columns: [table.parentId],
889
931
  foreignColumns: [table._internalId],
890
- name: "fk_comment_comment_parent_test"
932
+ name: "fk_comment_comment_parent_test_af0d05a4"
891
933
  }),
892
- index("idx_parent_test").on(table.parentId)
934
+ index("idx_comment_idx_parent_test_3c264dbc").on(table.parentId),
935
+ uniqueIndex("uidx_comment_idx_comment_external_id_test_6a1c2b8f").on(table.id)
893
936
  ])
894
937
 
895
938
  export const comment_testRelations = relations(comment_test, ({ one, many }) => ({
@@ -915,8 +958,8 @@ describe("generateSchema", () => {
915
958
  });
916
959
 
917
960
  describe("namespace sanitization", () => {
918
- it("should sanitize namespace with hyphens for Drizzle compatibility", () => {
919
- const generated = generateSchema(
961
+ it("should sanitize exports while preserving physical table names", () => {
962
+ const generated = generateDrizzleSchema(
920
963
  [{ namespace: "auth-db", schema: testSchema }],
921
964
  "postgresql",
922
965
  );
@@ -925,12 +968,13 @@ describe("generateSchema", () => {
925
968
  expect(generated).toContain("export const users_auth_db =");
926
969
  expect(generated).toContain("export const posts_auth_db =");
927
970
 
928
- // Physical table names must also be sanitized for Drizzle's relational query system
929
- expect(generated).toContain('pgTable("users_auth_db"');
930
- expect(generated).toContain('pgTable("posts_auth_db"');
971
+ // Physical table names use logical names with schema scoping
972
+ expect(generated).toContain('const schema_auth_db = pgSchema("auth-db");');
973
+ expect(generated).toContain('schema_auth_db.table("users"');
974
+ expect(generated).toContain('schema_auth_db.table("posts"');
931
975
 
932
- // Foreign key name should use sanitized namespace
933
- expect(generated).toContain('name: "fk_posts_users_author_auth_db"');
976
+ // Foreign key name should use the original namespace with hashed naming
977
+ expect(generated).toMatch(/name: "fk_posts_users_author"/);
934
978
 
935
979
  // Relations should reference sanitized table names
936
980
  expect(generated).toContain("foreignColumns: [users_auth_db._internalId]");
@@ -950,7 +994,10 @@ describe("generateSchema", () => {
950
994
  });
951
995
 
952
996
  it("should generate inverse relations for namespaced tables", () => {
953
- const generated = generateSchema([{ namespace: "my-app", schema: testSchema }], "postgresql");
997
+ const generated = generateDrizzleSchema(
998
+ [{ namespace: "my-app", schema: testSchema }],
999
+ "postgresql",
1000
+ );
954
1001
 
955
1002
  // User should have inverse "many" relation to posts
956
1003
  expect(generated).toMatch(
@@ -963,8 +1010,8 @@ describe("generateSchema", () => {
963
1010
  expect(generated).toContain("posts_my_appRelations: posts_my_appRelations");
964
1011
  });
965
1012
 
966
- it("should sanitize namespace with special characters in foreign key references", () => {
967
- const generated = generateSchema(
1013
+ it("should sanitize exports with special characters in foreign key references", () => {
1014
+ const generated = generateDrizzleSchema(
968
1015
  [{ namespace: "my-fragment-v2", schema: testSchema }],
969
1016
  "postgresql",
970
1017
  );
@@ -981,12 +1028,13 @@ describe("generateSchema", () => {
981
1028
  expect(generated).toContain("fields: [posts_my_fragment_v2.userId]");
982
1029
  expect(generated).toContain("references: [users_my_fragment_v2._internalId]");
983
1030
 
984
- // Physical table names must also be sanitized for Drizzle's relational query system
985
- expect(generated).toContain('pgTable("users_my_fragment_v2"');
986
- expect(generated).toContain('pgTable("posts_my_fragment_v2"');
1031
+ // Physical table names use logical names with schema scoping
1032
+ expect(generated).toContain('const schema_my_fragment_v2 = pgSchema("my-fragment-v2");');
1033
+ expect(generated).toContain('schema_my_fragment_v2.table("users"');
1034
+ expect(generated).toContain('schema_my_fragment_v2.table("posts"');
987
1035
 
988
1036
  expect(generated).toMatchInlineSnapshot(`
989
- "import { pgTable, varchar, text, integer, bigserial, uniqueIndex, index, bigint, foreignKey } from "drizzle-orm/pg-core"
1037
+ "import { pgSchema, varchar, text, integer, bigserial, uniqueIndex, index, bigint, foreignKey } from "drizzle-orm/pg-core"
990
1038
  import { createId } from "@fragno-dev/db/id"
991
1039
  import { relations } from "drizzle-orm"
992
1040
 
@@ -994,20 +1042,22 @@ describe("generateSchema", () => {
994
1042
  // Fragment: my-fragment-v2
995
1043
  // ============================================================================
996
1044
 
997
- export const users_my_fragment_v2 = pgTable("users_my_fragment_v2", {
998
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
1045
+ const schema_my_fragment_v2 = pgSchema("my-fragment-v2");
1046
+
1047
+ export const users_my_fragment_v2 = schema_my_fragment_v2.table("users", {
1048
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
999
1049
  name: text("name").notNull(),
1000
1050
  email: text("email").notNull(),
1001
1051
  age: integer("age"),
1002
1052
  _internalId: bigserial("_internalId", { mode: "number" }).primaryKey().notNull(),
1003
1053
  _version: integer("_version").notNull().default(0)
1004
1054
  }, (table) => [
1005
- uniqueIndex("idx_email_my-fragment-v2").on(table.email),
1006
- index("idx_name_my-fragment-v2").on(table.name)
1055
+ uniqueIndex("idx_email").on(table.email),
1056
+ index("idx_name").on(table.name)
1007
1057
  ])
1008
1058
 
1009
- export const posts_my_fragment_v2 = pgTable("posts_my_fragment_v2", {
1010
- id: varchar("id", { length: 30 }).notNull().$defaultFn(() => createId()),
1059
+ export const posts_my_fragment_v2 = schema_my_fragment_v2.table("posts", {
1060
+ id: varchar("id", { length: 30 }).notNull().unique().$defaultFn(() => createId()),
1011
1061
  title: text("title").notNull(),
1012
1062
  content: text("content").notNull(),
1013
1063
  userId: bigint("userId", { mode: "number" }).notNull(),
@@ -1018,10 +1068,10 @@ describe("generateSchema", () => {
1018
1068
  foreignKey({
1019
1069
  columns: [table.userId],
1020
1070
  foreignColumns: [users_my_fragment_v2._internalId],
1021
- name: "fk_posts_users_author_my_fragment_v2"
1071
+ name: "fk_posts_users_author"
1022
1072
  }),
1023
- index("idx_user_my-fragment-v2").on(table.userId),
1024
- index("idx_title_my-fragment-v2").on(table.title)
1073
+ index("idx_user").on(table.userId),
1074
+ index("idx_title").on(table.title)
1025
1075
  ])
1026
1076
 
1027
1077
  export const users_my_fragment_v2Relations = relations(users_my_fragment_v2, ({ many }) => ({
@@ -1056,23 +1106,23 @@ describe("generateSchema", () => {
1056
1106
  describe("schema generation", () => {
1057
1107
  it("should generate settings schema and multiple user fragments", () => {
1058
1108
  // settingsSchema is imported at the top to simulate what happens with linked internal fragments
1059
- const fragment1Schema = schema((s) => {
1109
+ const fragment1Schema = schema("fragment1", (s) => {
1060
1110
  return s.addTable("users", (t) => {
1061
1111
  return t.addColumn("id", idColumn()).addColumn("name", column("string"));
1062
1112
  });
1063
1113
  });
1064
1114
 
1065
- const fragment2Schema = schema((s) => {
1115
+ const fragment2Schema = schema("fragment2", (s) => {
1066
1116
  return s.addTable("posts", (t) => {
1067
1117
  return t.addColumn("id", idColumn()).addColumn("title", column("string"));
1068
1118
  });
1069
1119
  });
1070
1120
 
1071
- // De-duplication happens in generation-engine.ts before calling generateSchema
1072
- // This test verifies generateSchema works correctly with already-deduplicated inputs
1073
- const generated = generateSchema(
1121
+ // De-duplication happens in generation-engine.ts before calling generateDrizzleSchema
1122
+ // This test verifies generateDrizzleSchema works correctly with already-deduplicated inputs
1123
+ const generated = generateDrizzleSchema(
1074
1124
  [
1075
- { namespace: "", schema: internalSchema }, // Internal fragment (namespace: "")
1125
+ { namespace: null, schema: internalSchema }, // Internal fragment (namespace: null)
1076
1126
  { namespace: "fragment1", schema: fragment1Schema },
1077
1127
  { namespace: "fragment2", schema: fragment2Schema },
1078
1128
  ],
@@ -1104,14 +1154,14 @@ describe("generateSchema", () => {
1104
1154
 
1105
1155
  it("should generate schema for single fragment with custom namespace", () => {
1106
1156
  // Test a simple single-schema generation
1107
- const sharedSchema = schema((s) => {
1157
+ const sharedSchema = schema("shared", (s) => {
1108
1158
  return s.addTable("shared_table", (t) => {
1109
1159
  return t.addColumn("id", idColumn()).addColumn("data", column("string"));
1110
1160
  });
1111
1161
  });
1112
1162
 
1113
1163
  // De-duplication happens in generation-engine.ts, so we pass pre-deduplicated input
1114
- const generated = generateSchema(
1164
+ const generated = generateDrizzleSchema(
1115
1165
  [{ namespace: "namespace1", schema: sharedSchema }],
1116
1166
  "postgresql",
1117
1167
  );