@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,15 +1,16 @@
1
1
  import type { FragnoDatabase } from "../mod";
2
2
  import type { AnySchema } from "../schema/create";
3
- import type { PreparedMigration } from "./create";
4
- import {
5
- settingsSchema,
6
- SETTINGS_NAMESPACE,
7
- createSettingsManager,
8
- } from "../shared/settings-schema";
9
3
  import {
10
4
  fragnoDatabaseAdapterNameFakeSymbol,
11
5
  fragnoDatabaseAdapterVersionFakeSymbol,
12
6
  } from "../adapters/adapters";
7
+ import {
8
+ internalFragmentDef,
9
+ internalSchema,
10
+ SETTINGS_NAMESPACE,
11
+ getSchemaVersionFromDatabase,
12
+ } from "../fragments/internal-fragment";
13
+ import { instantiate } from "@fragno-dev/core";
13
14
 
14
15
  export interface GenerationEngineResult {
15
16
  schema: string;
@@ -23,7 +24,6 @@ export interface GenerationInternalResult {
23
24
  namespace: string;
24
25
  fromVersion: number;
25
26
  toVersion: number;
26
- preparedMigration?: PreparedMigration;
27
27
  }
28
28
 
29
29
  export interface ExecuteMigrationResult {
@@ -59,12 +59,30 @@ export async function generateMigrationsOrSchema<
59
59
  );
60
60
  }
61
61
 
62
- const fragments = databases.map((db) => ({
63
- schema: db.schema,
64
- namespace: db.namespace,
65
- }));
62
+ // Collect all schemas, de-duplicating by namespace.
63
+ // The internal fragment (settings schema) is always included first since all database
64
+ // fragments automatically link to it via withDatabase().
65
+ const fragmentsMap = new Map<string, { schema: AnySchema; namespace: string }>();
66
+
67
+ // Include internal fragment first with empty namespace (settings table has no prefix)
68
+ fragmentsMap.set("", {
69
+ schema: internalSchema,
70
+ namespace: "",
71
+ });
72
+
73
+ // Add user fragments, de-duplicating by namespace
74
+ // Each FragnoDatabase has a unique namespace, so this prevents duplicate schema generation
75
+ for (const db of databases) {
76
+ if (!fragmentsMap.has(db.namespace)) {
77
+ fragmentsMap.set(db.namespace, {
78
+ schema: db.schema,
79
+ namespace: db.namespace,
80
+ });
81
+ }
82
+ }
66
83
 
67
- const generator = adapter.createSchemaGenerator(fragments, {
84
+ const allFragments = Array.from(fragmentsMap.values());
85
+ const generator = adapter.createSchemaGenerator(allFragments, {
68
86
  path: options?.path,
69
87
  });
70
88
 
@@ -76,10 +94,10 @@ export async function generateMigrationsOrSchema<
76
94
  ];
77
95
  }
78
96
 
79
- // Otherwise, use migration engine for individual generation (e.g., Kysely)
80
- if (!adapter.createMigrationEngine) {
97
+ // Otherwise, use migration engine for individual generation (e.g., Kysely, GenericSQL)
98
+ if (!adapter.prepareMigrations) {
81
99
  throw new Error(
82
- "Adapter does not support migration-based schema generation. Ensure your adapter implements createMigrationEngine.",
100
+ "Adapter does not support migration-based schema generation. Ensure your adapter implements prepareMigrations.",
83
101
  );
84
102
  }
85
103
 
@@ -89,49 +107,36 @@ export async function generateMigrationsOrSchema<
89
107
  );
90
108
  }
91
109
 
92
- const settingsQueryEngine = adapter.createQueryEngine(settingsSchema, "");
93
- const settingsManager = createSettingsManager(settingsQueryEngine, SETTINGS_NAMESPACE);
110
+ // Use the internal fragment for settings management
111
+ const internalFragment = instantiate(internalFragmentDef)
112
+ .withConfig({})
113
+ .withOptions({ databaseAdapter: adapter })
114
+ .build();
94
115
 
