@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,6 +1,11 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
1
2
  import { createId } from "../id";
3
+ import type { DbNow } from "../query/db-now";
4
+ import type { Prettify } from "../util/types";
5
+ import { createTableStandardSchemaProps, createTableValidator } from "./validator";
2
6
 
3
7
  export { generateId } from "./generate-id";
8
+ export { FragnoDbValidationError } from "./validator";
4
9
 
5
10
  export type AnySchema = Schema<Record<string, AnyTable>>;
6
11
 
@@ -95,13 +100,13 @@ export class ExplicitRelationInit<
95
100
  TTables extends Record<string, AnyTable>,
96
101
  TTableName extends keyof TTables,
97
102
  > extends RelationInit<TRelationType, TTables, TTableName> {
98
- init(ormName: string): Relation<TRelationType, TTables[TTableName]> {
99
- const id = `${this.referencer.ormName}_${this.referencedTable.ormName}`;
103
+ init(name: string): Relation<TRelationType, TTables[TTableName]> {
104
+ const id = `${this.referencer.name}_${this.referencedTable.name}`;
100
105
 
101
106
  return {
102
107
  id,
103
108
  on: this.on,
104
- name: ormName,
109
+ name,
105
110
  referencer: this.referencer,
106
111
  table: this.referencedTable,
107
112
  type: this.type,
@@ -123,18 +128,57 @@ export interface Relation<
123
128
  on: [string, string][];
124
129
  }
125
130
 
131
+ type PickNullable<T> = {
132
+ [P in keyof T as null extends T[P] ? P : never]: T[P];
133
+ };
134
+
135
+ type PickNotNullable<T> = {
136
+ [P in keyof T as null extends T[P] ? never : P]: T[P];
137
+ };
138
+
139
+ type RawInsertValuesFromColumns<TColumns extends Record<string, AnyColumn>> = {
140
+ [K in keyof TColumns as string extends K ? never : K]: TColumns[K]["$in"];
141
+ };
142
+
143
+ type TableInsertValuesFromColumns<TColumns extends Record<string, AnyColumn>> = Prettify<
144
+ Partial<PickNullable<RawInsertValuesFromColumns<TColumns>>> &
145
+ PickNotNullable<RawInsertValuesFromColumns<TColumns>>
146
+ >;
147
+
148
+ export type TableInsertValues<T extends AnyTable> = TableInsertValuesFromColumns<T["columns"]>;
149
+
150
+ export type TableUnknownKeysMode = "strip" | "strict";
151
+
152
+ export type TableValidationOptions = {
153
+ unknownKeys?: TableUnknownKeysMode;
154
+ };
155
+
126
156
  export interface Table<
127
157
  TColumns extends Record<string, AnyColumn> = Record<string, AnyColumn>,
128
158
  TRelations extends Record<string, AnyRelation> = Record<string, AnyRelation>,
129
159
  TIndexes extends Record<string, Index> = Record<string, Index>,
130
160
  > {
161
+ /**
162
+ * Standard Schema-compatible validator for insert values.
163
+ */
164
+ "~standard": StandardSchemaV1.Props<
165
+ TableInsertValuesFromColumns<TColumns>,
166
+ TableInsertValuesFromColumns<TColumns>
167
+ >;
131
168
  name: string;
132
- ormName: string;
133
169
 
134
170
  columns: TColumns;
135
171
  relations: TRelations;
136
172
  indexes: TIndexes;
137
173
 
174
+ /**
175
+ * Validate insert values at runtime.
176
+ */
177
+ validate: (
178
+ value: unknown,
179
+ options?: TableValidationOptions,
180
+ ) => TableInsertValuesFromColumns<TColumns>;
181
+
138
182
  /**
139
183
  * Get column by name
140
184
  */
@@ -203,7 +247,6 @@ export type TypeMap = {
203
247
  export class Column<TType extends keyof TypeMap, TIn = unknown, TOut = unknown> {
204
248
  type: TType;
205
249
  name: string = "";
206
- ormName: string = "";
207
250
  isNullable: boolean = false;
208
251
  role: "external-id" | "internal-id" | "version" | "reference" | "regular" = "regular";
209
252
  isHidden: boolean = false;
@@ -421,9 +464,13 @@ export class VersionColumn<TIn = unknown, TOut = unknown> extends Column<"intege
421
464
  }
422
465
  }
423
466
 
467
+ type ColumnInput<TType extends keyof TypeMap> =
468
+ | TypeMap[TType]
469
+ | (TType extends "timestamp" | "date" ? DbNow : never);
470
+
424
471
  export function column<TType extends keyof TypeMap>(
425
472
  type: TType,
426
- ): Column<TType, TypeMap[TType], TypeMap[TType]> {
473
+ ): Column<TType, ColumnInput<TType>, TypeMap[TType]> {
427
474
  return new Column(type);
428
475
  }
429
476
 
@@ -579,6 +626,8 @@ export class FragnoReference {
579
626
  }
580
627
  }
581
628
 
629
+ const validationClasses = { FragnoId, FragnoReference };
630
+
582
631
  type RelationType = "one" | "many";
583
632
 
584
633
  export class TableBuilder<
@@ -590,7 +639,6 @@ export class TableBuilder<
590
639
  #columns: TColumns;
591
640
  #relations: TRelations;
592
641
  #indexes: TIndexes;
593
- #ormName: string = "";
594
642
  #columnOrder: string[] = [];
595
643
 
596
644
  constructor(name: string) {
@@ -626,7 +674,7 @@ export class TableBuilder<
626
674
  * Add a column to the table.
627
675
  */
628
676
  addColumn<TColumnName extends string, TColumn extends AnyColumn>(
629
- ormName: TColumnName,
677
+ name: TColumnName,
630
678
  col: TColumn,
631
679
  ): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes>;
632
680
 
@@ -634,28 +682,27 @@ export class TableBuilder<
634
682
  * Add a column to the table with simplified syntax.
635
683
  */
636
684
  addColumn<TColumnName extends string, TType extends keyof TypeMap>(
637
- ormName: TColumnName,
685
+ name: TColumnName,
638
686
  type: TType,
639
687
  ): TableBuilder<
640
- TColumns & Record<TColumnName, Column<TType, TypeMap[TType], TypeMap[TType]>>,
688
+ TColumns & Record<TColumnName, Column<TType, ColumnInput<TType>, TypeMap[TType]>>,
641
689
  TRelations,
642
690
  TIndexes
643
691
  >;
644
692
 
645
693
  addColumn<TColumnName extends string, TColumn extends AnyColumn, TType extends keyof TypeMap>(
646
- ormName: TColumnName,
694
+ name: TColumnName,
647
695
  colOrType: TColumn | TType,
648
696
  ): TableBuilder<TColumns & Record<TColumnName, TColumn>, TRelations, TIndexes> {
649
697
  // Create the column if a type string was provided
650
698
  const col = typeof colOrType === "string" ? column(colOrType) : colOrType;
651
699
 
652
700
  // Set column metadata
653
- col.ormName = ormName;
654
- col.name = ormName;
701
+ col.name = name;
655
702
 
656
703
  // Add column directly to this builder
657
- this.#columns[ormName] = col as unknown as TColumns[TColumnName];
658
- this.#columnOrder.push(ormName);
704
+ this.#columns[name] = col as unknown as TColumns[TColumnName];
705
+ this.#columnOrder.push(name);
659
706
 
660
707
  return this as unknown as TableBuilder<
661
708
  TColumns & Record<TColumnName, TColumn>,
@@ -716,7 +763,6 @@ export class TableBuilder<
716
763
  // Auto-add _internalId and _version columns if not already present
717
764
  if (!this.#columns["_internalId"]) {
718
765
  const col = internalIdColumn();
719
- col.ormName = "_internalId";
720
766
  col.name = "_internalId";
721
767
  // Safe: we're adding system columns to the internal columns object
722
768
  (this.#columns as Record<string, AnyColumn>)["_internalId"] = col;
@@ -724,18 +770,13 @@ export class TableBuilder<
724
770
 
725
771
  if (!this.#columns["_version"]) {
726
772
  const col = versionColumn();
727
- col.ormName = "_version";
728
773
  col.name = "_version";
729
774
  // Safe: we're adding system columns to the internal columns object
730
775
  (this.#columns as Record<string, AnyColumn>)["_version"] = col;
731
776
  }
732
777
 
733
- // Use name as ormName if ormName is not set
734
- const ormName = this.#ormName || this.#name;
735
-
736
- const table: Table<TColumns, TRelations, TIndexes> = {
778
+ const table = {
737
779
  name: this.#name,
738
- ormName,
739
780
  columns: this.#columns,
740
781
  relations: this.#relations,
741
782
  indexes: this.#indexes,
@@ -751,7 +792,10 @@ export class TableBuilder<
751
792
  getVersionColumn: () => {
752
793
  return versionCol!;
753
794
  },
754
- };
795
+ } as Table<TColumns, TRelations, TIndexes>;
796
+
797
+ table["~standard"] = createTableStandardSchemaProps(table, validationClasses);
798
+ table.validate = createTableValidator(table, validationClasses);
755
799
 
756
800
  // Set table reference and find special columns
757
801
  for (const k in this.#columns) {
@@ -787,6 +831,10 @@ export class TableBuilder<
787
831
  }
788
832
 
789
833
  export interface Schema<TTables extends Record<string, AnyTable> = Record<string, AnyTable>> {
834
+ /**
835
+ * @description The name of the schema (required).
836
+ */
837
+ name: string;
790
838
  /**
791
839
  * @description The version of the schema, automatically incremented on each change.
792
840
  */
@@ -851,11 +899,15 @@ type ColumnsToTuple<
851
899
  } & AnyColumn[];
852
900
 
853
901
  export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
902
+ #name: string;
854
903
  #tables: TTables;
855
904
  #version: number = 0;
856
905
  #operations: SchemaOperation[] = [];
906
+ #tableNames: Set<string> = new Set();
907
+ #indexNames: Set<string> = new Set();
857
908
 
858
- constructor(existingSchema?: Schema<TTables>) {
909
+ constructor(name: string, existingSchema?: Schema<TTables>) {
910
+ this.#name = name;
859
911
  if (existingSchema) {
860
912
  this.#tables = existingSchema.tables;
861
913
  this.#version = existingSchema.version;
@@ -863,6 +915,29 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
863
915
  } else {
864
916
  this.#tables = {} as TTables;
865
917
  }
918
+
919
+ for (const table of Object.values(this.#tables)) {
920
+ this.#registerTableName(table.name);
921
+ for (const index of Object.values(table.indexes)) {
922
+ this.#registerIndexName(index.name, table.name);
923
+ }
924
+ }
925
+ }
926
+
927
+ #registerTableName(name: string): void {
928
+ if (this.#tableNames.has(name)) {
929
+ throw new Error(`Duplicate table name "${name}" in schema "${this.#name}".`);
930
+ }
931
+ this.#tableNames.add(name);
932
+ }
933
+
934
+ #registerIndexName(name: string, tableName: string): void {
935
+ if (this.#indexNames.has(name)) {
936
+ throw new Error(
937
+ `Duplicate index name "${name}" in schema "${this.#name}". Index names must be unique across tables (conflict on "${tableName}").`,
938
+ );
939
+ }
940
+ this.#indexNames.add(name);
866
941
  }
867
942
 
868
943
  /**
@@ -871,7 +946,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
871
946
  *
872
947
  * @example
873
948
  * ```ts
874
- * const builder = new SchemaBuilder()
949
+ * const builder = new SchemaBuilder("combined")
875
950
  * .add(userSchema)
876
951
  * .add(postSchema)
877
952
  * .addTable("comments", ...);
@@ -880,10 +955,32 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
880
955
  mergeWithExistingSchema<TNewTables extends Record<string, AnyTable>>(
881
956
  schema: Schema<TNewTables>,
882
957
  ): SchemaBuilder<TTables & TNewTables> {
958
+ for (const table of Object.values(schema.tables)) {
959
+ if (this.#tableNames.has(table.name)) {
960
+ throw new Error(
961
+ `Duplicate table name "${table.name}" in schema "${this.#name}" when merging.`,
962
+ );
963
+ }
964
+ for (const index of Object.values(table.indexes)) {
965
+ if (this.#indexNames.has(index.name)) {
966
+ throw new Error(
967
+ `Duplicate index name "${index.name}" in schema "${this.#name}" when merging (conflict on "${table.name}").`,
968
+ );
969
+ }
970
+ }
971
+ }
972
+
883
973
  this.#tables = { ...this.#tables, ...schema.tables } as TTables & TNewTables;
884
974
  this.#operations = [...this.#operations, ...schema.operations];
885
975
  this.#version += schema.version;
886
976
 
977
+ for (const table of Object.values(schema.tables)) {
978
+ this.#tableNames.add(table.name);
979
+ for (const index of Object.values(table.indexes)) {
980
+ this.#indexNames.add(index.name);
981
+ }
982
+ }
983
+
887
984
  return this as unknown as SchemaBuilder<TTables & TNewTables>;
888
985
  }
889
986
 
@@ -896,7 +993,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
896
993
  TRelations extends Record<string, AnyRelation>,
897
994
  TIndexes extends Record<string, Index> = Record<string, Index>,
898
995
  >(
899
- ormName: TTableName,
996
+ name: TTableName,
900
997
  callback: (
901
998
  builder: TableBuilder<
902
999
  Record<string, AnyColumn>,
@@ -907,10 +1004,22 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
907
1004
  ): SchemaBuilder<TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>> {
908
1005
  this.#version++;
909
1006
 
910
- const tableBuilder = new TableBuilder(ormName);
1007
+ if (this.#tableNames.has(name)) {
1008
+ throw new Error(`Duplicate table name "${name}" in schema "${this.#name}".`);
1009
+ }
1010
+
1011
+ const tableBuilder = new TableBuilder(name);
911
1012
  const result = callback(tableBuilder);
912
1013
  const builtTable = result.build();
913
- builtTable.ormName = ormName;
1014
+ const indexNames = result.getIndexes().map((idx) => idx.name);
1015
+
1016
+ for (const indexName of indexNames) {
1017
+ if (this.#indexNames.has(indexName)) {
1018
+ throw new Error(
1019
+ `Duplicate index name "${indexName}" in schema "${this.#name}". Index names must be unique across tables (conflict on "${name}").`,
1020
+ );
1021
+ }
1022
+ }
914
1023
 
915
1024
  // Collect sub-operations in order
916
1025
  const subOperations: TableSubOperation[] = [];
@@ -947,7 +1056,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
947
1056
  subOperations.push({
948
1057
  type: "add-index",
949
1058
  name: idx.name,
950
- columns: idx.columns.map((c) => c.ormName),
1059
+ columns: idx.columns.map((c) => c.name),
951
1060
  unique: idx.unique,
952
1061
  });
953
1062
  }
@@ -955,13 +1064,17 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
955
1064
  // Add the add-table operation
956
1065
  this.#operations.push({
957
1066
  type: "add-table",
958
- tableName: ormName,
1067
+ tableName: name,
959
1068
  operations: subOperations,
960
1069
  });
961
1070
 
962
1071
  // Update tables map
963
- this.#tables = { ...this.#tables, [ormName]: builtTable } as TTables &
1072
+ this.#tables = { ...this.#tables, [name]: builtTable } as TTables &
964
1073
  Record<TTableName, Table<TColumns, TRelations, TIndexes>>;
1074
+ this.#tableNames.add(name);
1075
+ for (const indexName of indexNames) {
1076
+ this.#indexNames.add(indexName);
1077
+ }
965
1078
 
966
1079
  return this as unknown as SchemaBuilder<
967
1080
  TTables & Record<TTableName, Table<TColumns, TRelations, TIndexes>>
@@ -977,7 +1090,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
977
1090
  * @example
978
1091
  * ```ts
979
1092
  * // One-to-one or many-to-one: post -> user
980
- * schema(s => s
1093
+ * schema("blog", s => s
981
1094
  * .addTable("users", t => t.addColumn("id", idColumn()))
982
1095
  * .addTable("posts", t => t
983
1096
  * .addColumn("id", idColumn())
@@ -1030,6 +1143,10 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1030
1143
  const table = this.#tables[config.from.table];
1031
1144
  const referencedTable = this.#tables[config.to.table];
1032
1145
 
1146
+ if (!referenceName || referenceName.trim().length === 0) {
1147
+ throw new Error(`referenceName is required for addReference on ${config.from.table}`);
1148
+ }
1149
+
1033
1150
  if (!table) {
1034
1151
  throw new Error(`Table ${config.from.table} not found in schema`);
1035
1152
  }
@@ -1054,6 +1171,10 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1054
1171
  throw new Error(`Column ${actualTargetColumnName} not found in table ${config.to.table}`);
1055
1172
  }
1056
1173
 
1174
+ if (table.relations[referenceName]) {
1175
+ throw new Error(`Reference ${referenceName} already exists on table ${config.from.table}`);
1176
+ }
1177
+
1057
1178
  // Verify that reference columns are bigint (matching internal ID type)
1058
1179
  if (column.role === "reference" && column.type !== "bigint") {
1059
1180
  throw new Error(
@@ -1098,7 +1219,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1098
1219
  * @example
1099
1220
  * ```ts
1100
1221
  * // Add a new column to an existing table
1101
- * schema(s => s
1222
+ * schema("blog", s => s
1102
1223
  * .addTable("users", t => t
1103
1224
  * .addColumn("id", idColumn())
1104
1225
  * .addColumn("name", column("string")))
@@ -1168,10 +1289,15 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1168
1289
  // Add only new indexes
1169
1290
  for (const idx of resultBuilder.getIndexes()) {
1170
1291
  if (!existingIndexes.has(idx.name)) {
1292
+ if (this.#indexNames.has(idx.name)) {
1293
+ throw new Error(
1294
+ `Duplicate index name "${idx.name}" in schema "${this.#name}". Index names must be unique across tables (conflict on "${tableName}").`,
1295
+ );
1296
+ }
1171
1297
  subOperations.push({
1172
1298
  type: "add-index",
1173
1299
  name: idx.name,
1174
- columns: idx.columns.map((c) => c.ormName),
1300
+ columns: idx.columns.map((c) => c.name),
1175
1301
  unique: idx.unique,
1176
1302
  });
1177
1303
  }
@@ -1188,6 +1314,11 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1188
1314
 
1189
1315
  // Update table reference in schema
1190
1316
  this.#tables[tableName] = newTable as unknown as TTables[TTableName];
1317
+ for (const idx of resultBuilder.getIndexes()) {
1318
+ if (!existingIndexes.has(idx.name)) {
1319
+ this.#indexNames.add(idx.name);
1320
+ }
1321
+ }
1191
1322
 
1192
1323
  // Set table name for all columns
1193
1324
  for (const col of Object.values(newTable.columns)) {
@@ -1208,6 +1339,7 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1208
1339
  const tables = this.#tables;
1209
1340
 
1210
1341
  const schema: Schema<TTables> = {
1342
+ name: this.#name,
1211
1343
  version,
1212
1344
  tables,
1213
1345
  operations,
@@ -1231,7 +1363,6 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1231
1363
  }
1232
1364
 
1233
1365
  clonedCol.name = col.name;
1234
- clonedCol.ormName = col.ormName;
1235
1366
  clonedCol.isNullable = col.isNullable;
1236
1367
  clonedCol.role = col.role;
1237
1368
  clonedCol.isHidden = col.isHidden;
@@ -1240,20 +1371,28 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1240
1371
  clonedColumns[colName] = clonedCol;
1241
1372
  }
1242
1373
 
1243
- cloneTables[k] = {
1374
+ const clonedTable = {
1244
1375
  ...v,
1245
1376
  columns: clonedColumns,
1246
- };
1377
+ } as AnyTable;
1378
+
1379
+ clonedTable["~standard"] = createTableStandardSchemaProps(clonedTable, validationClasses);
1380
+ clonedTable.validate = createTableValidator(clonedTable, validationClasses);
1381
+
1382
+ cloneTables[k] = clonedTable;
1247
1383
  }
1248
1384
 
1249
- return new SchemaBuilder<TTables>({
1385
+ const clonedSchema: Schema<TTables> = {
1386
+ name: this.#name,
1250
1387
  version,
1251
1388
  tables: cloneTables as TTables,
1252
1389
  operations: [...operations],
1253
1390
  clone: () => {
1254
1391
  throw new Error("Cannot clone during clone");
1255
1392
  },
1256
- }).build();
1393
+ };
1394
+
1395
+ return new SchemaBuilder<TTables>(this.#name, clonedSchema).build();
1257
1396
  },
1258
1397
  };
1259
1398
 
@@ -1272,19 +1411,18 @@ export class SchemaBuilder<TTables extends Record<string, AnyTable> = {}> {
1272
1411
  * Create a new schema with callback pattern.
1273
1412
  */
1274
1413
  export function schema<const TTables extends Record<string, AnyTable> = {}>(
1414
+ name: string,
1275
1415
  callback: (builder: SchemaBuilder<{}>) => SchemaBuilder<TTables>,
1276
1416
  ): Schema<TTables> {
1277
- return callback(new SchemaBuilder()).build();
1417
+ return callback(new SchemaBuilder(name)).build();
1278
1418
  }
1279
1419
 
1280
- export function compileForeignKey(key: ForeignKey, nameType: "sql" | "orm" = "orm") {
1420
+ export function compileForeignKey(key: ForeignKey) {
1281
1421
  return {
1282
1422
  name: key.name,
1283
- table: nameType === "sql" ? key.table.name : key.table.ormName,
1284
- referencedTable: nameType === "sql" ? key.referencedTable.name : key.referencedTable.ormName,
1285
- referencedColumns: key.referencedColumns.map((col) =>
1286
- nameType === "sql" ? col.name : col.ormName,
1287
- ),
1288
- columns: key.columns.map((col) => (nameType === "sql" ? col.name : col.ormName)),
1423
+ table: key.table.name,
1424
+ referencedTable: key.referencedTable.name,
1425
+ referencedColumns: key.referencedColumns.map((col) => col.name),
1426
+ columns: key.columns.map((col) => col.name),
1289
1427
  };
1290
1428
  }
@@ -3,7 +3,7 @@ import { schema, idColumn, FragnoId } from "./create";
3
3
  import { generateId } from "./generate-id";
4
4
 
5
5
  describe("generateId", () => {
6
- const testSchema = schema((s) =>
6
+ const testSchema = schema("test", (s) =>
7
7
  s.addTable("users", (t) =>
8
8
  t.addColumn("id", idColumn()).addColumn("email", "string").addColumn("name", "string"),
9
9
  ),
@@ -34,7 +34,7 @@ describe("generateId", () => {
34
34
  });
35
35
 
36
36
  it("should work with multiple tables", () => {
37
- const multiTableSchema = schema((s) =>
37
+ const multiTableSchema = schema("multitable", (s) =>
38
38
  s
39
39
  .addTable("users", (t) =>
40
40
  t.addColumn("id", idColumn()).addColumn("email", "string").addColumn("name", "string"),
@@ -25,12 +25,12 @@ export function generateId<
25
25
  const idColumn = tableSchema.getIdColumn();
26
26
  const generated = idColumn.generateDefaultValue();
27
27
  if (generated === undefined) {
28
- throw new Error(`ID column ${idColumn.ormName} on table ${tableName} has no default generator`);
28
+ throw new Error(`ID column ${idColumn.name} on table ${tableName} has no default generator`);
29
29
  }
30
30
 
31
31
  if (typeof generated !== "string") {
32
32
  throw new Error(
33
- `ID column ${idColumn.ormName} on table ${tableName} has no default generator that generates a string.`,
33
+ `ID column ${idColumn.name} on table ${tableName} has no default generator that generates a string.`,
34
34
  );
35
35
  }
36
36
 
@@ -131,7 +131,17 @@ describe("serialize", () => {
131
131
  it("should convert string timestamps to Date", () => {
132
132
  const timestampCol = column("timestamp");
133
133
  const time = "2024-01-01 12:30:45.123";
134
- expect(deserialize(time, timestampCol, "postgresql")).toEqual(new Date(time));
134
+ const result = deserialize(time, timestampCol, "postgresql");
135
+ assert.instanceOf(result, Date);
136
+ expect(result.toISOString()).toBe("2024-01-01T12:30:45.123Z");
137
+ });
138
+
139
+ it("should treat timezone-less ISO timestamps as UTC", () => {
140
+ const timestampCol = column("timestamp");
141
+ const time = "2024-01-01T12:30:45.123";
142
+ const result = deserialize(time, timestampCol, "postgresql");
143
+ assert.instanceOf(result, Date);
144
+ expect(result.toISOString()).toBe("2024-01-01T12:30:45.123Z");
135
145
  });
136
146
 
137
147
  it("should convert ISO string timestamps to Date", () => {
@@ -262,7 +272,9 @@ describe("serialize", () => {
262
272
  it("should convert string timestamps to Date", () => {
263
273
  const timestampCol = column("timestamp");
264
274
  const time = "2024-01-01 12:30:45.123";
265
- expect(deserialize(time, timestampCol, "cockroachdb")).toEqual(new Date(time));
275
+ const result = deserialize(time, timestampCol, "cockroachdb");
276
+ assert.instanceOf(result, Date);
277
+ expect(result.toISOString()).toBe("2024-01-01T12:30:45.123Z");
266
278
  });
267
279
 
268
280
  it("should convert date strings to Date", () => {
@@ -1,4 +1,5 @@
1
1
  import type { SupportedDatabase } from "../../adapters/generic-sql/driver-config";
2
+ import type { SQLiteStorageMode } from "../../adapters/generic-sql/sqlite-storage";
2
3
  import { PostgreSQLTypeMapper } from "./dialect/postgres";
3
4
  import { MySQLTypeMapper } from "./dialect/mysql";
4
5
  import { SQLiteTypeMapper } from "./dialect/sqlite";
@@ -10,16 +11,20 @@ import { SQLiteTypeMapper } from "./dialect/sqlite";
10
11
  * (PostgreSQL, MySQL, or SQLite).
11
12
  *
12
13
  * @param database - The database type (sqlite, postgresql, or mysql)
14
+ * @param sqliteStorageMode - Optional SQLite storage mode override
13
15
  * @returns Dialect-specific SQLTypeMapper instance
14
16
  */
15
- export function createSQLTypeMapper(database: SupportedDatabase) {
17
+ export function createSQLTypeMapper(
18
+ database: SupportedDatabase,
19
+ sqliteStorageMode?: SQLiteStorageMode,
20
+ ) {
16
21
  switch (database) {
17
22
  case "postgresql":
18
23
  return new PostgreSQLTypeMapper(database);
19
24
  case "mysql":
20
25
  return new MySQLTypeMapper(database);
21
26
  case "sqlite":
22
- return new SQLiteTypeMapper(database);
27
+ return new SQLiteTypeMapper(database, sqliteStorageMode);
23
28
  default: {
24
29
  const exhaustiveCheck: never = database;
25
30
  throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
@@ -1,5 +1,7 @@
1
1
  import type { AnyColumn } from "../../create";
2
2
  import { SQLTypeMapper, type SQLiteDatabaseType } from "../type-mapping";
3
+ import type { SQLiteStorageMode } from "../../../adapters/generic-sql/sqlite-storage";
4
+ import { sqliteStorageDefault } from "../../../adapters/generic-sql/sqlite-storage";
3
5
 
4
6
  /**
5
7
  * SQLite-specific type mapper.
@@ -11,6 +13,13 @@ import { SQLTypeMapper, type SQLiteDatabaseType } from "../type-mapping";
11
13
  * - REAL for decimals
12
14
  */
13
15
  export class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {
16
+ private readonly sqliteStorageMode: SQLiteStorageMode;
17
+
18
+ constructor(database: "sqlite", sqliteStorageMode?: SQLiteStorageMode) {
19
+ super(database);
20
+ this.sqliteStorageMode = sqliteStorageMode ?? sqliteStorageDefault;
21
+ }
22
+
14
23
  protected getInternalIdType(): SQLiteDatabaseType {
15
24
  // SQLite uses INTEGER for auto-increment (INTEGER PRIMARY KEY)
16
25
  return "integer";
@@ -25,6 +34,9 @@ export class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {
25
34
  if ("role" in column && column.role === "reference") {
26
35
  return "integer";
27
36
  }
37
+ if (this.sqliteStorageMode.bigintStorage === "integer") {
38
+ return "integer";
39
+ }
28
40
  return "blob";
29
41
  }
30
42
 
@@ -50,10 +62,16 @@ export class SQLiteTypeMapper extends SQLTypeMapper<SQLiteDatabaseType> {
50
62
  }
51
63
 
52
64
  protected mapTimestamp(): SQLiteDatabaseType {
65
+ if (this.sqliteStorageMode.timestampStorage === "iso-text") {
66
+ return "text";
67
+ }
53
68
  return "integer";
54
69
  }
55
70
 
56
71
  protected mapDate(): SQLiteDatabaseType {
72
+ if (this.sqliteStorageMode.dateStorage === "iso-text") {
73
+ return "text";
74
+ }
57
75
  return "integer";
58
76
  }
59
77