@fragno-dev/db 0.1.14 → 0.2.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 (445) hide show
  1. package/.turbo/turbo-build.log +242 -139
  2. package/CHANGELOG.md +47 -0
  3. package/README.md +123 -8
  4. package/dist/adapters/adapters.d.ts +19 -5
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -19
  8. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  9. package/dist/adapters/drizzle/drizzle-adapter.js +7 -47
  10. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  11. package/dist/adapters/drizzle/generate.d.ts +7 -1
  12. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  13. package/dist/adapters/drizzle/generate.js +46 -45
  14. package/dist/adapters/drizzle/generate.js.map +1 -1
  15. package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
  16. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
  17. package/dist/adapters/generic-sql/driver-config.js +94 -0
  18. package/dist/adapters/generic-sql/driver-config.js.map +1 -0
  19. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
  20. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
  21. package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
  22. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
  23. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
  24. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
  25. package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
  26. package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
  27. package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
  28. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
  29. package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
  30. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
  31. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
  32. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
  33. package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
  34. package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
  35. package/dist/adapters/generic-sql/migration/executor.js +18 -0
  36. package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
  37. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
  38. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
  39. package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
  40. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
  41. package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
  42. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
  43. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
  44. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
  45. package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
  46. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
  47. package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
  48. package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
  49. package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
  50. package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
  51. package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
  52. package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
  53. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
  54. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
  55. package/dist/adapters/generic-sql/query/select-builder.js +69 -0
  56. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
  57. package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
  58. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
  59. package/dist/adapters/generic-sql/query/where-builder.js +129 -0
  60. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
  61. package/dist/adapters/generic-sql/result-interpreter.js +74 -0
  62. package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
  63. package/dist/adapters/generic-sql/uow-decoder.js +105 -0
  64. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
  65. package/dist/adapters/generic-sql/uow-encoder.js +93 -0
  66. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
  67. package/dist/adapters/kysely/kysely-adapter.d.ts +5 -16
  68. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  69. package/dist/adapters/kysely/kysely-adapter.js +6 -159
  70. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  71. package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +48 -62
  72. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
  73. package/dist/adapters/{kysely/kysely-shared.d.ts → shared/table-name-mapper.d.ts} +3 -2
  74. package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
  75. package/dist/adapters/shared/table-name-mapper.js +43 -0
  76. package/dist/adapters/shared/table-name-mapper.js.map +1 -0
  77. package/dist/adapters/shared/uow-operation-compiler.js +105 -0
  78. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
  79. package/dist/db-fragment-definition-builder.d.ts +186 -0
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  81. package/dist/db-fragment-definition-builder.js +207 -0
  82. package/dist/db-fragment-definition-builder.js.map +1 -0
  83. package/dist/fragments/internal-fragment.d.ts +53 -0
  84. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  85. package/dist/fragments/internal-fragment.js +111 -0
  86. package/dist/fragments/internal-fragment.js.map +1 -0
  87. package/dist/hooks/hooks.d.ts +51 -0
  88. package/dist/hooks/hooks.d.ts.map +1 -0
  89. package/dist/hooks/hooks.js +88 -0
  90. package/dist/hooks/hooks.js.map +1 -0
  91. package/dist/migration-engine/generation-engine.d.ts +0 -2
  92. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  93. package/dist/migration-engine/generation-engine.js +38 -56
  94. package/dist/migration-engine/generation-engine.js.map +1 -1
  95. package/dist/mod.d.ts +35 -23
  96. package/dist/mod.d.ts.map +1 -1
  97. package/dist/mod.js +48 -45
  98. package/dist/mod.js.map +1 -1
  99. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +165 -0
  100. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
  101. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  102. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  103. package/dist/packages/fragno/dist/api/error.js +48 -0
  104. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  105. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  106. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  107. package/dist/packages/fragno/dist/api/fragment-instantiator.js +525 -0
  108. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  109. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  110. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  111. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  112. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  113. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  114. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  115. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  116. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  117. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  118. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  119. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  120. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  121. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  122. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  123. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  124. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  125. package/dist/packages/fragno/dist/api/route.js +17 -0
  126. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  127. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  128. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  129. package/dist/query/column-defaults.js +27 -0
  130. package/dist/query/column-defaults.js.map +1 -0
  131. package/dist/query/cursor.d.ts +14 -6
  132. package/dist/query/cursor.d.ts.map +1 -1
  133. package/dist/query/cursor.js +16 -7
  134. package/dist/query/cursor.js.map +1 -1
  135. package/dist/query/orm/orm.d.ts +1 -1
  136. package/dist/query/orm/orm.js.map +1 -1
  137. package/dist/query/serialize/create-sql-serializer.js +30 -0
  138. package/dist/query/serialize/create-sql-serializer.js.map +1 -0
  139. package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
  140. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
  141. package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
  142. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
  143. package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
  144. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
  145. package/dist/query/serialize/sql-serializer.js +67 -0
  146. package/dist/query/serialize/sql-serializer.js.map +1 -0
  147. package/dist/query/{query.d.ts → simple-query-interface.d.ts} +6 -6
  148. package/dist/query/simple-query-interface.d.ts.map +1 -0
  149. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +133 -0
  150. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
  151. package/dist/query/unit-of-work/execute-unit-of-work.js +197 -0
  152. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
  153. package/dist/query/unit-of-work/retry-policy.d.ts +88 -0
  154. package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
  155. package/dist/query/unit-of-work/retry-policy.js +61 -0
  156. package/dist/query/unit-of-work/retry-policy.js.map +1 -0
  157. package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +145 -58
  158. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
  159. package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +435 -198
  160. package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
  161. package/dist/query/value-decoding.js +71 -0
  162. package/dist/query/value-decoding.js.map +1 -0
  163. package/dist/query/value-encoding.js +124 -0
  164. package/dist/query/value-encoding.js.map +1 -0
  165. package/dist/schema/create.d.ts +3 -0
  166. package/dist/schema/create.d.ts.map +1 -1
  167. package/dist/schema/create.js +4 -0
  168. package/dist/schema/create.js.map +1 -1
  169. package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
  170. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
  171. package/dist/schema/type-conversion/dialect/mysql.js +57 -0
  172. package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
  173. package/dist/schema/type-conversion/dialect/postgres.js +56 -0
  174. package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
  175. package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
  176. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
  177. package/dist/schema/type-conversion/type-mapping.js +63 -0
  178. package/dist/schema/type-conversion/type-mapping.js.map +1 -0
  179. package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
  180. package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
  181. package/dist/sql-driver/connection/connection-provider.js +19 -0
  182. package/dist/sql-driver/connection/connection-provider.js.map +1 -0
  183. package/dist/sql-driver/connection/single-connection-provider.js +23 -0
  184. package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
  185. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
  186. package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
  187. package/dist/sql-driver/dialects/dialects.d.ts +2 -0
  188. package/dist/sql-driver/dialects/dialects.js +3 -0
  189. package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
  190. package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
  191. package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
  192. package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
  193. package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
  194. package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
  195. package/dist/sql-driver/driver/runtime-driver.js +56 -0
  196. package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
  197. package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
  198. package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
  199. package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
  200. package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
  201. package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
  202. package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
  203. package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
  204. package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
  205. package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
  206. package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
  207. package/dist/sql-driver/sql-driver-adapter.js +68 -0
  208. package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
  209. package/dist/sql-driver/sql-driver.d.ts +38 -0
  210. package/dist/sql-driver/sql-driver.d.ts.map +1 -0
  211. package/dist/sql-driver/sql-driver.js +1 -0
  212. package/dist/sql-driver/sql.js +50 -0
  213. package/dist/sql-driver/sql.js.map +1 -0
  214. package/dist/with-database.d.ts +32 -0
  215. package/dist/with-database.d.ts.map +1 -0
  216. package/dist/with-database.js +34 -0
  217. package/dist/with-database.js.map +1 -0
  218. package/package.json +43 -9
  219. package/src/adapters/adapters.ts +23 -4
  220. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +140 -185
  221. package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +187 -55
  222. package/src/adapters/drizzle/drizzle-adapter.ts +14 -93
  223. package/src/adapters/drizzle/generate.test.ts +102 -269
  224. package/src/adapters/drizzle/generate.ts +89 -63
  225. package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
  226. package/src/adapters/drizzle/shared.ts +0 -34
  227. package/src/adapters/drizzle/test-utils.ts +36 -5
  228. package/src/adapters/generic-sql/README.md +14 -0
  229. package/src/adapters/generic-sql/driver-config.ts +144 -0
  230. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
  231. package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
  232. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
  233. package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
  234. package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
  235. package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
  236. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
  237. package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
  238. package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
  239. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
  240. package/src/adapters/generic-sql/migration/executor.ts +33 -0
  241. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
  242. package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
  243. package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
  244. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
  245. package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
  246. package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
  247. package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
  248. package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
  249. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
  250. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
  251. package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
  252. package/src/adapters/generic-sql/query/select-builder.ts +137 -0
  253. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
  254. package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
  255. package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
  256. package/src/adapters/generic-sql/query/where-builder.ts +211 -0
  257. package/src/adapters/generic-sql/result-interpreter.ts +102 -0
  258. package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
  259. package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
  260. package/src/adapters/generic-sql/uow-decoder.ts +152 -0
  261. package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
  262. package/src/adapters/generic-sql/uow-encoder.ts +131 -0
  263. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +90 -96
  264. package/src/adapters/kysely/kysely-adapter-sqlocal.test.ts +215 -0
  265. package/src/adapters/kysely/kysely-adapter.ts +10 -242
  266. package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +111 -106
  267. package/src/adapters/shared/table-name-mapper.ts +50 -0
  268. package/src/adapters/shared/uow-operation-compiler.ts +211 -0
  269. package/src/db-fragment-definition-builder.test.ts +887 -0
  270. package/src/db-fragment-definition-builder.ts +737 -0
  271. package/src/db-fragment-instantiator.test.ts +543 -0
  272. package/src/db-fragment-integration.test.ts +406 -0
  273. package/src/fragments/internal-fragment.test.ts +549 -0
  274. package/src/fragments/internal-fragment.ts +249 -0
  275. package/src/hooks/hooks.test.ts +575 -0
  276. package/src/hooks/hooks.ts +179 -0
  277. package/src/migration-engine/generation-engine.test.ts +60 -27
  278. package/src/migration-engine/generation-engine.ts +99 -92
  279. package/src/mod.ts +139 -78
  280. package/src/query/column-defaults.ts +49 -0
  281. package/src/query/cursor.test.ts +147 -3
  282. package/src/query/cursor.ts +25 -8
  283. package/src/query/orm/orm.ts +1 -1
  284. package/src/query/query-type.test.ts +9 -9
  285. package/src/query/serialize/create-sql-serializer.ts +34 -0
  286. package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
  287. package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
  288. package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
  289. package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
  290. package/src/query/serialize/sql-serializer.ts +143 -0
  291. package/src/query/{query.ts → simple-query-interface.ts} +4 -4
  292. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1310 -0
  293. package/src/query/unit-of-work/execute-unit-of-work.ts +504 -0
  294. package/src/query/unit-of-work/retry-policy.test.ts +217 -0
  295. package/src/query/unit-of-work/retry-policy.ts +141 -0
  296. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +831 -0
  297. package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +7 -5
  298. package/src/query/unit-of-work/unit-of-work.test.ts +1716 -0
  299. package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +716 -420
  300. package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -298
  301. package/src/query/value-decoding.ts +113 -0
  302. package/src/query/value-encoding.test.ts +390 -0
  303. package/src/query/value-encoding.ts +168 -0
  304. package/src/schema/create.test.ts +5 -1
  305. package/src/schema/create.ts +5 -0
  306. package/src/schema/serialize.test.ts +165 -407
  307. package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
  308. package/src/schema/type-conversion/dialect/mysql.ts +64 -0
  309. package/src/schema/type-conversion/dialect/postgres.ts +62 -0
  310. package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
  311. package/src/schema/type-conversion/type-mapping.test.ts +137 -0
  312. package/src/schema/type-conversion/type-mapping.ts +153 -0
  313. package/src/shared/connection-pool.ts +5 -5
  314. package/src/sql-driver/better-sqlite3.test.ts +126 -0
  315. package/src/sql-driver/connection/connection-provider.ts +27 -0
  316. package/src/sql-driver/connection/single-connection-provider.ts +42 -0
  317. package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
  318. package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
  319. package/src/sql-driver/dialects/dialects.ts +1 -0
  320. package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
  321. package/src/sql-driver/driver/runtime-driver.ts +91 -0
  322. package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
  323. package/src/sql-driver/query-executor/plugin.ts +22 -0
  324. package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
  325. package/src/sql-driver/query-executor/query-executor.ts +44 -0
  326. package/src/sql-driver/sql-driver-adapter.ts +96 -0
  327. package/src/sql-driver/sql-driver.ts +53 -0
  328. package/src/sql-driver/sql.ts +57 -0
  329. package/src/sql-driver/sqlocal.test.ts +117 -0
  330. package/src/with-database.ts +152 -0
  331. package/tsdown.config.ts +8 -2
  332. package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
  333. package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
  334. package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
  335. package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
  336. package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
  337. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
  338. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
  339. package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -315
  340. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
  341. package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -116
  342. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
  343. package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -149
  344. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
  345. package/dist/adapters/drizzle/join-column-utils.js +0 -28
  346. package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
  347. package/dist/adapters/drizzle/shared.d.ts +0 -14
  348. package/dist/adapters/drizzle/shared.d.ts.map +0 -1
  349. package/dist/adapters/drizzle/shared.js +0 -35
  350. package/dist/adapters/drizzle/shared.js.map +0 -1
  351. package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
  352. package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
  353. package/dist/adapters/kysely/kysely-query-builder.js +0 -321
  354. package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
  355. package/dist/adapters/kysely/kysely-query-compiler.js +0 -66
  356. package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
  357. package/dist/adapters/kysely/kysely-query.d.ts +0 -22
  358. package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
  359. package/dist/adapters/kysely/kysely-query.js +0 -223
  360. package/dist/adapters/kysely/kysely-query.js.map +0 -1
  361. package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
  362. package/dist/adapters/kysely/kysely-shared.js +0 -18
  363. package/dist/adapters/kysely/kysely-shared.js.map +0 -1
  364. package/dist/adapters/kysely/kysely-uow-compiler.js +0 -170
  365. package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
  366. package/dist/adapters/kysely/kysely-uow-executor.js +0 -89
  367. package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
  368. package/dist/adapters/kysely/migration/execute-base.js +0 -128
  369. package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
  370. package/dist/adapters/kysely/migration/execute-factory.js +0 -34
  371. package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
  372. package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
  373. package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
  374. package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
  375. package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
  376. package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
  377. package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
  378. package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
  379. package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
  380. package/dist/adapters/kysely/migration/execute.js +0 -34
  381. package/dist/adapters/kysely/migration/execute.js.map +0 -1
  382. package/dist/bind-services.d.ts +0 -7
  383. package/dist/bind-services.d.ts.map +0 -1
  384. package/dist/bind-services.js +0 -14
  385. package/dist/bind-services.js.map +0 -1
  386. package/dist/fragment.d.ts +0 -173
  387. package/dist/fragment.d.ts.map +0 -1
  388. package/dist/fragment.js +0 -191
  389. package/dist/fragment.js.map +0 -1
  390. package/dist/migration-engine/create.d.ts +0 -37
  391. package/dist/migration-engine/create.d.ts.map +0 -1
  392. package/dist/migration-engine/create.js +0 -58
  393. package/dist/migration-engine/create.js.map +0 -1
  394. package/dist/migration-engine/shared.d.ts +0 -112
  395. package/dist/migration-engine/shared.d.ts.map +0 -1
  396. package/dist/query/query.d.ts.map +0 -1
  397. package/dist/query/result-transform.js +0 -168
  398. package/dist/query/result-transform.js.map +0 -1
  399. package/dist/query/unit-of-work.d.ts.map +0 -1
  400. package/dist/query/unit-of-work.js.map +0 -1
  401. package/dist/schema/serialize.js +0 -106
  402. package/dist/schema/serialize.js.map +0 -1
  403. package/dist/shared/settings-schema.js +0 -36
  404. package/dist/shared/settings-schema.js.map +0 -1
  405. package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -170
  406. package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
  407. package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
  408. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1383
  409. package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -636
  410. package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -218
  411. package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -276
  412. package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
  413. package/src/adapters/drizzle/join-column-utils.ts +0 -39
  414. package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
  415. package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
  416. package/src/adapters/kysely/kysely-query-builder.ts +0 -666
  417. package/src/adapters/kysely/kysely-query-compiler.ts +0 -132
  418. package/src/adapters/kysely/kysely-query.test.ts +0 -498
  419. package/src/adapters/kysely/kysely-query.ts +0 -390
  420. package/src/adapters/kysely/kysely-shared.ts +0 -23
  421. package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -998
  422. package/src/adapters/kysely/kysely-uow-compiler.ts +0 -318
  423. package/src/adapters/kysely/kysely-uow-executor.ts +0 -145
  424. package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -811
  425. package/src/adapters/kysely/migration/execute-base.ts +0 -256
  426. package/src/adapters/kysely/migration/execute-factory.ts +0 -53
  427. package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
  428. package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
  429. package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
  430. package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
  431. package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
  432. package/src/adapters/kysely/migration/execute.ts +0 -50
  433. package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
  434. package/src/bind-services.test.ts +0 -214
  435. package/src/bind-services.ts +0 -37
  436. package/src/db-fragment.test.ts +0 -800
  437. package/src/fragment.ts +0 -727
  438. package/src/query/result-transform.ts +0 -271
  439. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  440. package/src/query/unit-of-work.test.ts +0 -943
  441. package/src/schema/serialize.ts +0 -396
  442. package/src/shared/settings-schema.ts +0 -61
  443. package/src/uow-context-integration.test.ts +0 -102
  444. package/src/uow-context.test.ts +0 -182
  445. /package/dist/query/{query.js → simple-query-interface.js} +0 -0