95
- let settingsSourceVersion: number;
96
- try {
97
- const result = await settingsManager.get("version");
98
-
99
- if (!result) {
100
- settingsSourceVersion = 0;
101
- } else {
102
- settingsSourceVersion = parseInt(result.value);
103
- }
104
- } catch {
105
- // We don't really have a way to verify this error happens because the key doesn't exist in the database
106
- settingsSourceVersion = 0;
107
- }
116
+ const settingsSourceVersion = await getSchemaVersionFromDatabase(
117
+ internalFragment,
118
+ SETTINGS_NAMESPACE,
119
+ );
108
120
 
109
121
  const generatedFiles: GenerationInternalResult[] = [];
110
122
 
111
- const settingsMigrator = adapter.createMigrationEngine(settingsSchema, SETTINGS_NAMESPACE);
112
- const settingsTargetVersion = settingsSchema.version;
123
+ // Use empty namespace for settings (SETTINGS_NAMESPACE is for prefixing keys, not the database namespace)
124
+ const settingsPreparedMigrations = adapter.prepareMigrations(internalSchema, "");
125
+ const settingsTargetVersion = internalSchema.version;
113
126
 
114
127
  // Generate settings table migration
115
- const settingsMigration = await settingsMigrator.prepareMigrationTo(settingsTargetVersion, {
116
- fromVersion: settingsSourceVersion,
117
- });
118
-
119
- if (!settingsMigration.getSQL) {
120
- throw new Error(
121
- "Migration engine does not support SQL generation. Ensure your adapter's migration engine provides getSQL().",
122
- );
123
- }
124
-
125
- const settingsSql = settingsMigration.getSQL();
128
+ const settingsSql = settingsPreparedMigrations.getSQL(
129
+ settingsSourceVersion,
130
+ settingsTargetVersion,
131
+ );
126
132
 
127
133
  if (settingsSql.trim()) {
128
134
  generatedFiles.push({
129
135
  schema: settingsSql,
130
136
  path: "settings-migration.sql", // Placeholder, will be renamed in post-processing
131
- namespace: SETTINGS_NAMESPACE,
137
+ namespace: "", // Empty namespace for settings table
132
138
  fromVersion: settingsSourceVersion,
133
139
  toVersion: settingsTargetVersion,
134
- preparedMigration: settingsMigration,
135
140
  });
136
141
  }
137
142
 
@@ -140,29 +145,19 @@ export async function generateMigrationsOrSchema<
140
145
  const dbAdapter = db.adapter;
141
146
 
142
147
  // Use migration engine
143
- if (!dbAdapter.createMigrationEngine) {
148
+ if (!dbAdapter.prepareMigrations) {
144
149
  throw new Error(
145
150
  `Adapter for ${db.namespace} does not support schema generation. ` +
146
- `Ensure your adapter implements either createSchemaGenerator or createMigrationEngine.`,
151
+ `Ensure your adapter implements either createSchemaGenerator or prepareMigrations.`,
147
152
  );
148
153
  }
149
154
 
150
- const migrator = dbAdapter.createMigrationEngine(db.schema, db.namespace);
155
+ const preparedMigrations = dbAdapter.prepareMigrations(db.schema, db.namespace);
151
156
  const targetVersion = options?.toVersion ?? db.schema.version;
152
157
  const sourceVersion = options?.fromVersion ?? 0;
153
158
 
154
159
  // Generate migration from source to target version
155
- const preparedMigration = await migrator.prepareMigrationTo(targetVersion, {
156
- fromVersion: sourceVersion,
157
- });
158
-
159
- if (!preparedMigration.getSQL) {
160
- throw new Error(
161
- "Migration engine does not support SQL generation. Ensure your adapter's migration engine provides getSQL().",
162
- );
163
- }
164
-
165
- const sql = preparedMigration.getSQL();
160
+ const sql = preparedMigrations.getSQL(sourceVersion, targetVersion);
166
161
 
167
162
  // If no migrations needed, skip this fragment
168
163
  if (sql.trim()) {
@@ -172,7 +167,6 @@ export async function generateMigrationsOrSchema<
172
167
  namespace: db.namespace,
173
168
  fromVersion: sourceVersion,
174
169
  toVersion: targetVersion,
175
- preparedMigration: preparedMigration,
176
170
  });
