@fragno-dev/db 0.2.1 → 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 (362) hide show
  1. package/.turbo/turbo-build.log +206 -140
  2. package/CHANGELOG.md +67 -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 +38 -28
  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 +45 -96
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +121 -99
  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 +172 -9
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +193 -74
  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 +47 -4
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +106 -39
  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 +17 -10
  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 +351 -100
  165. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  166. package/dist/query/unit-of-work/execute-unit-of-work.js +440 -267
  167. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  168. package/dist/query/unit-of-work/unit-of-work.d.ts +67 -22
  169. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  170. package/dist/query/unit-of-work/unit-of-work.js +110 -13
  171. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  172. package/dist/query/value-decoding.js +8 -5
  173. package/dist/query/value-decoding.js.map +1 -1
  174. package/dist/query/value-encoding.js +29 -9
  175. package/dist/query/value-encoding.js.map +1 -1
  176. package/dist/schema/create.d.ts +40 -14
  177. package/dist/schema/create.d.ts.map +1 -1
  178. package/dist/schema/create.js +82 -42
  179. package/dist/schema/create.js.map +1 -1
  180. package/dist/schema/generate-id.d.ts +20 -0
  181. package/dist/schema/generate-id.d.ts.map +1 -0
  182. package/dist/schema/generate-id.js +28 -0
  183. package/dist/schema/generate-id.js.map +1 -0
  184. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  185. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  186. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  187. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  188. package/dist/schema/validator.d.ts +10 -0
  189. package/dist/schema/validator.d.ts.map +1 -0
  190. package/dist/schema/validator.js +123 -0
  191. package/dist/schema/validator.js.map +1 -0
  192. package/dist/schema-output/drizzle.d.ts +30 -0
  193. package/dist/schema-output/drizzle.d.ts.map +1 -0
  194. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  195. package/dist/schema-output/drizzle.js.map +1 -0
  196. package/dist/schema-output/prisma.d.ts +17 -0
  197. package/dist/schema-output/prisma.d.ts.map +1 -0
  198. package/dist/schema-output/prisma.js +296 -0
  199. package/dist/schema-output/prisma.js.map +1 -0
  200. package/dist/util/default-database-adapter.js +61 -0
  201. package/dist/util/default-database-adapter.js.map +1 -0
  202. package/dist/with-database.d.ts +1 -1
  203. package/dist/with-database.d.ts.map +1 -1
  204. package/dist/with-database.js +12 -3
  205. package/dist/with-database.js.map +1 -1
  206. package/package.json +43 -28
  207. package/src/adapters/adapters.ts +30 -24
  208. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  209. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  210. package/src/adapters/drizzle/test-utils.ts +12 -8
  211. package/src/adapters/generic-sql/driver-config.ts +38 -0
  212. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  213. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  214. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  215. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  216. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  217. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  218. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  219. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  220. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  221. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  222. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  223. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  224. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  225. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  226. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  227. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  228. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  229. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  230. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  231. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  232. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  233. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  234. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  235. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  236. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  237. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  238. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  239. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  240. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +49 -35
  241. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +48 -32
  242. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  243. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  244. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  245. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  246. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  247. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  248. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  249. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  250. package/src/adapters/in-memory/errors.ts +20 -0
  251. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  252. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  253. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  254. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  255. package/src/adapters/in-memory/index.ts +3 -0
  256. package/src/adapters/in-memory/options.test.ts +41 -0
  257. package/src/adapters/in-memory/options.ts +87 -0
  258. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  259. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  260. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  261. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  262. package/src/adapters/in-memory/store.test.ts +68 -0
  263. package/src/adapters/in-memory/store.ts +145 -0
  264. package/src/adapters/in-memory/value-comparison.ts +53 -0
  265. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  266. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  267. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  268. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  269. package/src/adapters/sql/index.ts +12 -0
  270. package/src/db-fragment-definition-builder.test.ts +88 -54
  271. package/src/db-fragment-definition-builder.ts +201 -322
  272. package/src/db-fragment-instantiator.test.ts +169 -101
  273. package/src/db-fragment-integration.test.ts +301 -149
  274. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  275. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  276. package/src/dispatchers/node/index.test.ts +91 -0
  277. package/src/dispatchers/node/index.ts +87 -0
  278. package/src/fragments/internal-fragment.routes.ts +42 -0
  279. package/src/fragments/internal-fragment.schema.ts +51 -0
  280. package/src/fragments/internal-fragment.test.ts +730 -274
  281. package/src/fragments/internal-fragment.ts +447 -154
  282. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  283. package/src/hooks/durable-hooks-processor.ts +67 -0
  284. package/src/hooks/hooks.test.ts +411 -259
  285. package/src/hooks/hooks.ts +265 -66
  286. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  287. package/src/migration-engine/auto-from-schema.ts +5 -2
  288. package/src/migration-engine/create.test.ts +2 -2
  289. package/src/migration-engine/generation-engine.test.ts +229 -104
  290. package/src/migration-engine/generation-engine.ts +94 -64
  291. package/src/migration-engine/shared.ts +1 -0
  292. package/src/mod.ts +78 -30
  293. package/src/naming/sql-naming.ts +180 -0
  294. package/src/outbox/outbox-builder.ts +241 -0
  295. package/src/outbox/outbox.test.ts +253 -0
  296. package/src/outbox/outbox.ts +137 -0
  297. package/src/query/column-defaults.ts +41 -3
  298. package/src/query/condition-builder.test.ts +3 -3
  299. package/src/query/cursor.test.ts +116 -18
  300. package/src/query/cursor.ts +75 -26
  301. package/src/query/db-now.ts +6 -0
  302. package/src/query/query-type.test.ts +2 -2
  303. package/src/query/serialize/create-sql-serializer.ts +7 -2
  304. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  305. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  306. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  307. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  308. package/src/query/serialize/sql-serializer.ts +4 -4
  309. package/src/query/simple-query-interface.ts +5 -0
  310. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1512 -1458
  311. package/src/query/unit-of-work/execute-unit-of-work.ts +1708 -596
  312. package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
  313. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +32 -32
  314. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  315. package/src/query/unit-of-work/unit-of-work.test.ts +231 -36
  316. package/src/query/unit-of-work/unit-of-work.ts +229 -31
  317. package/src/query/value-decoding.test.ts +13 -2
  318. package/src/query/value-decoding.ts +17 -4
  319. package/src/query/value-encoding.test.ts +85 -2
  320. package/src/query/value-encoding.ts +56 -6
  321. package/src/schema/create.test.ts +129 -42
  322. package/src/schema/create.ts +187 -47
  323. package/src/schema/generate-id.test.ts +57 -0
  324. package/src/schema/generate-id.ts +38 -0
  325. package/src/schema/serialize.test.ts +14 -2
  326. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  327. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  328. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  329. package/src/schema/validator.test.ts +197 -0
  330. package/src/schema/validator.ts +231 -0
  331. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  332. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  333. package/src/schema-output/prisma.test.ts +536 -0
  334. package/src/schema-output/prisma.ts +573 -0
  335. package/src/util/default-database-adapter.ts +106 -0
  336. package/src/with-database.ts +22 -3
  337. package/tsdown.config.ts +6 -4
  338. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  339. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  341. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  342. package/dist/adapters/drizzle/generate.d.ts +0 -30
  343. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  344. package/dist/adapters/drizzle/generate.js.map +0 -1
  345. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  346. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  347. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  348. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  349. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  350. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  351. package/dist/adapters/shared/table-name-mapper.js +0 -43
  352. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  353. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  354. package/dist/schema-generator/schema-generator.d.ts +0 -15
  355. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  356. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  357. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  358. package/src/adapters/shared/table-name-mapper.ts +0 -50
  359. package/src/schema-generator/schema-generator.ts +0 -12
  360. package/src/shared/config.ts +0 -10
  361. package/src/shared/connection-pool.ts +0 -24
  362. package/src/shared/prisma.ts +0 -45