@@ -1,6 +1,11 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  import { decodeCursor, createCursorFromRecord, serializeCursorValues, Cursor } from "./cursor";
3
3
  import { column, idColumn, schema } from "../schema/create";
4
+ import {
5
+ BetterSQLite3DriverConfig,
6
+ MySQL2DriverConfig,
7
+ NodePostgresDriverConfig,
8
+ } from "../adapters/generic-sql/driver-config";
4
9
 
5
10
  describe("Cursor utilities", () => {
6
11
  describe("Cursor class encode and decode", () => {
@@ -245,7 +250,11 @@ describe("Cursor utilities", () => {
245
250
  });
246
251
 
247
252
  const indexColumns = [table.columns.id, table.columns.age];
248
- const serialized = serializeCursorValues(cursor, indexColumns, "postgresql");
253
+ const serialized = serializeCursorValues(
254
+ cursor,
255
+ indexColumns,
256
+ new NodePostgresDriverConfig(),
257
+ );
249
258
 
250
259
  expect(serialized).toHaveProperty("id", "user123");
251
260
  expect(serialized).toHaveProperty("age", 25);
@@ -267,7 +276,11 @@ describe("Cursor utilities", () => {
267
276
  });
268
277
 
269
278
  const indexColumns = [table.columns.id, table.columns.name];
270
- const serialized = serializeCursorValues(cursor, indexColumns, "postgresql");
279
+ const serialized = serializeCursorValues(
280
+ cursor,
281
+ indexColumns,
282
+ new NodePostgresDriverConfig(),
283
+ );
271
284
 
272
285
  expect(serialized).toHaveProperty("id", "user123");
273
286
  expect(serialized).not.toHaveProperty("name");
@@ -307,13 +320,144 @@ describe("Cursor utilities", () => {
307
320
  const decoded = decodeCursor(cursor.encode());
308
321
 
309
322
  // Serialize the values
310
- const serialized = serializeCursorValues(decoded, indexColumns, "postgresql");
323
+ const serialized = serializeCursorValues(
324
+ decoded,
325
+ indexColumns,
326
+ new NodePostgresDriverConfig(),
327
+ );
311
328
 
312
329
  // Should preserve the values
313
330
  expect(serialized["score"]).toBe(42);
314
331
  expect(serialized["createdAt"]).toBe(1234567890);
315
332
  });
316
333
 
334
+ it("should handle Date objects in cursors for PostgreSQL", () => {
335
+ const testSchema = schema((s) =>
336
+ s.addTable("posts", (t) =>
337
+ t
338
+ .addColumn("id", idColumn())
339
+ .addColumn("createdAt", column("timestamp"))
340
+ .createIndex("created", ["createdAt"]),
341
+ ),
342
+ );
343
+
344
+ const table = testSchema.tables.posts;
345
+ const createdAtDate = new Date("2025-11-07T09:36:57.959Z");
346
+ const record = {
347
+ id: "post123",
348
+ createdAt: createdAtDate,
349
+ };
350
+
351
+ const index = table.indexes.created;
352
+ const indexColumns = index.columns;
353
+
354
+ // Create cursor from record (has Date object)
355
+ const cursor = createCursorFromRecord(record, indexColumns, {
356
+ indexName: "created",
357
+ orderDirection: "asc",
358
+ pageSize: 10,
359
+ });
360
+
361
+ // Encode and decode (Date becomes string in JSON)
362
+ const encoded = cursor.encode();
363
+ const decoded = decodeCursor(encoded);
364
+
365
+ // After decode, the value is a string (from JSON.parse)
366
+ expect(typeof decoded.indexValues["createdAt"]).toBe("string");
367
+ expect(decoded.indexValues["createdAt"]).toBe("2025-11-07T09:36:57.959Z");
368
+
369
+ // Serialize should convert it back to Date for the database
370
+ const serialized = serializeCursorValues(
371
+ decoded,
372
+ indexColumns,
373
+ new NodePostgresDriverConfig(),
374
+ );
375
+
376
+ // For PostgreSQL, Date objects should be passed through as-is
377
+ expect(serialized["createdAt"]).toBeInstanceOf(Date);
378
+ expect((serialized["createdAt"] as Date).toISOString()).toBe("2025-11-07T09:36:57.959Z");
379
+ });
380
+
381
+ it("should handle Date objects in cursors for SQLite", () => {
382
+ const testSchema = schema((s) =>
383
+ s.addTable("posts", (t) =>
384
+ t
385
+ .addColumn("id", idColumn())
386
+ .addColumn("createdAt", column("timestamp"))
387
+ .createIndex("created", ["createdAt"]),
388
+ ),
389
+ );
390
+
391
+ const table = testSchema.tables.posts;
392
+ const createdAtDate = new Date("2025-11-07T09:36:57.959Z");
393
+ const record = {
394
+ id: "post123",
395
+ createdAt: createdAtDate,
396
+ };
397
+
398
+ const index = table.indexes.created;
399
+ const indexColumns = index.columns;
400
+
401
+ // Create cursor from record
402
+ const cursor = createCursorFromRecord(record, indexColumns, {
403
+ indexName: "created",
404
+ orderDirection: "asc",
405
+ pageSize: 10,
406
+ });
407
+
408
+ // Encode and decode
409
+ const decoded = decodeCursor(cursor.encode());
410
+
411
+ // Serialize should convert string back to Date, then to timestamp number for SQLite
412
+ const serialized = serializeCursorValues(
413
+ decoded,
414
+ indexColumns,
415
+ new BetterSQLite3DriverConfig(),
416
+ );
417
+
418
+ // For SQLite, Date should be converted to timestamp number
419
+ expect(typeof serialized["createdAt"]).toBe("number");
420
+ expect(serialized["createdAt"]).toBe(createdAtDate.getTime());
421
+ });
422
+
423
+ it("should handle Date objects in cursors for MySQL", () => {
424
+ const testSchema = schema((s) =>
425
+ s.addTable("posts", (t) =>
426
+ t
427
+ .addColumn("id", idColumn())
428
+ .addColumn("createdAt", column("timestamp"))
429
+ .createIndex("created", ["createdAt"]),
430
+ ),
431
+ );
432
+
433
+ const table = testSchema.tables.posts;
434
+ const createdAtDate = new Date("2025-11-07T09:36:57.959Z");
435
+ const record = {
436
+ id: "post123",
437
+ createdAt: createdAtDate,
438
+ };
439
+
440
+ const index = table.indexes.created;
441
+ const indexColumns = index.columns;
442
+
443
+ // Create cursor from record
444
+ const cursor = createCursorFromRecord(record, indexColumns, {
445
+ indexName: "created",
446
+ orderDirection: "asc",
447
+ pageSize: 10,
448
+ });
449
+
450
+ // Encode and decode
451
+ const decoded = decodeCursor(cursor.encode());
452
+
453
+ // Serialize for MySQL
454
+ const serialized = serializeCursorValues(decoded, indexColumns, new MySQL2DriverConfig());
455
+
456
+ // For MySQL, Date objects should be passed through as-is
457
+ expect(serialized["createdAt"]).toBeInstanceOf(Date);
458
+ expect((serialized["createdAt"] as Date).toISOString()).toBe("2025-11-07T09:36:57.959Z");
459
+ });
460
+
317
461
  it("should handle different order directions correctly", () => {
318
462
  const cursorAsc = new Cursor({
319
463
  indexName: "_primary",
@@ -1,6 +1,7 @@
1
1
  import type { AnyColumn } from "../schema/create";
2
- import { serialize } from "../schema/serialize";
3
- import type { SQLProvider } from "../shared/providers";
2
+ import { createSQLSerializer } from "./serialize/create-sql-serializer";
3
+ import { resolveFragnoIdValue } from "./value-encoding";
4
+ import type { DriverConfig } from "../adapters/generic-sql/driver-config";
4
5
 
5
6
  /**
6
7
  * Cursor object containing all information needed for pagination
@@ -78,6 +79,10 @@ export interface CursorResult<T> {
78
79
  * Cursor to fetch the next page (undefined if no more results)
79
80
  */
80
81
  cursor?: Cursor;
82
+ /**
83
+ * Whether there are more results available after this page
84
+ */
85
+ hasNextPage: boolean;
81
86
  }
82
87
 
83
88
  /**
@@ -203,12 +208,16 @@ export function createCursorFromRecord(
203
208
  /**
204
209
  * Serialize cursor values for database queries
205
210
  *
206
- * Converts cursor values (which are in application format) to database format
207
- * using the column serialization rules.
211
+ * Converts cursor values (which are in JSON-compatible format after decode)
212
+ * to database format using the column serialization rules.
213
+ *
214
+ * This function performs a two-step process:
215
+ * 1. Deserialize from JSON format to application format (e.g., ISO string → Date)
216
+ * 2. Serialize from application format to database format (e.g., Date → driver format)
208
217
  *
209
218
  * @param cursor - The cursor object
210
219
  * @param indexColumns - The columns that make up the index
211
- * @param provider - The SQL provider
220
+ * @param driverConfig - The driver configuration
212
221
  * @returns Serialized values ready for database queries
213
222
  *
214
223
  * @example
@@ -216,21 +225,29 @@ export function createCursorFromRecord(
216
225
  * const serialized = serializeCursorValues(
217
226
  * cursor,
218
227
  * [table.columns.createdAt],
219
- * "postgresql"
228
+ * driverConfig
220
229
  * );
221
230
  * ```
222
231
  */
223
232
  export function serializeCursorValues(
224
233
  cursor: Cursor,
225
234
  indexColumns: AnyColumn[],
226
- provider: SQLProvider,
235
+ driverConfig: DriverConfig,
227
236
  ): Record<string, unknown> {
237
+ const serializer = createSQLSerializer(driverConfig);
228
238
  const serialized: Record<string, unknown> = {};
229
239
 
230
240
  for (const col of indexColumns) {
231
241
  const value = cursor.indexValues[col.ormName];
232
242
  if (value !== undefined) {
233
- serialized[col.ormName] = serialize(value, col, provider);
243
+ // First deserialize from JSON format to application format
244
+ // (e.g., "2025-11-07T09:36:57.959Z" string → Date object)
245
+ const deserialized = serializer.deserialize(value, col);
246
+ // Resolve FragnoId/FragnoReference to primitive values (if present)
247
+ const resolved = resolveFragnoIdValue(deserialized, col);
248
+ // Then serialize to database format
249
+ // (e.g., Date → database driver format)
250
+ serialized[col.ormName] = serializer.serialize(resolved, col);
234
251
  }
235
252
  }
236
253
 
@@ -4,7 +4,7 @@ import type {
4
4
  FindManyOptions,
5
5
  JoinBuilder,
6
6
  OrderBy,
7
- } from "../query";
7
+ } from "../simple-query-interface";
8
8
  import { buildCondition, type Condition } from "../condition-builder";
9
9
  import type { AnyColumn, AnyRelation, AnyTable } from "../../schema/create";
10
10
 
@@ -1,14 +1,14 @@
1
1
  import { describe, expectTypeOf, it } from "vitest";
2
2
  import { column, FragnoId, idColumn, referenceColumn, schema } from "../schema/create";
3
3
  import type {
4
- AbstractQuery,
4
+ SimpleQueryInterface,
5
5
  FindFirstOptions,
6
6
  FindManyOptions,
7
7
  JoinBuilder,
8
8
  OrderBy,
9
9
  SelectClause,
10
10
  TableToInsertValues,
11
- } from "./query";
11
+ } from "./simple-query-interface";
12
12
  import type { ConditionBuilder } from "./condition-builder";
13
13
 
14
14
  describe("query type tests", () => {
@@ -91,8 +91,8 @@ describe("query type tests", () => {
91
91
  });
92
92
  });
93
93
 
94
- describe("AbstractQuery methods", () => {
95
- type Query = AbstractQuery<TestSchema>;
94
+ describe("SimpleQueryInterface methods", () => {
95
+ type Query = SimpleQueryInterface<TestSchema>;
96
96
 
97
97
  describe("findFirst", () => {
98
98
  it("should return all columns when select is true or undefined", () => {
@@ -257,7 +257,7 @@ describe("query type tests", () => {
257
257
 
258
258
  describe("table name type checking", () => {
259
259
  it("should only allow valid table names", () => {
260
- const _query = {} as AbstractQuery<TestSchema>;
260
+ const _query = {} as SimpleQueryInterface<TestSchema>;
261
261
 
262
262
  // Valid table names
263
263
  type UsersParam = Parameters<typeof _query.find<"users">>;
@@ -272,7 +272,7 @@ describe("query type tests", () => {
272
272
 
273
273
  describe("column type inference", () => {
274
274
  it("should correctly infer column types for users table", () => {
275
- const _query = {} as AbstractQuery<TestSchema>;
275
+ const _query = {} as SimpleQueryInterface<TestSchema>;
276
276
  type Result = Awaited<ReturnType<typeof _query.findFirst<"users">>>;
277
277
  type User = Exclude<Result, null>;
278
278
 
@@ -284,7 +284,7 @@ describe("query type tests", () => {
284
284
  });
285
285
 
286
286
  it("should correctly infer column types for posts table", () => {
287
- const _query = {} as AbstractQuery<TestSchema>;
287
+ const _query = {} as SimpleQueryInterface<TestSchema>;
288
288
  type Result = Awaited<ReturnType<typeof _query.findFirst<"posts">>>;
289
289
  type Post = Exclude<Result, null>;
290
290
 
@@ -297,7 +297,7 @@ describe("query type tests", () => {
297
297
  });
298
298
 
299
299
  it("should correctly infer column types for comments table", () => {
300
- const _query = {} as AbstractQuery<TestSchema>;
300
+ const _query = {} as SimpleQueryInterface<TestSchema>;
301
301
  type Result = Awaited<ReturnType<typeof _query.findFirst<"comments">>>;
302
302
  type Comment = Exclude<Result, null>;
303
303
 
@@ -311,7 +311,7 @@ describe("query type tests", () => {
311
311
 
312
312
  describe("complex scenarios", () => {
313
313
  it("should handle multiple table operations with correct types", () => {
314
- const _query = {} as AbstractQuery<TestSchema>;
314
+ const _query = {} as SimpleQueryInterface<TestSchema>;
315
315
 
316
316
  // Create user return type
317
317
  type UserResult = Awaited<ReturnType<typeof _query.create<"users">>>;
@@ -0,0 +1,34 @@
1
+ import type { DriverConfig } from "../../adapters/generic-sql/driver-config";
2
+ import { SQLSerializer } from "./sql-serializer";
3
+ import { SQLiteSerializer } from "./dialect/sqlite-serializer";
4
+ import { PostgreSQLSerializer } from "./dialect/postgres-serializer";
5
+ import { MySQLSerializer } from "./dialect/mysql-serializer";
6
+
7
+ // Re-export SQLSerializer for convenience
8
+ export { SQLSerializer } from "./sql-serializer";
9
+
10
+ /**
11
+ * Factory function to create a dialect-specific SQL serializer from a DriverConfig.
12
+ *
13
+ * Based on the database type, returns the appropriate serializer implementation
14
+ * (PostgreSQL, MySQL, or SQLite).
15
+ *
16
+ * @param driverConfig - The driver configuration
17
+ * @returns Dialect-specific SQLSerializer instance
18
+ */
19
+ export function createSQLSerializer(driverConfig: DriverConfig): SQLSerializer {
20
+ // TODO: The serializers are pretty lenient in what they accept (lost of typeof checks), it may
21
+ // be beneficial to implement serializers per DriverConfig, and be less lenient.
22
+ switch (driverConfig.databaseType) {
23
+ case "postgresql":
24
+ return new PostgreSQLSerializer(driverConfig);
25
+ case "mysql":
26
+ return new MySQLSerializer(driverConfig);
27
+ case "sqlite":
28
+ return new SQLiteSerializer(driverConfig);
29
+ default: {
30
+ const exhaustiveCheck: never = driverConfig.databaseType;
31
+ throw new Error(`Unsupported database type: ${exhaustiveCheck}`);
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,142 @@
1
+ import type { AnyColumn } from "../../../schema/create";
2
+ import { SQLSerializer } from "../sql-serializer";
3
+ import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
4
+
5
+ /**
6
+ * MySQL-specific serializer.
7
+ *
8
+ * MySQL has good native type support:
9
+ * - Native JSON support (MySQL 5.7+)
10
+ * - Native boolean type (TINYINT(1))
11
+ * - Native timestamp/datetime/date types
12
+ * - Native bigint support
13
+ *
14
+ * Similar to PostgreSQL, most values pass through without conversion.
15
+ * Timestamps/dates are returned as strings and need to be parsed.
16
+ */
17
+ export class MySQLSerializer extends SQLSerializer {
18
+ constructor(driverConfig: DriverConfig) {
19
+ super(driverConfig);
20
+ }
21
+
22
+ protected serializeDate(value: Date): Date {
23
+ // MySQL handles Date objects natively
24
+ return value;
25
+ }
26
+
27
+ protected serializeBoolean(value: boolean): boolean {
28
+ // MySQL handles boolean natively (as TINYINT(1))
29
+ return value;
30
+ }
31
+
32
+ protected serializeBigInt(value: bigint, _col: AnyColumn): bigint {
33
+ // MySQL handles bigint natively
34
+ return value;
35
+ }
36
+
37
+ protected deserializeDate(value: unknown): Date {
38
+ if (value instanceof Date) {
39
+ return value;
40
+ }
41
+ // MySQL returns timestamps/dates as strings
42
+ if (typeof value === "string") {
43
+ return new Date(value);
44
+ }
45
+ throw new Error(`Cannot deserialize date from value: ${value}`);
46
+ }
47
+
48
+ protected deserializeBoolean(value: unknown): boolean {
49
+ if (typeof value === "boolean") {
50
+ return value;
51
+ }
52
+ // MySQL may return booleans as numbers (0/1)
53
+ if (typeof value === "number") {
54
+ return value === 1;
55
+ }
56
+ throw new Error(`Cannot deserialize boolean from value: ${value}`);
57
+ }
58
+
59
+ protected deserializeBigInt(value: unknown): bigint {
60
+ if (typeof value === "bigint") {
61
+ return value;
62
+ }
63
+ // MySQL may return bigints as strings
64
+ if (typeof value === "string") {
65
+ return BigInt(value);
66
+ }
67
+ if (typeof value === "number") {
68
+ return BigInt(value);
69
+ }
70
+ throw new Error(`Cannot deserialize bigint from value: ${value}`);
71
+ }
72
+
73
+ protected serializeJson(value: unknown): unknown {
74
+ // MySQL supports native JSON, pass through as-is
75
+ return value;
76
+ }
77
+
78
+ protected deserializeJson(value: unknown): unknown {
79
+ // MySQL returns parsed JSON objects, pass through as-is
80
+ return value;
81
+ }
82
+
83
+ protected deserializeBinary(value: unknown): Uint8Array {
84
+ // MySQL can return Buffer or Uint8Array for BLOB columns
85
+ if (value instanceof Buffer) {
86
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
87
+ }
88
+ if (value instanceof Uint8Array) {
89
+ return value;
90
+ }
91
+ if (value instanceof ArrayBuffer) {
92
+ return new Uint8Array(value);
93
+ }
94
+ throw new Error(`Cannot deserialize binary from value: ${typeof value}`);
95
+ }
96
+
97
+ protected deserializeInteger(value: unknown): number {
98
+ if (typeof value === "number") {
99
+ return value;
100
+ }
101
+ // MySQL may return integers as strings
102
+ if (typeof value === "string") {
103
+ const num = Number(value);
104
+ if (isNaN(num)) {
105
+ throw new Error(`Cannot deserialize integer from invalid string: ${value}`);
106
+ }
107
+ return num;
108
+ }
109
+ // MySQL may return bigint for large integers
110
+ if (typeof value === "bigint") {
111
+ if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
112
+ throw new RangeError(
113
+ `Cannot deserialize integer value ${value}: exceeds safe integer range`,
114
+ );
115
+ }
116
+ return Number(value);
117
+ }
118
+ throw new Error(`Cannot deserialize integer from value: ${typeof value}`);
119
+ }
120
+
121
+ protected deserializeDecimal(value: unknown): number {
122
+ // MySQL can return decimals as numbers or strings
123
+ if (typeof value === "number") {
124
+ return value;
125
+ }
126
+ if (typeof value === "string") {
127
+ const num = parseFloat(value);
128
+ if (isNaN(num)) {
129
+ throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
130
+ }
131
+ return num;
132
+ }
133
+ throw new Error(`Cannot deserialize decimal from value: ${typeof value}`);
134
+ }
135
+
136
+ protected deserializeString(value: unknown): string {
137
+ if (typeof value === "string") {
138
+ return value;
139
+ }
140
+ throw new Error(`Cannot deserialize string from value: ${typeof value}`);
141
+ }
142
+ }
@@ -0,0 +1,129 @@
1
+ import type { AnyColumn } from "../../../schema/create";
2
+ import { SQLSerializer } from "../sql-serializer";
3
+ import type { DriverConfig } from "../../../adapters/generic-sql/driver-config";
4
+
5
+ /**
6
+ * PostgreSQL-specific serializer.
7
+ *
8
+ * PostgreSQL has excellent native type support:
9
+ * - Native JSON support
10
+ * - Native boolean type
11
+ * - Native timestamp/date types
12
+ * - Native bigint support
13
+ *
14
+ * Most values pass through without conversion, only strings need to be parsed to Date.
15
+ */
16
+ export class PostgreSQLSerializer extends SQLSerializer {
17
+ constructor(driverConfig: DriverConfig) {
18
+ super(driverConfig);
19
+ }
20
+
21
+ protected serializeDate(value: Date): Date {
22
+ // PostgreSQL handles Date objects natively
23
+ return value;
24
+ }
25
+
26
+ protected serializeBoolean(value: boolean): boolean {
27
+ // PostgreSQL handles boolean natively
28
+ return value;
29
+ }
30
+
31
+ protected serializeBigInt(value: bigint, _col: AnyColumn): bigint {
32
+ // PostgreSQL handles bigint natively
33
+ return value;
34
+ }
35
+
36
+ protected deserializeDate(value: unknown): Date {
37
+ if (value instanceof Date) {
38
+ return value;
39
+ }
40
+ // PostgreSQL returns timestamps/dates as strings
41
+ if (typeof value === "string") {
42
+ return new Date(value);
43
+ }
44
+ throw new Error(`Cannot deserialize date from value: ${value}`);
45
+ }
46
+
47
+ protected deserializeBoolean(value: unknown): boolean {
48
+ if (typeof value === "boolean") {
49
+ return value;
50
+ }
51
+ throw new Error(`Cannot deserialize boolean from value: ${value}`);
52
+ }
53
+
54
+ protected deserializeBigInt(value: unknown): bigint {
55
+ if (typeof value === "bigint") {
56
+ return value;
57
+ }
58
+ // PostgreSQL may return bigints as strings
59
+ if (typeof value === "string") {
60
+ return BigInt(value);
61
+ }
62
+ if (typeof value === "number") {
63
+ return BigInt(value);
64
+ }
65
+ throw new Error(`Cannot deserialize bigint from value: ${value}`);
66
+ }
67
+
68
+ protected serializeJson(value: unknown): unknown {
69
+ // PostgreSQL supports native JSON, pass through as-is
70
+ return value;
71
+ }
72
+
73
+ protected deserializeJson(value: unknown): unknown {
74
+ // PostgreSQL returns parsed JSON objects, pass through as-is
75
+ return value;
76
+ }
77
+
78
+ protected deserializeBinary(value: unknown): Uint8Array {
79
+ // PostgreSQL can return Buffer or Uint8Array for BYTEA columns
80
+ if (value instanceof Buffer) {
81
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
82
+ }
83
+ if (value instanceof Uint8Array) {
84
+ return value;
85
+ }
86
+ if (value instanceof ArrayBuffer) {
87
+ return new Uint8Array(value);
88
+ }
89
+ throw new Error(`Cannot deserialize binary from value: ${typeof value}`);
90
+ }
91
+
92
+ protected deserializeInteger(value: unknown): number {
93
+ if (typeof value === "number") {
94
+ return value;
95
+ }
96
+ // PostgreSQL may return bigint for large integers
97
+ if (typeof value === "bigint") {
98
+ if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
99
+ throw new RangeError(
100
+ `Cannot deserialize integer value ${value}: exceeds safe integer range`,
101
+ );
102
+ }
103
+ return Number(value);
104
+ }
105
+ throw new Error(`Cannot deserialize integer from value: ${typeof value}`);
106
+ }
107
+
108
+ protected deserializeDecimal(value: unknown): number {
109
+ // PostgreSQL can return decimals as numbers or strings depending on precision
110
+ if (typeof value === "number") {
111
+ return value;
112
+ }
113
+ if (typeof value === "string") {
114
+ const num = parseFloat(value);
115
+ if (isNaN(num)) {
116
+ throw new Error(`Cannot deserialize decimal from invalid string: ${value}`);
117
+ }
118
+ return num;
119
+ }
120
+ throw new Error(`Cannot deserialize decimal from value: ${typeof value}`);
121
+ }
122
+
123
+ protected deserializeString(value: unknown): string {
124
+ if (typeof value === "string") {
125
+ return value;
126
+ }
127
+ throw new Error(`Cannot deserialize string from value: ${typeof value}`);
128
+ }
129
+ }