@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
@@ -0,0 +1,543 @@
1
+ import { describe, it, expect, vi, assert } from "vitest";
2
+ import { instantiate, defineFragment } from "@fragno-dev/core";
3
+ import { defineRoutes } from "@fragno-dev/core/route";
4
+ import { withDatabase } from "./with-database";
5
+ import { schema, idColumn, column } from "./schema/create";
6
+ import type { DatabaseAdapter } from "./adapters/adapters";
7
+ import type { SimpleQueryInterface } from "./query/simple-query-interface";
8
+ import { RequestContextStorage } from "@fragno-dev/core/internal/request-context-storage";
9
+ import { z } from "zod";
10
+
11
+ // Create a test schema
12
+ const testSchema = schema((s) => {
13
+ return s.addTable("users", (t) => {
14
+ return t.addColumn("id", idColumn()).addColumn("name", column("string"));
15
+ });
16
+ });
17
+
18
+ type TestSchema = typeof testSchema;
19
+
20
+ // Mock database adapter
21
+ function createMockAdapter(): DatabaseAdapter {
22
+ const mockdb = {
23
+ createUnitOfWork: vi.fn(() => {
24
+ // Create a mock restricted UOW
25
+ const createMockRestrictedUow = () => ({
26
+ forSchema: vi.fn((schema) => ({
27
+ schema,
28
+ table: vi.fn(() => ({
29
+ findMany: vi.fn(),
30
+ })),
31
+ restrict: vi.fn(() => createMockRestrictedUow()),
32
+ })),
33
+ restrict: vi.fn(() => createMockRestrictedUow()),
34
+ table: vi.fn(() => ({
35
+ findMany: vi.fn(),
36
+ })),
37
+ });
38
+
39
+ return {
40
+ forSchema: vi.fn((schema) => ({
41
+ schema,
42
+ table: vi.fn(() => ({
43
+ findMany: vi.fn(),
44
+ })),
45
+ restrict: vi.fn(() => createMockRestrictedUow()),
46
+ })),
47
+ restrict: vi.fn(() => createMockRestrictedUow()),
48
+ executeRetrieve: vi.fn(),
49
+ executeMutations: vi.fn(),
50
+ commit: vi.fn(),
51
+ rollback: vi.fn(),
52
+ reset: vi.fn(),
53
+ table: vi.fn(() => ({
54
+ findMany: vi.fn(),
55
+ })),
56
+ };
57
+ }),
58
+ type: "mock",
59
+ } as unknown as SimpleQueryInterface<TestSchema>;
60
+
61
+ return {
62
+ createQueryEngine: vi.fn(() => mockdb),
63
+ migrate: vi.fn(),
64
+ close: vi.fn(),
65
+ type: "mock",
66
+ contextStorage: new RequestContextStorage(),
67
+ } as unknown as DatabaseAdapter;
68
+ }
69
+
70
+ describe("db-fragment-instantiator", () => {
71
+ describe("Unit of Work in request context", () => {
72
+ it("should provide executeRestrictedUnitOfWork on this context in route handlers", async () => {
73
+ const definition = defineFragment("test-db-fragment")
74
+ .extend(withDatabase(testSchema))
75
+ .build();
76
+
77
+ const routes = defineRoutes(definition).create(({ defineRoute }) => [
78
+ defineRoute({
79
+ method: "GET",
80
+ path: "/test",
81
+ handler: async function (_input, { json }) {
82
+ // Access executeRestrictedUnitOfWork from this context
83
+ expect(this.uow).toBeDefined();
84
+
85
+ return json({ hasExecuteMethod: !!this.uow });
86
+ },
87
+ }),
88
+ ]);
89
+
90
+ const mockAdapter = createMockAdapter();
91
+ const fragment = instantiate(definition)
92
+ .withRoutes([routes])
93
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
94
+ .build();
95
+
96
+ const response = await fragment.handler(new Request("http://localhost/api/test"));
97
+ const data = await response.json();
98
+
99
+ expect(data).toEqual({ hasExecuteMethod: true });
100
+ });
101
+
102
+ it("should provide schema-typed UOW via executeRestrictedUnitOfWork", async () => {
103
+ const definition = defineFragment("test-db-fragment")
104
+ .extend(withDatabase(testSchema))
105
+ .build();
106
+
107
+ const routes = defineRoutes(definition).create(({ defineRoute }) => [
108
+ defineRoute({
109
+ method: "GET",
110
+ path: "/test",
111
+ handler: async function (_input, { json }) {
112
+ const result = await this.uow(async ({ forSchema }) => {
113
+ const uow = forSchema(testSchema);
114
+ return { hasSchemaUow: !!uow };
115
+ });
116
+
117
+ return json(result);
118
+ },
119
+ }),
120
+ ]);
121
+
122
+ const mockAdapter = createMockAdapter();
123
+ const fragment = instantiate(definition)
124
+ .withRoutes([routes])
125
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
126
+ .build();
127
+
128
+ const response = await fragment.handler(new Request("http://localhost/api/test"));
129
+ const data = await response.json();
130
+
131
+ expect(data).toEqual({ hasSchemaUow: true });
132
+ });
133
+ });
134
+
135
+ describe("implicit database dependencies", () => {
136
+ it("should provide db dependency to services", () => {
137
+ const definition = defineFragment("test-db-fragment")
138
+ .extend(withDatabase(testSchema))
139
+ .providesBaseService(({ deps }) => ({
140
+ getDb: () => deps.db,
141
+ }))
142
+ .build();
143
+
144
+ const mockAdapter = createMockAdapter();
145
+ const fragment = instantiate(definition)
146
+ .withOptions({ databaseAdapter: mockAdapter })
147
+ .build();
148
+
149
+ const db = fragment.services.getDb();
150
+ expect(db).toBeDefined();
151
+ expect(db.createUnitOfWork).toBeDefined();
152
+ });
153
+
154
+ it("should provide schema dependency to services", () => {
155
+ const definition = defineFragment("test-db-fragment")
156
+ .extend(withDatabase(testSchema))
157
+ .providesBaseService(({ deps }) => ({
158
+ getSchema: () => deps.schema,
159
+ }))
160
+ .build();
161
+
162
+ const mockAdapter = createMockAdapter();
163
+ const fragment = instantiate(definition)
164
+ .withOptions({ databaseAdapter: mockAdapter })
165
+ .build();
166
+
167
+ const schemaFromService = fragment.services.getSchema();
168
+ expect(schemaFromService).toBe(testSchema);
169
+ });
170
+
171
+ it("should provide createUnitOfWork dependency", () => {
172
+ const definition = defineFragment("test-db-fragment")
173
+ .extend(withDatabase(testSchema))
174
+ .providesBaseService(({ deps }) => ({
175
+ createUow: () => deps.createUnitOfWork(),
176
+ }))
177
+ .build();
178
+
179
+ const mockAdapter = createMockAdapter();
180
+ const fragment = instantiate(definition)
181
+ .withOptions({ databaseAdapter: mockAdapter })
182
+ .build();
183
+
184
+ const uow = fragment.services.createUow();
185
+ expect(uow).toBeDefined();
186
+ expect(uow.executeRetrieve).toBeDefined();
187
+ expect(uow.executeMutations).toBeDefined();
188
+ });
189
+ });
190
+
191
+ describe("database operations with UOW", () => {
192
+ it("should allow accessing schema-typed UOW in handlers via executeRestrictedUnitOfWork", async () => {
193
+ const testSchemaWithCounter = schema((s) => {
194
+ return s.addTable("counters", (t) => {
195
+ return t.addColumn("id", idColumn()).addColumn("value", column("integer"));
196
+ });
197
+ });
198
+
199
+ const definition = defineFragment("test-db-fragment")
200
+ .extend(withDatabase(testSchemaWithCounter))
201
+ .build();
202
+
203
+ const routes = defineRoutes(definition).create(({ defineRoute }) => [
204
+ defineRoute({
205
+ method: "GET",
206
+ path: "/counters",
207
+ handler: async function (_input, { json }) {
208
+ const result = await this.uow(async ({ forSchema }) => {
209
+ const uow = forSchema(testSchemaWithCounter);
210
+ // Verify that we can access the UOW
211
+ return { hasCountersTable: !!uow };
212
+ });
213
+
214
+ return json(result);
215
+ },
216
+ }),
217
+ ]);
218
+
219
+ const mockAdapter = createMockAdapter();
220
+ const fragment = instantiate(definition)
221
+ .withRoutes([routes])
222
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
223
+ .build();
224
+
225
+ const response = await fragment.handler(new Request("http://localhost/api/counters"));
226
+ const data = await response.json();
227
+
228
+ expect(data).toEqual({ hasCountersTable: true });
229
+ });
230
+ });
231
+
232
+ describe("service integration with UOW", () => {
233
+ it("should allow services to access UOW via forSchema", async () => {
234
+ const definition = defineFragment("test-db-fragment")
235
+ .extend(withDatabase(testSchema))
236
+ .providesBaseService(({ defineService }) =>
237
+ defineService({
238
+ checkTypedUowExists: function () {
239
+ const uow = this.uow(testSchema);
240
+ return !!uow;
241
+ },
242
+ }),
243
+ )
244
+ .build();
245
+
246
+ const routes = defineRoutes(definition).create(({ services, defineRoute }) => [
247
+ defineRoute({
248
+ method: "GET",
249
+ path: "/check",
250
+ outputSchema: z.object({ hasTypedUow: z.boolean() }),
251
+ handler: async function (_input, { json }) {
252
+ const hasTypedUow = services.checkTypedUowExists();
253
+ return json({ hasTypedUow });
254
+ },
255
+ }),
256
+ ]);
257
+
258
+ const mockAdapter = createMockAdapter();
259
+ const fragment = instantiate(definition)
260
+ .withRoutes([routes])
261
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
262
+ .build();
263
+
264
+ const response = await fragment.callRoute("GET", "/check");
265
+ expect(response.status).toBe(200);
266
+ assert(response.type === "json");
267
+ expect(response.data).toEqual({ hasTypedUow: true });
268
+ });
269
+
270
+ it.skip("should share same UOW across multiple service calls from handler", async () => {
271
+ const definition = defineFragment("test-db-fragment")
272
+ .extend(withDatabase(testSchema))
273
+ .providesService("helpers", ({ defineService }) =>
274
+ defineService({
275
+ logUow: function () {
276
+ return this.uow(testSchema);
277
+ },
278
+ }),
279
+ )
280
+ .providesService("main", ({ defineService }) =>
281
+ defineService({
282
+ markUow: function () {
283
+ return this.uow(testSchema);
284
+ },
285
+ }),
286
+ )
287
+ .build();
288
+
289
+ const routes = defineRoutes(definition).create(({ services, defineRoute }) => [
290
+ defineRoute({
291
+ method: "GET",
292
+ path: "/nested",
293
+ handler: async function (_input, { json }) {
294
+ // Mark the UOW with an ID
295
+ const uow1 = services.main.markUow();
296
+ const uow2 = services.helpers.logUow();
297
+ const uow3 = services.main.markUow();
298
+
299
+ console.log({
300
+ x: uow1 === uow2,
301
+ y: uow2 === uow3,
302
+ z: uow1 === uow3,
303
+ });
304
+
305
+ return json({
306
+ same: uow1 === uow2 && uow2 === uow3,
307
+ });
308
+ },
309
+ }),
310
+ ]);
311
+
312
+ const mockAdapter = createMockAdapter();
313
+ const fragment = instantiate(definition)
314
+ .withRoutes([routes])
315
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
316
+ .build();
317
+
318
+ const response = await fragment.handler(new Request("http://localhost/api/nested"));
319
+ const data = await response.json();
320
+
321
+ expect(data).toEqual({
322
+ same: true,
323
+ });
324
+ });
325
+ });
326
+
327
+ describe("inContext with database fragments", () => {
328
+ it("should allow calling services with UOW via inContext", () => {
329
+ const definition = defineFragment("test-db-fragment")
330
+ .extend(withDatabase(testSchema))
331
+ .providesBaseService(({ defineService }) =>
332
+ defineService({
333
+ getUowExists: function () {
334
+ const uow = this.uow(testSchema);
335
+ return !!uow;
336
+ },
337
+ }),
338
+ )
339
+ .build();
340
+
341
+ const mockAdapter = createMockAdapter();
342
+ const fragment = instantiate(definition)
343
+ .withOptions({ databaseAdapter: mockAdapter })
344
+ .build();
345
+
346
+ const result = fragment.inContext(() => fragment.services.getUowExists());
347
+ expect(result).toBe(true);
348
+ });
349
+ });
350
+
351
+ describe("UOW isolation per request", () => {
352
+ it("should create fresh UOW for each request", async () => {
353
+ let createUowCallCount = 0;
354
+ const mockAdapter = createMockAdapter();
355
+ const queryEngine = mockAdapter.createQueryEngine(testSchema, "test");
356
+
357
+ // Track how many times createUnitOfWork is called
358
+ const originalCreateUow = queryEngine.createUnitOfWork;
359
+ queryEngine.createUnitOfWork = vi.fn(() => {
360
+ createUowCallCount++;
361
+ return originalCreateUow();
362
+ });
363
+
364
+ const definition = defineFragment("test-db-fragment")
365
+ .extend(withDatabase(testSchema))
366
+ .build();
367
+
368
+ const routes = defineRoutes(definition).create(({ defineRoute }) => [
369
+ defineRoute({
370
+ method: "GET",
371
+ path: "/test",
372
+ handler: async function (_input, { json }) {
373
+ const result = await this.uow(async ({ forSchema }) => {
374
+ const uow = forSchema(testSchema);
375
+ return { hasUow: !!uow };
376
+ });
377
+ return json(result);
378
+ },
379
+ }),
380
+ ]);
381
+
382
+ const fragment = instantiate(definition)
383
+ .withRoutes([routes])
384
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
385
+ .build();
386
+
387
+ // Make two requests
388
+ await fragment.handler(new Request("http://localhost/api/test"));
389
+ await fragment.handler(new Request("http://localhost/api/test"));
390
+
391
+ // Verify that createUnitOfWork was called twice (once per request)
392
+ expect(createUowCallCount).toBe(2);
393
+ expect(queryEngine.createUnitOfWork).toHaveBeenCalledTimes(2);
394
+ });
395
+ });
396
+
397
+ describe("withDependencies with database context", () => {
398
+ it("should provide db and databaseAdapter in withDependencies context", () => {
399
+ interface Config {
400
+ prefix: string;
401
+ }
402
+
403
+ const definition = defineFragment<Config>("test-db-fragment")
404
+ .extend(withDatabase(testSchema))
405
+ .withDependencies(({ config, db, databaseAdapter }) => ({
406
+ userService: {
407
+ prefix: config.prefix,
408
+ hasAdapter: !!databaseAdapter,
409
+ hasDb: !!db,
410
+ },
411
+ }))
412
+ .providesBaseService(({ deps }) => ({
413
+ getUserServicePrefix: () => deps.userService.prefix,
414
+ hasAdapter: () => deps.userService.hasAdapter,
415
+ hasDb: () => deps.userService.hasDb,
416
+ }))
417
+ .build();
418
+
419
+ const mockAdapter = createMockAdapter();
420
+ const fragment = instantiate(definition)
421
+ .withConfig({ prefix: "USER_" })
422
+ .withOptions({ databaseAdapter: mockAdapter })
423
+ .build();
424
+
425
+ expect(fragment.services.getUserServicePrefix()).toBe("USER_");
426
+ expect(fragment.services.hasAdapter()).toBe(true);
427
+ expect(fragment.services.hasDb()).toBe(true);
428
+ });
429
+ });
430
+
431
+ describe("$internal object", () => {
432
+ it("should populate $internal.deps with database dependencies", () => {
433
+ const definition = defineFragment("test-db-fragment")
434
+ .extend(withDatabase(testSchema))
435
+ .build();
436
+
437
+ const mockAdapter = createMockAdapter();
438
+ const fragment = instantiate(definition)
439
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
440
+ .build();
441
+
442
+ expect(fragment.$internal.deps).toBeDefined();
443
+ expect(fragment.$internal.deps).toHaveProperty("db");
444
+ expect(fragment.$internal.deps).toHaveProperty("schema");
445
+ expect(fragment.$internal.deps).toHaveProperty("namespace");
446
+ expect(fragment.$internal.deps).toHaveProperty("createUnitOfWork");
447
+ });
448
+
449
+ it("should populate $internal.options with database adapter", () => {
450
+ const definition = defineFragment("test-db-fragment")
451
+ .extend(withDatabase(testSchema))
452
+ .build();
453
+
454
+ const mockAdapter = createMockAdapter();
455
+ const fragment = instantiate(definition)
456
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
457
+ .build();
458
+
459
+ expect(fragment.$internal.options).toBeDefined();
460
+ expect(fragment.$internal.options).toHaveProperty("databaseAdapter");
461
+ expect(fragment.$internal.options.databaseAdapter).toBe(mockAdapter);
462
+ expect(fragment.$internal.options).toHaveProperty("mountRoute", "/api");
463
+ });
464
+
465
+ it("should have correct schema and namespace in $internal.deps", () => {
466
+ const definition = defineFragment("test-db-fragment")
467
+ .extend(withDatabase(testSchema))
468
+ .build();
469
+
470
+ const mockAdapter = createMockAdapter();
471
+ const fragment = instantiate(definition)
472
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
473
+ .build();
474
+
475
+ expect(fragment.$internal.deps.schema).toBe(testSchema);
476
+ expect(fragment.$internal.deps.namespace).toBe("test-db-fragment");
477
+ });
478
+
479
+ it("should populate $internal when using providesBaseService without withDependencies", () => {
480
+ const definition = defineFragment("test-db-fragment")
481
+ .extend(withDatabase(testSchema))
482
+ .providesBaseService(({ defineService }) =>
483
+ defineService({
484
+ testMethod: function () {
485
+ return "test";
486
+ },
487
+ }),
488
+ )
489
+ .build();
490
+
491
+ const mockAdapter = createMockAdapter();
492
+ const fragment = instantiate(definition)
493
+ .withOptions({ mountRoute: "/api", databaseAdapter: mockAdapter })
494
+ .build();
495
+
496
+ expect(fragment.$internal.deps).toBeDefined();
497
+ expect(fragment.$internal.deps).toHaveProperty("db");
498
+ expect(fragment.$internal.deps).toHaveProperty("schema");
499
+ expect(fragment.$internal.deps).toHaveProperty("namespace");
500
+ expect(fragment.$internal.deps).toHaveProperty("createUnitOfWork");
501
+ expect(fragment.$internal.options).toBeDefined();
502
+ expect(fragment.$internal.options).toHaveProperty("databaseAdapter");
503
+ expect(fragment.$internal.options.databaseAdapter).toBe(mockAdapter);
504
+ });
505
+ });
506
+
507
+ describe("error handling", () => {
508
+ it("should throw when databaseAdapter is not provided", () => {
509
+ const definition = defineFragment("test-db-fragment")
510
+ .extend(withDatabase(testSchema))
511
+ .build();
512
+
513
+ expect(() => {
514
+ instantiate(definition)
515
+ // @ts-expect-error - Test case
516
+ .withOptions({})
517
+ .build();
518
+ }).toThrow("Database fragment requires a database adapter");
519
+ });
520
+
521
+ it("should throw when forSchema called outside request context", () => {
522
+ const definition = defineFragment("test-db-fragment")
523
+ .extend(withDatabase(testSchema))
524
+ .providesBaseService(({ defineService }) =>
525
+ defineService({
526
+ tryGetUow: function () {
527
+ return this.uow(testSchema);
528
+ },
529
+ }),
530
+ )
531
+ .build();
532
+
533
+ const mockAdapter = createMockAdapter();
534
+ const fragment = instantiate(definition)
535
+ .withOptions({ databaseAdapter: mockAdapter })
536
+ .build();
537
+
538
+ expect(() => fragment.services.tryGetUow()).toThrow(
539
+ "No storage found in RequestContextStorage. Service must be called within a route handler OR using `inContext`.",
540
+ );
541
+ });
542
+ });
543
+ });