@@ -19,7 +19,8 @@ export class MySQLSerializer extends SQLSerializer {
19
19
  super(driverConfig);
20
20
  }
21
21
 
22
- protected serializeDate(value: Date): Date {
22
+ protected serializeDate(value: Date, _col: AnyColumn): Date {
23
+ void _col;
23
24
  // MySQL handles Date objects natively
24
25
  return value;
25
26
  }
@@ -34,7 +35,8 @@ export class MySQLSerializer extends SQLSerializer {
34
35
  return value;
35
36
  }
36
37
 
37
- protected deserializeDate(value: unknown): Date {
38
+ protected deserializeDate(value: unknown, _col: AnyColumn): Date {
39
+ void _col;
38
40
  if (value instanceof Date) {
39
41
  return value;
40
42
  }
@@ -96,12 +98,15 @@ export class MySQLSerializer extends SQLSerializer {
96
98
 
97
99
  protected deserializeInteger(value: unknown): number {
98
100
  if (typeof value === "number") {
101
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
102
+ throw new Error(`Cannot deserialize integer from invalid number: ${value}`);
103
+ }
99
104
  return value;
100
105
  }
101
106
  // MySQL may return integers as strings
102
107
  if (typeof value === "string") {
103
108
  const num = Number(value);
104
- if (isNaN(num)) {
109
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
105
110
  throw new Error(`Cannot deserialize integer from invalid string: ${value}`);
106
111
  }
107
112
  return num;
@@ -121,11 +126,14 @@ export class MySQLSerializer extends SQLSerializer {
121
126
  protected deserializeDecimal(value: unknown): number {
122
127
  // MySQL can return decimals as numbers or strings
123
128
  if (typeof value === "number") {
129
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
130
+ throw new Error(`Cannot deserialize decimal from invalid number: ${value}`);
131
+ }
124
132
  return value;
125
133
  }
126
134
  if (typeof value === "string") {
127
135
  const num = parseFloat(value);
128
- if (isNaN(num)) {
136
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
129
137
  throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
130
138
  }
131
139
  return num;
@@ -18,7 +18,8 @@ export class PostgreSQLSerializer extends SQLSerializer {
18
18
  super(driverConfig);
19
19
  }
20
20
 
21
- protected serializeDate(value: Date): Date {
21
+ protected serializeDate(value: Date, _col: AnyColumn): Date {
22
+ void _col;
22
23
  // PostgreSQL handles Date objects natively
23
24
  return value;
24
25
  }
@@ -33,13 +34,18 @@ export class PostgreSQLSerializer extends SQLSerializer {
33
34
  return value;
34
35
  }
35
36
 
36
- protected deserializeDate(value: unknown): Date {
37
+ protected deserializeDate(value: unknown, _col: AnyColumn): Date {
38
+ void _col;
37
39
  if (value instanceof Date) {
40
+ if (this.driverConfig.driverType === "pglite") {
41
+ return new Date(value.getTime() - value.getTimezoneOffset() * 60_000);
42
+ }
38
43
  return value;
39
44
  }
40
45
  // PostgreSQL returns timestamps/dates as strings
41
46
  if (typeof value === "string") {
42
- return new Date(value);
47
+ // Normalize timezone-less timestamps to UTC to avoid local offset drift.
48
+ return new Date(normalizeTimestampString(value));
43
49
  }
44
50
  throw new Error(`Cannot deserialize date from value: ${value}`);
45
51
  }
@@ -91,6 +97,9 @@ export class PostgreSQLSerializer extends SQLSerializer {
91
97
 
92
98
  protected deserializeInteger(value: unknown): number {
93
99
  if (typeof value === "number") {
100
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
101
+ throw new Error(`Cannot deserialize integer from invalid number: ${value}`);
102
+ }
94
103
  return value;
95
104
  }
96
105
  // PostgreSQL may return bigint for large integers
@@ -108,11 +117,14 @@ export class PostgreSQLSerializer extends SQLSerializer {
108
117
  protected deserializeDecimal(value: unknown): number {
109
118
  // PostgreSQL can return decimals as numbers or strings depending on precision
110
119
  if (typeof value === "number") {
120
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
121
+ throw new Error(`Cannot deserialize decimal from invalid number: ${value}`);
122
+ }
111
123
  return value;
112
124
  }
113
125
  if (typeof value === "string") {
114
126
  const num = parseFloat(value);
115
- if (isNaN(num)) {
127
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
116
128
  throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
117
129
  }
118
130
  return num;
@@ -127,3 +139,21 @@ export class PostgreSQLSerializer extends SQLSerializer {
127
139
  throw new Error(`Cannot deserialize string from value: ${typeof value}`);
128
140
  }
129
141
  }
142
+
143
+ const normalizeTimestampString = (value: string) => {
144
+ if (!hasTimeComponent(value) || !isTimestampWithoutTimezone(value)) {
145
+ return value;
146
+ }
147
+ const withTimeSeparator = value.includes(" ") ? value.replace(" ", "T") : value;
148
+ return `${withTimeSeparator}Z`;
149
+ };
150
+
151
+ const hasTimeComponent = (value: string) => /\d{2}:\d{2}:\d{2}/.test(value);
152
+
153
+ const isTimestampWithoutTimezone = (value: string) => {
154
+ // Detect RFC3339-like timezone indicators: Z or +/-HH(:MM)?
155
+ if (value.endsWith("Z")) {
156
+ return false;
157
+ }
158
+ return !/[+-]\d{2}(:?\d{2})?$/.test(value);
159
+ };
@@ -2,10 +2,18 @@ import { describe, it, expect } from "vitest";
2
2
  import { SQLiteSerializer } from "./sqlite-serializer";
3
3
  import type { AnyColumn } from "../../../schema/create";
4
4
  import { BetterSQLite3DriverConfig } from "../../../adapters/generic-sql/driver-config";
5
+ import { sqliteStoragePrisma } from "../../../adapters/generic-sql/sqlite-storage";
5
6
 
6
7
  describe("SQLiteSerializer", () => {
7
8
  const mockDriverConfig = new BetterSQLite3DriverConfig();
8
9
  const serializer = new SQLiteSerializer(mockDriverConfig);
10
+ const prismaSerializer = new SQLiteSerializer(mockDriverConfig, sqliteStoragePrisma);
11
+ const timestampColumn: AnyColumn = {
12
+ name: "createdAt",
13
+ type: "timestamp",
14
+ role: "regular",
15
+ isNullable: false,
16
+ } as AnyColumn;
9
17
 
10
18
  describe("serializeBigInt", () => {
11
19
  describe("for internal-id and reference columns", () => {
@@ -110,6 +118,19 @@ describe("SQLiteSerializer", () => {
110
118
  expect((result as Buffer).length).toBe(8);
111
119
  });
112
120
 
121
+ it("should keep bigint for regular column in prisma storage", () => {
122
+ const col: AnyColumn = {
123
+ name: "largeNumber",
124
+ type: "bigint",
125
+ role: "regular",
126
+ isNullable: false,
127
+ } as AnyColumn;
128
+
129
+ const result = prismaSerializer["serializeBigInt"](BigInt(789), col);
130
+ expect(result).toBe(BigInt(789));
131
+ expect(typeof result).toBe("bigint");
132
+ });
133
+
113
134
  it("should handle large values outside safe integer range as Buffer", () => {
114
135
  const col: AnyColumn = {
115
136
  name: "largeNumber",
@@ -132,11 +153,18 @@ describe("SQLiteSerializer", () => {
132
153
  describe("other serialization methods", () => {
133
154
  it("should serialize Date to timestamp number", () => {
134
155
  const date = new Date("2024-01-01T00:00:00Z");
135
- const result = serializer["serializeDate"](date);
156
+ const result = serializer["serializeDate"](date, timestampColumn);
136
157
  expect(result).toBe(date.getTime());
137
158
  expect(typeof result).toBe("number");
138
159
  });
139
160
 
161
+ it("should serialize Date to ISO string for prisma storage", () => {
162
+ const date = new Date("2024-01-01T00:00:00Z");
163
+ const result = prismaSerializer["serializeDate"](date, timestampColumn);
164
+ expect(result).toBe(date.toISOString());
165
+ expect(typeof result).toBe("string");
166
+ });
167
+
140
168
  it("should serialize boolean to 0/1", () => {
141
169
  expect(serializer["serializeBoolean"](true)).toBe(1);
142
170
  expect(serializer["serializeBoolean"](false)).toBe(0);
@@ -181,6 +209,18 @@ describe("SQLiteSerializer", () => {
181
209
  });
182
210
  });
183
211
 
212
+ describe("deserializeDate", () => {
213
+ it("should parse CURRENT_TIMESTAMP format as UTC", () => {
214
+ const date = prismaSerializer["deserializeDate"]("2024-03-10 12:34:56", timestampColumn);
215
+ expect(date.toISOString()).toBe("2024-03-10T12:34:56.000Z");
216
+ });
217
+
218
+ it("should parse CURRENT_TIMESTAMP format with milliseconds as UTC", () => {
219
+ const date = prismaSerializer["deserializeDate"]("2024-03-10 12:34:56.789", timestampColumn);
220
+ expect(date.toISOString()).toBe("2024-03-10T12:34:56.789Z");
221
+ });
222
+ });
223
+
184
224
  describe("deserializeInteger", () => {
185
225
  it("should deserialize number directly", () => {
186
226
  expect(serializer["deserializeInteger"](42)).toBe(42);
@@ -248,4 +288,14 @@ describe("SQLiteSerializer", () => {
248
288
  );
249
289
  });
250
290
  });
291
+
292
+ describe("deserializeBigInt", () => {
293
+ it("should throw when prisma storage receives unsafe bigint number", () => {
294
+ const unsafeNumber = Number.MAX_SAFE_INTEGER + 10;
295
+ expect(() => prismaSerializer["deserializeBigInt"](unsafeNumber)).toThrow(RangeError);
296
+ expect(() => prismaSerializer["deserializeBigInt"](unsafeNumber)).toThrow(
297
+ /exceeds Number\.MAX_SAFE_INTEGER/,
298
+ );
299
+ });
300
+ });
251
301
  });
@@ -1,23 +1,59 @@
1
1
  import type { AnyColumn } from "../../../schema/create";
2
2
  import { SQLSerializer } from "../sql-serializer";
3
3
  import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
4
+ import type { SQLiteStorageMode } from "../../../adapters/generic-sql/sqlite-storage";
5
+ import { sqliteStorageDefault } from "../../../adapters/generic-sql/sqlite-storage";
6
+
7
+ const SQLITE_UTC_TIMESTAMP_REGEX =
8
+ /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/;
9
+
10
+ function parseSQLiteUtcTimestamp(value: string): Date | null {
11
+ const match = SQLITE_UTC_TIMESTAMP_REGEX.exec(value);
12
+ if (!match) {
13
+ return null;
14
+ }
15
+
16
+ const [, year, month, day, hour, minute, second, millis] = match;
17
+ const milliseconds = millis ? Number(millis.padEnd(3, "0")) : 0;
18
+ return new Date(
19
+ Date.UTC(
20
+ Number(year),
21
+ Number(month) - 1,
22
+ Number(day),
23
+ Number(hour),
24
+ Number(minute),
25
+ Number(second),
26
+ milliseconds,
27
+ ),
28
+ );
29
+ }
4
30
 
5
31
  /**
6
32
  * SQLite-specific serializer.
7
33
  *
8
34
  * SQLite has limited native type support and requires conversions:
9
35
  * - JSON → strings (no native JSON support)
10
- * - Dates → numbers (timestamps)
36
+ * - Dates → numbers or ISO strings (storage-mode dependent)
11
37
  * - Booleans → 0/1
12
- * - BigInts → Buffer (except for internal-id and reference columns → number)
38
+ * - BigInts → Buffer or integer (storage-mode dependent; internal-id/reference stay integer)
13
39
  * - Numbers/strings → Date for timestamps/dates
14
40
  */
15
41
  export class SQLiteSerializer extends SQLSerializer {
16
- constructor(driverConfig: DriverConfig) {
42
+ private readonly sqliteStorageMode: SQLiteStorageMode;
43
+
44
+ constructor(driverConfig: DriverConfig, sqliteStorageMode?: SQLiteStorageMode) {
17
45
  super(driverConfig);
46
+ this.sqliteStorageMode = sqliteStorageMode ?? sqliteStorageDefault;
18
47
  }
19
48
 
20
- protected serializeDate(value: Date): number {
49
+ protected serializeDate(value: Date, col: AnyColumn): number | string {
50
+ const storage =
51
+ col.type === "date"
52
+ ? this.sqliteStorageMode.dateStorage
53
+ : this.sqliteStorageMode.timestampStorage;
54
+ if (storage === "iso-text") {
55
+ return value.toISOString();
56
+ }
21
57
  return value.getTime();
22
58
  }
23
59
 
@@ -25,7 +61,7 @@ export class SQLiteSerializer extends SQLSerializer {
25
61
  return value ? 1 : 0;
26
62
  }
27
63
 
28
- protected serializeBigInt(value: bigint, col: AnyColumn): number | Buffer {
64
+ protected serializeBigInt(value: bigint, col: AnyColumn): bigint | number | Buffer {
29
65
  // SQLite special case: internal-id and reference columns use integer, not blob
30
66
  // These should be converted to numbers for SQLite
31
67
  if (col.role === "reference" || col.role === "internal-id") {
@@ -40,18 +76,52 @@ export class SQLiteSerializer extends SQLSerializer {
40
76
  }
41
77
  return Number(value);
42
78
  }
79
+ if (this.sqliteStorageMode.bigintStorage === "integer") {
80
+ return value;
81
+ }
43
82
  const buf = Buffer.alloc(8);
44
83
  buf.writeBigInt64BE(value);
45
84
  return buf;
46
85
  }
47
86
 
48
- protected deserializeDate(value: unknown): Date {
87
+ protected deserializeDate(value: unknown, col: AnyColumn): Date {
49
88
  if (value instanceof Date) {
50
89
  return value;
51
90
  }
52
- if (typeof value === "number" || typeof value === "string") {
91
+ if (typeof value === "string") {
92
+ if (/^\d+$/.test(value)) {
93
+ const numericDate = new Date(Number(value));
94
+ if (Number.isNaN(numericDate.getTime())) {
95
+ throw new Error(`Cannot deserialize date from value: ${value}`);
96
+ }
97
+ return numericDate;
98
+ }
99
+ const parsed = parseSQLiteUtcTimestamp(value);
100
+ const date = parsed ?? new Date(value);
101
+ if (Number.isNaN(date.getTime())) {
102
+ throw new Error(`Cannot deserialize date from value: ${value}`);
103
+ }
104
+ return date;
105
+ }
106
+ if (typeof value === "number") {
107
+ if (Number.isNaN(value)) {
108
+ throw new Error(`Cannot deserialize date from value: ${value}`);
109
+ }
53
110
  return new Date(value);
54
111
  }
112
+ if (typeof value === "bigint") {
113
+ const storage =
114
+ col.type === "date"
115
+ ? this.sqliteStorageMode.dateStorage
116
+ : this.sqliteStorageMode.timestampStorage;
117
+ if (storage === "epoch-ms") {
118
+ const date = new Date(Number(value));
119
+ if (Number.isNaN(date.getTime())) {
120
+ throw new Error(`Cannot deserialize date from value: ${value}`);
121
+ }
122
+ return date;
123
+ }
124
+ }
55
125
  throw new Error(`Cannot deserialize date from value: ${value}`);
56
126
  }
57
127
 
@@ -76,6 +146,13 @@ export class SQLiteSerializer extends SQLSerializer {
76
146
  return BigInt(value);
77
147
  }
78
148
  if (typeof value === "number") {
149
+ if (this.sqliteStorageMode.bigintStorage === "integer") {
150
+ if (Math.abs(value) > Number.MAX_SAFE_INTEGER) {
151
+ throw new RangeError(
152
+ `Cannot deserialize bigint value ${value}: exceeds Number.MAX_SAFE_INTEGER`,
153
+ );
154
+ }
155
+ }
79
156
  return BigInt(value);
80
157
  }
81
158
  throw new Error(`Cannot deserialize bigint from value: ${value}`);
@@ -110,12 +187,15 @@ export class SQLiteSerializer extends SQLSerializer {
110
187
 
111
188
  protected deserializeInteger(value: unknown): number {
112
189
  if (typeof value === "number") {
190
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
191
+ throw new Error(`Cannot deserialize integer from invalid number: ${value}`);
192
+ }
113
193
  return value;
114
194
  }
115
195
  // SQLite may return integers as strings for large values
116
196
  if (typeof value === "string") {
117
197
  const num = Number(value);
118
- if (isNaN(num)) {
198
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
119
199
  throw new Error(`Cannot deserialize integer from invalid string: ${value}`);
120
200
  }
121
201
  return num;
@@ -135,11 +215,14 @@ export class SQLiteSerializer extends SQLSerializer {
135
215
  protected deserializeDecimal(value: unknown): number {
136
216
  // SQLite stores decimals as REAL (floating point) or TEXT
137
217
  if (typeof value === "number") {
218
+ if (Number.isNaN(value) || !Number.isFinite(value)) {
219
+ throw new Error(`Cannot deserialize decimal from invalid number: ${value}`);
220
+ }
138
221
  return value;
139
222
  }
140
223
  if (typeof value === "string") {
141
224
  const num = parseFloat(value);
142
- if (isNaN(num)) {
225
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
143
226
  throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
144
227
  }
145
228
  return num;
@@ -40,7 +40,7 @@ export abstract class SQLSerializer {
40
40
 
41
41
  // Handle date/timestamp deserialization
42
42
  if (col.type === "timestamp" || col.type === "date") {
43
- return this.deserializeDate(value);
43
+ return this.deserializeDate(value, col);
44
44
  }
45
45
 
46
46
  // Handle boolean deserialization
@@ -103,7 +103,7 @@ export abstract class SQLSerializer {
103
103
  if (!skipDriverConversions) {
104
104
  // Handle date/timestamp serialization
105
105
  if (value instanceof Date) {
106
- return this.serializeDate(value);
106
+ return this.serializeDate(value, col);
107
107
  }
108
108
 
109
109
  // Handle boolean serialization
@@ -126,13 +126,13 @@ export abstract class SQLSerializer {
126
126
  }
127
127
 
128
128
  // Abstract methods for dialect-specific serialization
129
- protected abstract serializeDate(value: Date): Date | number;
129
+ protected abstract serializeDate(value: Date, col: AnyColumn): Date | number | string;
130
130
  protected abstract serializeBoolean(value: boolean): boolean | number;
131
131
  protected abstract serializeBigInt(value: bigint, col: AnyColumn): bigint | number | Buffer;
132
132
  protected abstract serializeJson(value: unknown): unknown;
133
133
 
134
134
  // Abstract methods for dialect-specific deserialization
135
- protected abstract deserializeDate(value: unknown): Date;
135
+ protected abstract deserializeDate(value: unknown, col: AnyColumn): Date;
136
136
  protected abstract deserializeBoolean(value: unknown): boolean;
137
137
  protected abstract deserializeBigInt(value: unknown): bigint;
138
138
  protected abstract deserializeJson(value: unknown): unknown;
@@ -133,6 +133,11 @@ export type FindManyOptions<
133
133
  : {});
134
134
 
135
135
  export interface SimpleQueryInterface<TSchema extends AnySchema, TUOWConfig = void> {
136
+ /**
137
+ * Fetch the current database timestamp.
138
+ * Optional for adapters that cannot provide DB time.
139
+ */
140
+ now?: () => Promise<Date>;
136
141
  /**
137
142
  * Find multiple records using a builder pattern
138
143
  */