177
171
  }
178
172
  }
@@ -199,7 +193,7 @@ export async function executeMigrations<const TDatabases extends FragnoDatabase<
199
193
  const adapter = firstDb.adapter;
200
194
 
201
195
  // Validate adapter supports migrations
202
- if (!adapter.createMigrationEngine) {
196
+ if (!adapter.prepareMigrations) {
203
197
  throw new Error(
204
198
  "Adapter does not support running migrations. The adapter only supports schema generation.\n" +
205
199
  "Try using 'generateMigrationsOrSchema' instead to generate schema files.",
@@ -233,36 +227,41 @@ export async function executeMigrations<const TDatabases extends FragnoDatabase<
233
227
  namespace: string;
234
228
  fromVersion: number;
235
229
  toVersion: number;
236
- preparedMigration: PreparedMigration;
230
+ execute: () => Promise<void>;
237
231
  }> = [];
238
232
 
239
233
  // 1. Prepare settings table migration
240
- const settingsQueryEngine = adapter.createQueryEngine(settingsSchema, "");
241
- const settingsManager = createSettingsManager(settingsQueryEngine, SETTINGS_NAMESPACE);
242
-
243
- let settingsSourceVersion: number;
244
- try {
245
- const result = await settingsManager.get("version");
246
- settingsSourceVersion = result ? parseInt(result.value) : 0;
247
- } catch {
248
- settingsSourceVersion = 0;
249
- }
234
+ // Use the internal fragment for settings management
235
+ const internalFragment = instantiate(internalFragmentDef)
236
+ .withConfig({})
237
+ .withOptions({ databaseAdapter: adapter })
238
+ .build();
250
239
 
251
- const settingsMigrator = adapter.createMigrationEngine(settingsSchema, SETTINGS_NAMESPACE);
252
- const settingsTargetVersion = settingsSchema.version;
240
+ const settingsSourceVersion = await getSchemaVersionFromDatabase(
241
+ internalFragment,
242
+ SETTINGS_NAMESPACE,
243
+ );
244
+
245
+ // Use empty namespace for settings (SETTINGS_NAMESPACE is for prefixing keys, not the database namespace)
246
+ const settingsPreparedMigrations = adapter.prepareMigrations(internalSchema, "");
247
+ const settingsTargetVersion = internalSchema.version;
253
248
 
254
249
  if (settingsSourceVersion < settingsTargetVersion) {
255
- const settingsMigration = await settingsMigrator.prepareMigrationTo(settingsTargetVersion, {
256
- fromVersion: settingsSourceVersion,
257
- updateSettings: true,
258
- });
250
+ const compiledMigration = settingsPreparedMigrations.compile(
251
+ settingsSourceVersion,
252
+ settingsTargetVersion,
253
+ { updateVersionInMigration: true },
254
+ );
259
255
 
260
- if (settingsMigration.operations.length > 0) {
256
+ if (compiledMigration.statements.length > 0) {
261
257
  migrationsToExecute.push({
262
- namespace: SETTINGS_NAMESPACE,
258
+ namespace: "", // Empty namespace for settings table
263
259
  fromVersion: settingsSourceVersion,
264
260
  toVersion: settingsTargetVersion,
265
- preparedMigration: settingsMigration,
261
+ execute: () =>
262
+ settingsPreparedMigrations.execute(settingsSourceVersion, settingsTargetVersion, {
263
+ updateVersionInMigration: true,
264
+ }),
266
265
  });
267
266
  }
268
267
  }
@@ -271,21 +270,24 @@ export async function executeMigrations<const TDatabases extends FragnoDatabase<
271
270
  const sortedDatabases = [...databases].sort((a, b) => a.namespace.localeCompare(b.namespace));
272
271
 
273
272
  for (const fragnoDb of sortedDatabases) {
274
- const migrator = adapter.createMigrationEngine(fragnoDb.schema, fragnoDb.namespace);
275
- const currentVersion = await migrator.getVersion();
273
+ const preparedMigrations = adapter.prepareMigrations(fragnoDb.schema, fragnoDb.namespace);
274
+ const currentVersion = await getSchemaVersionFromDatabase(internalFragment, fragnoDb.namespace);
276
275
  const targetVersion = fragnoDb.schema.version;
277
276
 
278
277
  if (currentVersion < targetVersion) {
279
- const preparedMigration = await migrator.prepareMigrationTo(targetVersion, {
280
- updateSettings: true,
278
+ const compiledMigration = preparedMigrations.compile(currentVersion, targetVersion, {
279
+ updateVersionInMigration: true,
281
280
  });
282
281
 
283
- if (preparedMigration.operations.length > 0) {
282
+ if (compiledMigration.statements.length > 0) {
284
283
  migrationsToExecute.push({
285
284
  namespace: fragnoDb.namespace,
286
285
  fromVersion: currentVersion,
287
286
  toVersion: targetVersion,
288
- preparedMigration: preparedMigration,
287
+ execute: () =>
288
+ preparedMigrations.execute(currentVersion, targetVersion, {
289
+ updateVersionInMigration: true,
290
+ }),
289
291
  });
290
292
  }
291
293
  }
@@ -293,7 +295,7 @@ export async function executeMigrations<const TDatabases extends FragnoDatabase<
293
295
 
294
296
  // 3. Execute all migrations in order
295
297
  for (const migration of migrationsToExecute) {
296
- await migration.preparedMigration.execute();
298
+ await migration.execute();
297
299
  results.push({
298
300
  namespace: migration.namespace,
299
301
  didMigrate: true,
@@ -334,12 +336,13 @@ export function postProcessMigrationFilenames(
334
336
  return [];
335
337
  }
336
338
 
337
- // Sort files: settings namespace first, then alphabetically by namespace
339
+ // Sort files: settings namespace first (empty string), then alphabetically by namespace
338
340
  const sortedFiles = [...files].sort((a, b) => {
339
- if (a.namespace === SETTINGS_NAMESPACE) {
341
+ // Settings table has empty namespace - sort it first
342
+ if (a.namespace === "") {
340
343
  return -1;
341
344
  }
342
- if (b.namespace === SETTINGS_NAMESPACE) {
345
+ if (b.namespace === "") {
343
346
  return 1;
344
347
  }
345
348
  return a.namespace.localeCompare(b.namespace);
@@ -357,7 +360,11 @@ export function postProcessMigrationFilenames(
357
360
  const orderNum = (index + 1).toString().padStart(3, "0");
358
361
  const fromPadded = fromVersion.toString().padStart(3, "0");
359
362
  const toPadded = toVersion.toString().padStart(3, "0");
360
- const safeName = file.namespace.replace(/[^a-z0-9-]/gi, "_");
363
+
364
+ // For settings table (empty namespace), use "fragno_db_settings" in the filename
365
+ // For other tables, use their namespace
366
+ const safeName =
367
+ file.namespace === "" ? "fragno_db_settings" : file.namespace.replace(/[^a-z0-9-]/gi, "_");
361
368
  const newPath = `${date}_${orderNum}_f${fromPadded}_t${toPadded}_${safeName}.sql`;
362
369
 
363
370
  return {
package/src/mod.ts CHANGED
@@ -1,8 +1,16 @@
1
1
  import type { DatabaseAdapter } from "./adapters/adapters";
2
2
  import type { AnySchema } from "./schema/create";
3
- import type { AbstractQuery } from "./query/query";
4
3
  import type { CursorResult } from "./query/cursor";
5
4
  import { Cursor } from "./query/cursor";
5
+ import type { FragnoInstantiatedFragment, AnyFragnoInstantiatedFragment } from "@fragno-dev/core";
6
+ import type {
7
+ FragnoPublicConfigWithDatabase,
8
+ ImplicitDatabaseDependencies,
9
+ } from "./db-fragment-definition-builder";
10
+ import {
11
+ getSchemaVersionFromDatabase,
12
+ type InternalFragmentInstance,
13
+ } from "./fragments/internal-fragment";
6
14
 
7
15
  export type { DatabaseAdapter, CursorResult };
8
16
  export { Cursor };
@@ -30,40 +38,6 @@ export function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySch
30
38
  );
31
39
  }
32
40
 
33
- /**
34
- * Definition of a Fragno database schema and namespace.
35
- * Created by library authors using defineFragnoDatabase().
36
- * Apps instantiate it by calling .create(adapter).
37
- */
38
- export class FragnoDatabaseDefinition<const T extends AnySchema> {
39
- #namespace: string;
40
- #schema: T;
41
-
42
- constructor(options: CreateFragnoDatabaseDefinitionOptions<T>) {
43
- this.#namespace = options.namespace;
44
- this.#schema = options.schema;
45
- }
46
-
47
- get namespace() {
48
- return this.#namespace;
49
- }
50
-
51
- get schema() {
52
- return this.#schema;
53
- }
54
-
55
- /**
56
- * Creates a FragnoDatabase instance by binding an adapter to this definition.
57
- */
58
- create<TUOWConfig = void>(adapter: DatabaseAdapter<TUOWConfig>): FragnoDatabase<T, TUOWConfig> {
59
- return new FragnoDatabase({
60
- namespace: this.#namespace,
61
- schema: this.#schema,
62
- adapter,
63
- });
64
- }
65
- }
66
-
67
41
  /**
68
42
  * A Fragno database instance with a bound adapter.
69
43
  * Created from a FragnoDatabaseDefinition by calling .create(adapter).
@@ -83,30 +57,6 @@ export class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {
83
57
  return fragnoDatabaseFakeSymbol;
84
58
  }
85
59
 
86
- async createClient(): Promise<AbstractQuery<T, TUOWConfig>> {
87
- const dbVersion = await this.#adapter.getSchemaVersion(this.#namespace);
88
- if (dbVersion !== this.#schema.version.toString()) {
89
- throw new Error(
90
- `Database is not at expected version. Did you forget to run migrations?` +
91
- ` Current version: ${dbVersion}, Expected version: ${this.#schema.version}`,
92
- );
93
- }
94
-
95
- return this.#adapter.createQueryEngine(this.#schema, this.#namespace);
96
- }
97
-
98
- async runMigrations(): Promise<boolean> {
99
- if (!this.#adapter.createMigrationEngine) {
100
- throw new Error("Migration engine not supported for this adapter.");
101
- }
102
-
103
- const migrator = this.#adapter.createMigrationEngine(this.#schema, this.#namespace);
104
- const preparedMigration = await migrator.prepareMigration();
105
- await preparedMigration.execute();
106
-
107
- return preparedMigration.operations.length > 0;
108
- }
109
-
110
60
  get namespace() {
111
61
  return this.#namespace;
112
62
  }
@@ -120,36 +70,147 @@ export class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {
120
70
  }
121
71
  }
122
72
 
123
- export function defineFragnoDatabase<const TSchema extends AnySchema>(
124
- options: CreateFragnoDatabaseDefinitionOptions<TSchema>,
125
- ): FragnoDatabaseDefinition<TSchema> {
126
- return new FragnoDatabaseDefinition(options);
127
- }
128
-
129
73
  export {
130
- defineFragmentWithDatabase,
131
- DatabaseFragmentBuilder,
74
+ DatabaseFragmentDefinitionBuilder,
132
75
  type FragnoPublicConfigWithDatabase,
133
76
  type DatabaseFragmentContext,
134
- type DatabaseRouteHandler,
135
- } from "./fragment";
77
+ type DatabaseHandlerContext as DatabaseRequestContext,
78
+ type ImplicitDatabaseDependencies,
79
+ } from "./db-fragment-definition-builder";
80
+
81
+ export { withDatabase } from "./with-database";
136
82
 
137
83
  export { decodeCursor, type CursorData } from "./query/cursor";
138
84
 
139
85
  export {
140
86
  createUnitOfWork,
141
87
  UnitOfWork,
142
- UnitOfWorkSchemaView,
143
- type IUnitOfWorkBase,
88
+ TypedUnitOfWork,
89
+ type IUnitOfWork,
90
+ type IUnitOfWorkRestricted,
144
91
  type UOWCompiler,
145
92
  type UOWExecutor,
146
93
  type UOWDecoder,
147
- } from "./query/unit-of-work";
94
+ } from "./query/unit-of-work/unit-of-work";
95
+
96
+ export {
97
+ type RetryPolicy,
98
+ NoRetryPolicy,
99
+ ExponentialBackoffRetryPolicy,
100
+ LinearBackoffRetryPolicy,
101
+ } from "./query/unit-of-work/retry-policy";
148
102
 
149
103
  export {
150
- withUnitOfWork,
151
- serviceContext,
152
- uowStorage,
153
- type DatabaseRequestThisContext,
154
- } from "./fragment";
155
- export { type BoundServices } from "./bind-services";
104
+ executeUnitOfWork,
105
+ type ExecuteUnitOfWorkResult,
106
+ type ExecuteUnitOfWorkCallbacks,
107
+ type ExecuteUnitOfWorkOptions,
108
+ } from "./query/unit-of-work/execute-unit-of-work";
109
+
110
+ export type { BoundServices } from "@fragno-dev/core";
111
+
112
+ export { internalFragmentDef } from "./fragments/internal-fragment";
113
+ export type { InternalFragmentInstance } from "./fragments/internal-fragment";
114
+
115
+ export type { HookContext, HooksMap, HookFn, HookPayload, TriggerHookOptions } from "./hooks/hooks";
116
+
117
+ export type AnyFragnoInstantiatedDatabaseFragment = FragnoInstantiatedFragment<
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
119
+ any,
120
+ ImplicitDatabaseDependencies<AnySchema>,
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
+ any,
123
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
124
+ any,
125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
+ any,
127
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
+ any,
129
+ FragnoPublicConfigWithDatabase,
130
+ // Ensure the fragment has the internal fragment linked
131
+ { _fragno_internal: InternalFragmentInstance } & Record<string, AnyFragnoInstantiatedFragment>
132
+ >;
133
+
134
+ /**
135
+ * Helper function to run migrations for a database fragment.
136
+ * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.
137
+ * This function:
138
+ * 1. Ensures the internal settings fragment is migrated first
139
+ * 2. Retrieves the current database version from the internal fragment
140
+ * 3. Runs migration from current version to target version
141
+ *
142
+ * @param fragment - The instantiated fragment to run migrations for
143
+ * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const fragment = instantiate(myFragmentDef)
148
+ * .withConfig({})
149
+ * .withRoutes([])
150
+ * .withOptions({ databaseAdapter: myAdapter })
151
+ * .build();
152
+ *
153
+ * await migrate(fragment);
154
+ * ```
155
+ */
156
+ export async function migrate(fragment: AnyFragnoInstantiatedDatabaseFragment): Promise<void> {
157
+ const { options, deps, linkedFragments } = fragment.$internal;
158
+ const adapter = options.databaseAdapter;
159
+
160
+ // Check if adapter supports prepareMigrations
161
+ if (!adapter.prepareMigrations) {
162
+ throw new Error(
163
+ "Database adapter does not support prepareMigrations. Please use an adapter that implements this method.",
164
+ );
165
+ }
166
+
167
+ const schema = deps.schema;
168
+ const namespace = deps.namespace;
169
+
170
+ // Step 1: Ensure the internal fragment (settings table) is migrated first
171
+ const internalFragment = linkedFragments._fragno_internal;
172
+
173
+ if (!internalFragment) {
174
+ throw new Error("Internal fragment not found. Please ensure the internal fragment is linked.");
175
+ }
176
+
177
+ if (!(await adapter.isConnectionHealthy())) {
178
+ throw new Error(
179
+ "Database connection is not healthy. Please check your database connection and try again.",
180
+ );
181
+ }
182
+
183
+ const internalDeps = internalFragment.$internal.deps;
184
+ const internalSchema = internalDeps.schema;
185
+ const internalNamespace = internalDeps.namespace;
186
+
187
+ const internalCurrentVersion = await getSchemaVersionFromDatabase(
188
+ internalFragment,
189
+ internalNamespace,
190
+ );
191
+
192
+ // Migrate internal fragment if needed
193
+ if (internalCurrentVersion < internalSchema.version) {
194
+ const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);
195
+ await internalMigrations.execute(internalCurrentVersion, internalSchema.version);
196
+ }
197
+
198
+ // Step 2: Get current database version for this fragment's namespace
199
+ const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);
200
+
201
+ // Step 3: Run the migration from current version to target version
202
+ const targetVersion = schema.version;
203
+
204
+ if (currentVersion === targetVersion) {
205
+ return;
206
+ }
207
+
208
+ if (currentVersion > targetVersion) {
209
+ throw new Error(
210
+ `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,
211
+ );
212
+ }
213
+
214
+ const migrations = adapter.prepareMigrations(schema, namespace);
215
+ await migrations.execute(currentVersion, targetVersion);
216
+ }
@@ -0,0 +1,49 @@
1
+ import type { AnyColumn } from "../schema/create";
2
+ import { createId } from "../id";
3
+
4
+ /**
5
+ * Generate a runtime default value for a column that has defaultTo$()
6
+ *
7
+ * Only generates values for runtime defaults (defaultTo$), NOT static defaults (defaultTo).
8
+ * Static defaults should be handled by the database via DEFAULT constraints.
9
+ *
10
+ * @param column - The column with a default value configuration
11
+ * @returns The generated default value, or undefined if the column has no runtime default
12
+ *
13
+ * @internal
14
+ */
15
+ export function generateRuntimeDefault(column: AnyColumn): unknown {
16
+ // Check if column has a default value configuration
17
+ if (!column.default) {
18
+ return undefined;
19
+ }
20
+
21
+ // If it's a static default value (defaultTo), return undefined
22
+ // as the database should handle this via DEFAULT constraint
23
+ if ("value" in column.default) {
24
+ return undefined;
25
+ }
26
+
27
+ // If it's a database-level special function (defaultTo(b => b.now())), return undefined
28
+ // as the database should handle this via DEFAULT NOW() or equivalent
29
+ if ("dbSpecial" in column.default) {
30
+ return undefined;
31
+ }
32
+
33
+ // Handle runtime defaults (defaultTo$)
34
+ const runtime = column.default.runtime;
35
+
36
+ if (runtime === "cuid") {
37
+ return createId();
38
+ }
39
+
40
+ if (runtime === "now") {
41
+ return new Date();
42
+ }
43
+
44
+ if (typeof runtime === "function") {
45
+ return runtime();
46
+ }
47
+
48
+ return undefined;
49
+ }