@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
package/src/fragment.ts DELETED
@@ -1,727 +0,0 @@
1
- import type { AnySchema } from "./schema/create";
2
- import type { AbstractQuery } from "./query/query";
3
- import type { DatabaseAdapter } from "./adapters/adapters";
4
- import { bindServicesToContext, type BoundServices } from "./bind-services";
5
- import { AsyncLocalStorage } from "async_hooks";
6
- import type { IUnitOfWorkBase, UnitOfWorkSchemaView } from "./query/unit-of-work";
7
- import type { RequestThisContext } from "@fragno-dev/core/api";
8
-
9
- export const uowStorage = new AsyncLocalStorage<IUnitOfWorkBase>();
10
-
11
- /**
12
- * Service context for database fragments, providing access to the Unit of Work.
13
- */
14
- export interface DatabaseRequestThisContext extends RequestThisContext {
15
- /**
16
- * Get the Unit of Work from the current context.
17
- * @param schema - Optional schema to get a typed view. If not provided, returns the base UOW.
18
- * @returns IUnitOfWorkBase if no schema provided, or typed UnitOfWorkSchemaView if schema provided.
19
- */
20
- getUnitOfWork(): IUnitOfWorkBase;
21
- getUnitOfWork<TSchema extends AnySchema>(
22
- schema: TSchema,
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
- ): UnitOfWorkSchemaView<TSchema, [], any>;
25
- }
26
-
27
- export const serviceContext: DatabaseRequestThisContext = {
28
- getUnitOfWork<TSchema extends AnySchema>(
29
- schema?: TSchema,
30
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
- ): any {
32
- const uow = uowStorage.getStore();
33
- if (!uow) {
34
- throw new Error("No UnitOfWork in context. Service must be called within a route handler.");
35
- }
36
- if (schema) {
37
- return uow.forSchema(schema);
38
- }
39
- return uow;
40
- },
41
- };
42
-
43
- export function withUnitOfWork<T>(uow: IUnitOfWorkBase, callback: () => T): Promise<T> {
44
- return Promise.resolve(uowStorage.run(uow, callback));
45
- }
46
-
47
- /**
48
- * Type helper that enforces DatabaseRequestThisContext on all functions in a service object
49
- */
50
- type WithDatabaseThis<T> = {
51
- [K in keyof T]: T[K] extends (...args: infer A) => infer R
52
- ? (this: DatabaseRequestThisContext, ...args: A) => R
53
- : T[K] extends Record<string, unknown>
54
- ? WithDatabaseThis<T[K]>
55
- : T[K];
56
- };
57
-
58
- // Import types from fragno package
59
- import type {
60
- FragmentDefinition,
61
- RouteHandler,
62
- FragnoPublicConfig,
63
- RequestInputContext,
64
- RequestOutputContext,
65
- } from "@fragno-dev/core";
66
-
67
- export { bindServicesToContext, type BoundServices };
68
-
69
- /**
70
- * Route handler type for database fragments with access to Unit of Work.
71
- */
72
- export type DatabaseRouteHandler = (
73
- this: DatabaseRequestThisContext,
74
- inputContext: RequestInputContext,
75
- outputContext: RequestOutputContext,
76
- ) => Promise<Response>;
77
-
78
- /**
79
- * Extended FragnoPublicConfig that includes a database adapter.
80
- * Use this type when creating fragments with database support.
81
- */
82
- export type FragnoPublicConfigWithDatabase = FragnoPublicConfig & {
83
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- databaseAdapter: DatabaseAdapter<any>;
85
- };
86
-
87
- /**
88
- * Additional context provided to database fragments containing the database adapter and ORM instance.
89
- */
90
- export type DatabaseFragmentContext<TSchema extends AnySchema> = {
91
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
- databaseAdapter: DatabaseAdapter<any>;
93
- orm: AbstractQuery<TSchema>;
94
- };
95
-
96
- export class DatabaseFragmentBuilder<
97
- const TSchema extends AnySchema,
98
- const TConfig,
99
- const TDeps = {},
100
- const TServices = {},
101
- const TUsedServices = {},
102
- const TProvidedServices = {},
103
- > {
104
- // Type-only property to expose type parameters for better inference
105
- readonly $types!: {
106
- schema: TSchema;
107
- config: TConfig;
108
- deps: TDeps;
109
- services: TServices;
110
- usedServices: TUsedServices;
111
- providedServices: TProvidedServices;
112
- };
113
-
114
- #name: string;
115
- #schema?: TSchema;
116
- #namespace?: string;
117
- #dependencies?: (
118
- context: {
119
- config: TConfig;
120
- fragnoConfig: FragnoPublicConfig;
121
- } & DatabaseFragmentContext<TSchema>,
122
- ) => TDeps;
123
- #services?: (
124
- context: {
125
- config: TConfig;
126
- fragnoConfig: FragnoPublicConfig;
127
- deps: TDeps & TUsedServices;
128
- defineService: <T extends Record<string, unknown>>(
129
- services: WithDatabaseThis<T>,
130
- ) => WithDatabaseThis<T>;
131
- } & DatabaseFragmentContext<TSchema>,
132
- ) => TServices;
133
- #usedServices?: Record<string, { name: string; required: boolean }>;
134
- #providedServices?: Record<string, unknown>;
135
-
136
- constructor(options: {
137
- name: string;
138
- schema?: TSchema;
139
- namespace?: string;
140
- dependencies?: (
141
- context: {
142
- config: TConfig;
143
- fragnoConfig: FragnoPublicConfig;
144
- } & DatabaseFragmentContext<TSchema>,
145
- ) => TDeps;
146
- services?: (
147
- context: {
148
- config: TConfig;
149
- fragnoConfig: FragnoPublicConfig;
150
- deps: TDeps & TUsedServices;
151
- defineService: <T extends Record<string, unknown>>(
152
- services: WithDatabaseThis<T>,
153
- ) => WithDatabaseThis<T>;
154
- } & DatabaseFragmentContext<TSchema>,
155
- ) => TServices;
156
- usedServices?: Record<string, { name: string; required: boolean }>;
157
- providedServices?: Record<string, unknown>;
158
- }) {
159
- this.#name = options.name;
160
- this.#schema = options.schema;
161
- this.#namespace = options.namespace;
162
- this.#dependencies = options.dependencies;
163
- this.#services = options.services;
164
- this.#usedServices = options.usedServices;
165
- this.#providedServices = options.providedServices;
166
- }
167
-
168
- get $requiredOptions(): FragnoPublicConfigWithDatabase {
169
- throw new Error("Type only method. Do not call.");
170
- }
171
-
172
- get definition(): FragmentDefinition<
173
- TConfig,
174
- TDeps,
175
- BoundServices<TServices>,
176
- { databaseSchema?: TSchema; databaseNamespace: string },
177
- BoundServices<TUsedServices>,
178
- BoundServices<TProvidedServices>,
179
- DatabaseRequestThisContext
180
- > {
181
- const schema = this.#schema;
182
- const namespace = this.#namespace ?? "";
183
- const name = this.#name;
184
- const dependencies = this.#dependencies;
185
- const services = this.#services;
186
- const providedServices = this.#providedServices;
187
-
188
- return {
189
- name,
190
- dependencies: (config: TConfig, options: FragnoPublicConfig) => {
191
- const dbContext = this.#createDatabaseContext(options, schema, namespace, name);
192
- return dependencies?.({ config, fragnoConfig: options, ...dbContext }) ?? ({} as TDeps);
193
- },
194
- services: (
195
- config: TConfig,
196
- options: FragnoPublicConfig,
197
- deps: TDeps & BoundServices<TUsedServices>,
198
- ) => {
199
- const dbContext = this.#createDatabaseContext(options, schema, namespace, name);
200
- // Cast deps back to raw type for internal services function.
201
- // This is safe because:
202
- // 1. deps are already bound (their 'this' parameters are stripped)
203
- // 2. The services function expects raw types but only uses the public API
204
- // 3. BoundServices<T> has the same runtime shape as T (just without 'this')
205
-
206
- // defineService provides typing for service functions
207
- // It expects the input to already have proper 'this' types on functions
208
- const defineService = <T extends Record<string, unknown>>(
209
- services: WithDatabaseThis<T>,
210
- ): WithDatabaseThis<T> => services;
211
-
212
- const rawServices =
213
- services?.({
214
- config,
215
- fragnoConfig: options,
216
- deps: deps as TDeps & TUsedServices,
217
- defineService,
218
- ...dbContext,
219
- }) ?? ({} as TServices);
220
-
221
- // Bind all service methods to serviceContext
222
- return bindServicesToContext(
223
- rawServices as Record<string, unknown>,
224
- ) as BoundServices<TServices>;
225
- },
226
- additionalContext: {
227
- databaseSchema: schema,
228
- databaseNamespace: namespace,
229
- },
230
- createHandlerWrapper: schema
231
- ? (options: FragnoPublicConfig) => {
232
- const dbContext = this.#createDatabaseContext(options, schema, namespace, name);
233
- const { orm } = dbContext;
234
-
235
- // Return handler wrapper function
236
- return (handler: DatabaseRouteHandler): RouteHandler => {
237
- return async (inputContext, outputContext) => {
238
- // Create UOW for this request
239
- const uow = orm.createUnitOfWork();
240
-
241
- // Execute handler within AsyncLocalStorage context
242
- return withUnitOfWork(uow, async () => {
243
- // Bind handler to serviceContext so it has access to getUnitOfWork via 'this'
244
- const boundHandler = handler.bind(serviceContext);
245
- return boundHandler(inputContext, outputContext);
246
- });
247
- };
248
- };
249
- }
250
- : undefined,
251
- usedServices: this.#usedServices as
252
- | {
253
- [K in keyof TUsedServices]: { name: string; required: boolean };
254
- }
255
- | undefined,
256
- // Pass providedServices as-is - let fragment-instantiation.ts handle resolution
257
- // The factory functions will be called by createFragment
258
- providedServices: providedServices as
259
- | {
260
- [K in keyof BoundServices<TProvidedServices>]: BoundServices<TProvidedServices>[K];
261
- }
262
- | ((
263
- config: TConfig,
264
- options: FragnoPublicConfig,
265
- deps: TDeps & BoundServices<TUsedServices>,
266
- ) => BoundServices<TProvidedServices>)
267
- | undefined,
268
- };
269
- }
270
-
271
- #createDatabaseContext(
272
- options: FragnoPublicConfig,
273
- schema: TSchema | undefined,
274
- namespace: string,
275
- name: string,
276
- ): DatabaseFragmentContext<TSchema> {
277
- // Safe cast: FragnoPublicConfig is extended with databaseAdapter by the user
278
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
279
- const databaseAdapter = (options as any).databaseAdapter as DatabaseAdapter<any> | undefined;
280
-
281
- if (!databaseAdapter) {
282
- throw new Error(`Fragment '${name}' requires a database adapter in options.databaseAdapter`);
283
- }
284
- if (!schema) {
285
- throw new Error(`Fragment '${name}' requires a schema. Use withDatabase() to provide one.`);
286
- }
287
-
288
- // Safe cast: we create a query engine for TSchema and know it will be AbstractQuery<TSchema>
289
- const orm = databaseAdapter.createQueryEngine(
290
- schema,
291
- namespace,
292
- ) as unknown as AbstractQuery<TSchema>;
293
-
294
- return { databaseAdapter, orm };
295
- }
296
-
297
- withDatabase<TNewSchema extends AnySchema>(
298
- schema: TNewSchema,
299
- namespace?: string,
300
- ): DatabaseFragmentBuilder<
301
- TNewSchema,
302
- TConfig,
303
- TDeps,
304
- TServices,
305
- TUsedServices,
306
- TProvidedServices
307
- > {
308
- return new DatabaseFragmentBuilder<
309
- TNewSchema,
310
- TConfig,
311
- TDeps,
312
- TServices,
313
- TUsedServices,
314
- TProvidedServices
315
- >({
316
- name: this.#name,
317
- schema,
318
- namespace: namespace ?? this.#name + "-db",
319
- dependencies: this.#dependencies as
320
- | ((
321
- context: {
322
- config: TConfig;
323
- fragnoConfig: FragnoPublicConfig;
324
- } & DatabaseFragmentContext<TNewSchema>,
325
- ) => TDeps)
326
- | undefined,
327
- services: this.#services as
328
- | ((
329
- context: {
330
- config: TConfig;
331
- fragnoConfig: FragnoPublicConfig;
332
- deps: TDeps & TUsedServices;
333
- defineService: <T extends Record<string, unknown>>(
334
- services: WithDatabaseThis<T>,
335
- ) => WithDatabaseThis<T>;
336
- } & DatabaseFragmentContext<TNewSchema>,
337
- ) => TServices)
338
- | undefined,
339
- usedServices: this.#usedServices,
340
- providedServices: this.#providedServices,
341
- });
342
- }
343
-
344
- withDependencies<TNewDeps>(
345
- fn: (
346
- context: {
347
- config: TConfig;
348
- fragnoConfig: FragnoPublicConfig;
349
- } & DatabaseFragmentContext<TSchema>,
350
- ) => TNewDeps,
351
- ): DatabaseFragmentBuilder<TSchema, TConfig, TNewDeps, {}, TUsedServices, TProvidedServices> {
352
- return new DatabaseFragmentBuilder<
353
- TSchema,
354
- TConfig,
355
- TNewDeps,
356
- {},
357
- TUsedServices,
358
- TProvidedServices
359
- >({
360
- name: this.#name,
361
- schema: this.#schema,
362
- namespace: this.#namespace,
363
- dependencies: fn,
364
- services: undefined,
365
- usedServices: this.#usedServices,
366
- providedServices: this.#providedServices,
367
- });
368
- }
369
-
370
- /**
371
- * Declare that this fragment uses a service.
372
- * @param serviceName - The name of the service to use
373
- * @param options - Optional configuration: { optional: boolean } (defaults to required)
374
- */
375
- usesService<TServiceName extends string, TService>(
376
- serviceName: TServiceName,
377
- options?: { optional?: false },
378
- ): DatabaseFragmentBuilder<
379
- TSchema,
380
- TConfig,
381
- TDeps,
382
- TServices,
383
- TUsedServices & { [K in TServiceName]: TService },
384
- TProvidedServices
385
- >;
386
- usesService<TServiceName extends string, TService>(
387
- serviceName: TServiceName,
388
- options: { optional: true },
389
- ): DatabaseFragmentBuilder<
390
- TSchema,
391
- TConfig,
392
- TDeps,
393
- TServices,
394
- TUsedServices & { [K in TServiceName]: TService | undefined },
395
- TProvidedServices
396
- >;
397
- usesService<TServiceName extends string, TService>(
398
- serviceName: TServiceName,
399
- options?: { optional?: boolean },
400
- ): DatabaseFragmentBuilder<
401
- TSchema,
402
- TConfig,
403
- TDeps,
404
- TServices,
405
- TUsedServices & { [K in TServiceName]: TService | TService | undefined },
406
- TProvidedServices
407
- > {
408
- const isOptional = options?.optional ?? false;
409
- return new DatabaseFragmentBuilder<
410
- TSchema,
411
- TConfig,
412
- TDeps,
413
- TServices,
414
- TUsedServices & { [K in TServiceName]: TService | (TService | undefined) },
415
- TProvidedServices
416
- >({
417
- name: this.#name,
418
- schema: this.#schema,
419
- namespace: this.#namespace,
420
- dependencies: this.#dependencies as unknown as
421
- | ((
422
- context: {
423
- config: TConfig;
424
- fragnoConfig: FragnoPublicConfig;
425
- } & DatabaseFragmentContext<TSchema>,
426
- ) => TDeps)
427
- | undefined,
428
- services: this.#services as unknown as
429
- | ((
430
- context: {
431
- config: TConfig;
432
- fragnoConfig: FragnoPublicConfig;
433
- deps: TDeps &
434
- (TUsedServices & { [K in TServiceName]: TService | (TService | undefined) });
435
- } & DatabaseFragmentContext<TSchema>,
436
- ) => TServices)
437
- | undefined,
438
- usedServices: {
439
- ...this.#usedServices,
440
- [serviceName]: { name: serviceName, required: !isOptional },
441
- },
442
- providedServices: this.#providedServices,
443
- });
444
- }
445
-
446
- /**
447
- * Define services for this fragment (unnamed).
448
- * Functions in the service will have access to DatabaseRequestThisContext via `this` if using `defineService`.
449
- *
450
- * @example
451
- * With `this` context:
452
- * ```ts
453
- * .providesService(({ defineService }) => defineService({
454
- * createUser: function(name: string) {
455
- * const uow = this.getUnitOfWork(mySchema);
456
- * return uow.create('user', { name });
457
- * }
458
- * }))
459
- * ```
460
- *
461
- * Without `this` context:
462
- * ```ts
463
- * .providesService(({ db }) => ({
464
- * createUser: async (name: string) => {
465
- * return db.create('user', { name });
466
- * }
467
- * }))
468
- * ```
469
- */
470
- providesService<TNewServices>(
471
- fn: (context: {
472
- config: TConfig;
473
- fragnoConfig: FragnoPublicConfig;
474
- deps: TDeps & TUsedServices;
475
- db: AbstractQuery<TSchema>;
476
- defineService: <T extends Record<string, unknown>>(
477
- services: WithDatabaseThis<T>,
478
- ) => WithDatabaseThis<T>;
479
- }) => TNewServices,
480
- ): DatabaseFragmentBuilder<
481
- TSchema,
482
- TConfig,
483
- TDeps,
484
- TNewServices,
485
- TUsedServices,
486
- TProvidedServices
487
- >;
488
-
489
- /**
490
- * Provide a named service that other fragments can use.
491
- * Functions in the service will have access to DatabaseRequestThisContext via `this` if using `defineService`.
492
- * You can also pass a service object directly instead of a callback.
493
- *
494
- * @example
495
- * With callback and `this` context:
496
- * ```ts
497
- * .providesService("myService", ({ defineService }) => defineService({
498
- * createUser: function(name: string) {
499
- * const uow = this.getUnitOfWork(mySchema);
500
- * return uow.create('user', { name });
501
- * }
502
- * }))
503
- * ```
504
- *
505
- * With callback, no `this` context:
506
- * ```ts
507
- * .providesService("myService", ({ db }) => ({
508
- * createUser: async (name: string) => {
509
- * return db.create('user', { name });
510
- * }
511
- * }))
512
- * ```
513
- *
514
- * With direct object:
515
- * ```ts
516
- * .providesService("myService", {
517
- * createUser: async (name: string) => { ... }
518
- * })
519
- * ```
520
- */
521
- providesService<TServiceName extends string, TService>(
522
- serviceName: TServiceName,
523
- fnOrService:
524
- | ((context: {
525
- config: TConfig;
526
- fragnoConfig: FragnoPublicConfig;
527
- deps: TDeps & TUsedServices;
528
- db: AbstractQuery<TSchema>;
529
- defineService: <T extends Record<string, unknown>>(
530
- services: WithDatabaseThis<T>,
531
- ) => WithDatabaseThis<T>;
532
- }) => TService)
533
- | TService,
534
- ): DatabaseFragmentBuilder<
535
- TSchema,
536
- TConfig,
537
- TDeps,
538
- TServices,
539
- TUsedServices,
540
- TProvidedServices & { [K in TServiceName]: BoundServices<TService> }
541
- >;
542
-
543
- providesService<TServiceName extends string, TService>(
544
- ...args:
545
- | [
546
- fn: (context: {
547
- config: TConfig;
548
- fragnoConfig: FragnoPublicConfig;
549
- deps: TDeps & TUsedServices;
550
- db: AbstractQuery<TSchema>;
551
- defineService: <T extends Record<string, unknown>>(
552
- services: WithDatabaseThis<T>,
553
- ) => WithDatabaseThis<T>;
554
- }) => TService,
555
- ]
556
- | [
557
- serviceName: TServiceName,
558
- fnOrService:
559
- | ((context: {
560
- config: TConfig;
561
- fragnoConfig: FragnoPublicConfig;
562
- deps: TDeps & TUsedServices;
563
- db: AbstractQuery<TSchema>;
564
- defineService: <T extends Record<string, unknown>>(
565
- services: WithDatabaseThis<T>,
566
- ) => WithDatabaseThis<T>;
567
- }) => TService)
568
- | TService,
569
- ]
570
- ):
571
- | DatabaseFragmentBuilder<TSchema, TConfig, TDeps, TService, TUsedServices, TProvidedServices>
572
- | DatabaseFragmentBuilder<
573
- TSchema,
574
- TConfig,
575
- TDeps,
576
- TServices,
577
- TUsedServices,
578
- TProvidedServices & { [K in TServiceName]: BoundServices<TService> }
579
- > {
580
- if (args.length === 1) {
581
- // Unnamed service - replaces withServices
582
- const [fn] = args;
583
-
584
- // Create a callback that takes a single context object (matching #services signature)
585
- // Note: We don't explicitly type the return to preserve the WithDatabaseThis wrapper
586
- const servicesCallback = (
587
- context: {
588
- config: TConfig;
589
- fragnoConfig: FragnoPublicConfig;
590
- deps: TDeps & TUsedServices;
591
- } & DatabaseFragmentContext<TSchema>,
592
- ) => {
593
- // defineService provides typing for service functions
594
- // It expects the input to already have proper 'this' types on functions
595
- const defineService = <T extends Record<string, unknown>>(
596
- services: WithDatabaseThis<T>,
597
- ): WithDatabaseThis<T> => services;
598
-
599
- const services = fn({
600
- config: context.config,
601
- fragnoConfig: context.fragnoConfig,
602
- deps: context.deps,
603
- db: context.orm,
604
- defineService,
605
- });
606
-
607
- // Return without casting to preserve the WithDatabaseThis wrapper
608
- return services;
609
- };
610
-
611
- return new DatabaseFragmentBuilder<
612
- TSchema,
613
- TConfig,
614
- TDeps,
615
- TService,
616
- TUsedServices,
617
- TProvidedServices
618
- >({
619
- name: this.#name,
620
- schema: this.#schema,
621
- namespace: this.#namespace,
622
- dependencies: this.#dependencies,
623
- // Safe cast: servicesCallback returns WithDatabaseThis<TService> but we store it as TService.
624
- // At runtime, bindServicesToContext will handle the 'this' binding properly.
625
- services: servicesCallback as (
626
- context: {
627
- config: TConfig;
628
- fragnoConfig: FragnoPublicConfig;
629
- deps: TDeps & TUsedServices;
630
- defineService: <T extends Record<string, unknown>>(
631
- services: WithDatabaseThis<T>,
632
- ) => WithDatabaseThis<T>;
633
- } & DatabaseFragmentContext<TSchema>,
634
- ) => TService,
635
- usedServices: this.#usedServices,
636
- providedServices: this.#providedServices,
637
- });
638
- } else {
639
- // Named service
640
- const [serviceName, fnOrService] = args;
641
-
642
- // Create a callback that provides the full context
643
- const createService = (
644
- config: TConfig,
645
- options: FragnoPublicConfig,
646
- deps: TDeps & TUsedServices,
647
- ): BoundServices<TService> => {
648
- const dbContext = this.#createDatabaseContext(
649
- options,
650
- this.#schema,
651
- this.#namespace ?? "",
652
- this.#name,
653
- );
654
-
655
- // Check if fnOrService is a function or a direct object
656
- let implementation: TService;
657
- if (typeof fnOrService === "function") {
658
- // It's a callback - call it with context
659
- // defineService provides typing for service functions
660
- // It expects the input to already have proper 'this' types on functions
661
- const defineService = <T extends Record<string, unknown>>(
662
- services: WithDatabaseThis<T>,
663
- ): WithDatabaseThis<T> => services;
664
-
665
- // Safe cast: we checked that fnOrService is a function
666
- implementation = (
667
- fnOrService as (context: {
668
- config: TConfig;
669
- fragnoConfig: FragnoPublicConfig;
670
- deps: TDeps & TUsedServices;
671
- db: AbstractQuery<TSchema>;
672
- defineService: <T extends Record<string, unknown>>(
673
- services: WithDatabaseThis<T>,
674
- ) => WithDatabaseThis<T>;
675
- }) => TService
676
- )({
677
- config,
678
- fragnoConfig: options,
679
- deps,
680
- db: dbContext.orm,
681
- defineService,
682
- });
683
- } else {
684
- // It's a direct object
685
- implementation = fnOrService;
686
- }
687
-
688
- // Bind the service implementation so methods have access to serviceContext
689
- return bindServicesToContext(
690
- implementation as Record<string, unknown>,
691
- ) as BoundServices<TService>;
692
- };
693
-
694
- // We need to evaluate this immediately to store in providedServices
695
- // For now, we'll create a placeholder that will be evaluated when fragment is instantiated
696
- // Actually, we need to defer this until fragment instantiation
697
- // Let's store a function that creates the service
698
- return new DatabaseFragmentBuilder<
699
- TSchema,
700
- TConfig,
701
- TDeps,
702
- TServices,
703
- TUsedServices,
704
- TProvidedServices & { [K in TServiceName]: BoundServices<TService> }
705
- >({
706
- name: this.#name,
707
- schema: this.#schema,
708
- namespace: this.#namespace,
709
- dependencies: this.#dependencies,
710
- services: this.#services,
711
- usedServices: this.#usedServices,
712
- providedServices: {
713
- ...this.#providedServices,
714
- [serviceName]: createService,
715
- } as Record<string, unknown>,
716
- });
717
- }
718
- }
719
- }
720
-
721
- export function defineFragmentWithDatabase<TConfig = {}>(
722
- name: string,
723
- ): DatabaseFragmentBuilder<never, TConfig, {}, {}, {}, {}> {
724
- return new DatabaseFragmentBuilder<never, TConfig, {}, {}, {}, {}>({
725
- name,
726
- });
727
- }