@fragno-dev/db 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/.turbo/turbo-build.log +206 -140
  2. package/CHANGELOG.md +67 -0
  3. package/README.md +30 -9
  4. package/dist/adapters/adapters.d.ts +23 -21
  5. package/dist/adapters/adapters.d.ts.map +1 -1
  6. package/dist/adapters/adapters.js.map +1 -1
  7. package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
  8. package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
  9. package/dist/adapters/generic-sql/driver-config.js +23 -1
  10. package/dist/adapters/generic-sql/driver-config.js.map +1 -1
  11. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +27 -9
  12. package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
  13. package/dist/adapters/generic-sql/generic-sql-adapter.js +55 -16
  14. package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
  15. package/dist/adapters/generic-sql/generic-sql-uow-executor.js +129 -3
  16. package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
  17. package/dist/adapters/generic-sql/migration/dialect/mysql.js +24 -5
  18. package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
  19. package/dist/adapters/generic-sql/migration/dialect/postgres.js +6 -5
  20. package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
  21. package/dist/adapters/generic-sql/migration/dialect/sqlite.js +21 -10
  22. package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
  23. package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
  24. package/dist/adapters/generic-sql/migration/prepared-migrations.js +8 -8
  25. package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
  26. package/dist/adapters/generic-sql/migration/sql-generator.js +74 -51
  27. package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
  28. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +6 -5
  29. package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
  30. package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
  31. package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
  32. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +25 -17
  33. package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
  34. package/dist/adapters/generic-sql/query/select-builder.js +5 -3
  35. package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
  36. package/dist/adapters/generic-sql/query/sql-query-compiler.js +15 -12
  37. package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
  38. package/dist/adapters/generic-sql/query/where-builder.js +38 -28
  39. package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
  40. package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
  41. package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
  42. package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
  43. package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
  44. package/dist/adapters/generic-sql/uow-decoder.js +7 -3
  45. package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
  46. package/dist/adapters/generic-sql/uow-encoder.js +28 -8
  47. package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
  48. package/dist/adapters/in-memory/condition-evaluator.js +131 -0
  49. package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
  50. package/dist/adapters/in-memory/errors.d.ts +13 -0
  51. package/dist/adapters/in-memory/errors.d.ts.map +1 -0
  52. package/dist/adapters/in-memory/errors.js +23 -0
  53. package/dist/adapters/in-memory/errors.js.map +1 -0
  54. package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
  55. package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
  56. package/dist/adapters/in-memory/in-memory-adapter.js +176 -0
  57. package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
  58. package/dist/adapters/in-memory/in-memory-uow.js +648 -0
  59. package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
  60. package/dist/adapters/in-memory/index.d.ts +4 -0
  61. package/dist/adapters/in-memory/index.js +4 -0
  62. package/dist/adapters/in-memory/options.d.ts +28 -0
  63. package/dist/adapters/in-memory/options.d.ts.map +1 -0
  64. package/dist/adapters/in-memory/options.js +61 -0
  65. package/dist/adapters/in-memory/options.js.map +1 -0
  66. package/dist/adapters/in-memory/reference-resolution.js +26 -0
  67. package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
  68. package/dist/adapters/in-memory/sorted-array-index.js +129 -0
  69. package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
  70. package/dist/adapters/in-memory/store.js +71 -0
  71. package/dist/adapters/in-memory/store.js.map +1 -0
  72. package/dist/adapters/in-memory/value-comparison.js +28 -0
  73. package/dist/adapters/in-memory/value-comparison.js.map +1 -0
  74. package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
  75. package/dist/adapters/shared/uow-operation-compiler.js +11 -11
  76. package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
  77. package/dist/adapters/sql/index.d.ts +5 -0
  78. package/dist/adapters/sql/index.js +4 -0
  79. package/dist/db-fragment-definition-builder.d.ts +45 -96
  80. package/dist/db-fragment-definition-builder.d.ts.map +1 -1
  81. package/dist/db-fragment-definition-builder.js +121 -99
  82. package/dist/db-fragment-definition-builder.js.map +1 -1
  83. package/dist/dispatchers/cloudflare-do/index.d.ts +26 -0
  84. package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
  85. package/dist/dispatchers/cloudflare-do/index.js +63 -0
  86. package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
  87. package/dist/dispatchers/node/index.d.ts +17 -0
  88. package/dist/dispatchers/node/index.d.ts.map +1 -0
  89. package/dist/dispatchers/node/index.js +59 -0
  90. package/dist/dispatchers/node/index.js.map +1 -0
  91. package/dist/fragments/internal-fragment.d.ts +172 -9
  92. package/dist/fragments/internal-fragment.d.ts.map +1 -1
  93. package/dist/fragments/internal-fragment.js +193 -74
  94. package/dist/fragments/internal-fragment.js.map +1 -1
  95. package/dist/fragments/internal-fragment.routes.js +29 -0
  96. package/dist/fragments/internal-fragment.routes.js.map +1 -0
  97. package/dist/fragments/internal-fragment.schema.d.ts +9 -0
  98. package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
  99. package/dist/fragments/internal-fragment.schema.js +22 -0
  100. package/dist/fragments/internal-fragment.schema.js.map +1 -0
  101. package/dist/hooks/durable-hooks-processor.d.ts +14 -0
  102. package/dist/hooks/durable-hooks-processor.d.ts.map +1 -0
  103. package/dist/hooks/durable-hooks-processor.js +32 -0
  104. package/dist/hooks/durable-hooks-processor.js.map +1 -0
  105. package/dist/hooks/hooks.d.ts +47 -4
  106. package/dist/hooks/hooks.d.ts.map +1 -1
  107. package/dist/hooks/hooks.js +106 -39
  108. package/dist/hooks/hooks.js.map +1 -1
  109. package/dist/migration-engine/auto-from-schema.js +14 -11
  110. package/dist/migration-engine/auto-from-schema.js.map +1 -1
  111. package/dist/migration-engine/generation-engine.d.ts +16 -10
  112. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  113. package/dist/migration-engine/generation-engine.js +72 -33
  114. package/dist/migration-engine/generation-engine.js.map +1 -1
  115. package/dist/migration-engine/shared.js.map +1 -1
  116. package/dist/mod.d.ts +17 -10
  117. package/dist/mod.d.ts.map +1 -1
  118. package/dist/mod.js +14 -8
  119. package/dist/mod.js.map +1 -1
  120. package/dist/naming/sql-naming.d.ts +19 -0
  121. package/dist/naming/sql-naming.d.ts.map +1 -0
  122. package/dist/naming/sql-naming.js +116 -0
  123. package/dist/naming/sql-naming.js.map +1 -0
  124. package/dist/node_modules/.pnpm/{rou3@0.7.10 → rou3@0.7.12}/node_modules/rou3/dist/index.js +8 -5
  125. package/dist/node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js.map +1 -0
  126. package/dist/outbox/outbox-builder.js +156 -0
  127. package/dist/outbox/outbox-builder.js.map +1 -0
  128. package/dist/outbox/outbox.d.ts +52 -0
  129. package/dist/outbox/outbox.d.ts.map +1 -0
  130. package/dist/outbox/outbox.js +37 -0
  131. package/dist/outbox/outbox.js.map +1 -0
  132. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +3 -2
  133. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -1
  134. package/dist/packages/fragno/dist/api/fragment-instantiator.js +164 -20
  135. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
  136. package/dist/packages/fragno/dist/api/request-input-context.js +67 -0
  137. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -1
  138. package/dist/packages/fragno/dist/api/route.js +14 -1
  139. package/dist/packages/fragno/dist/api/route.js.map +1 -1
  140. package/dist/packages/fragno/dist/internal/trace-context.js +12 -0
  141. package/dist/packages/fragno/dist/internal/trace-context.js.map +1 -0
  142. package/dist/query/column-defaults.js +20 -4
  143. package/dist/query/column-defaults.js.map +1 -1
  144. package/dist/query/cursor.d.ts +3 -1
  145. package/dist/query/cursor.d.ts.map +1 -1
  146. package/dist/query/cursor.js +45 -14
  147. package/dist/query/cursor.js.map +1 -1
  148. package/dist/query/db-now.d.ts +8 -0
  149. package/dist/query/db-now.d.ts.map +1 -0
  150. package/dist/query/db-now.js +7 -0
  151. package/dist/query/db-now.js.map +1 -0
  152. package/dist/query/serialize/create-sql-serializer.js +3 -2
  153. package/dist/query/serialize/create-sql-serializer.js.map +1 -1
  154. package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
  155. package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
  156. package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
  157. package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
  158. package/dist/query/serialize/dialect/sqlite-serializer.js +55 -11
  159. package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
  160. package/dist/query/serialize/sql-serializer.js +2 -2
  161. package/dist/query/serialize/sql-serializer.js.map +1 -1
  162. package/dist/query/simple-query-interface.d.ts +6 -1
  163. package/dist/query/simple-query-interface.d.ts.map +1 -1
  164. package/dist/query/unit-of-work/execute-unit-of-work.d.ts +351 -100
  165. package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
  166. package/dist/query/unit-of-work/execute-unit-of-work.js +440 -267
  167. package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
  168. package/dist/query/unit-of-work/unit-of-work.d.ts +67 -22
  169. package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
  170. package/dist/query/unit-of-work/unit-of-work.js +110 -13
  171. package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
  172. package/dist/query/value-decoding.js +8 -5
  173. package/dist/query/value-decoding.js.map +1 -1
  174. package/dist/query/value-encoding.js +29 -9
  175. package/dist/query/value-encoding.js.map +1 -1
  176. package/dist/schema/create.d.ts +40 -14
  177. package/dist/schema/create.d.ts.map +1 -1
  178. package/dist/schema/create.js +82 -42
  179. package/dist/schema/create.js.map +1 -1
  180. package/dist/schema/generate-id.d.ts +20 -0
  181. package/dist/schema/generate-id.d.ts.map +1 -0
  182. package/dist/schema/generate-id.js +28 -0
  183. package/dist/schema/generate-id.js.map +1 -0
  184. package/dist/schema/type-conversion/create-sql-type-mapper.js +3 -2
  185. package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
  186. package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
  187. package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
  188. package/dist/schema/validator.d.ts +10 -0
  189. package/dist/schema/validator.d.ts.map +1 -0
  190. package/dist/schema/validator.js +123 -0
  191. package/dist/schema/validator.js.map +1 -0
  192. package/dist/schema-output/drizzle.d.ts +30 -0
  193. package/dist/schema-output/drizzle.d.ts.map +1 -0
  194. package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +82 -56
  195. package/dist/schema-output/drizzle.js.map +1 -0
  196. package/dist/schema-output/prisma.d.ts +17 -0
  197. package/dist/schema-output/prisma.d.ts.map +1 -0
  198. package/dist/schema-output/prisma.js +296 -0
  199. package/dist/schema-output/prisma.js.map +1 -0
  200. package/dist/util/default-database-adapter.js +61 -0
  201. package/dist/util/default-database-adapter.js.map +1 -0
  202. package/dist/with-database.d.ts +1 -1
  203. package/dist/with-database.d.ts.map +1 -1
  204. package/dist/with-database.js +12 -3
  205. package/dist/with-database.js.map +1 -1
  206. package/package.json +43 -28
  207. package/src/adapters/adapters.ts +30 -24
  208. package/src/adapters/drizzle/migrate-drizzle.test.ts +54 -33
  209. package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +599 -0
  210. package/src/adapters/drizzle/test-utils.ts +12 -8
  211. package/src/adapters/generic-sql/driver-config.ts +38 -0
  212. package/src/adapters/generic-sql/generic-sql-adapter.test.ts +5 -5
  213. package/src/adapters/generic-sql/generic-sql-adapter.ts +110 -24
  214. package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +54 -0
  215. package/src/adapters/generic-sql/generic-sql-uow-executor.ts +231 -3
  216. package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +118 -0
  217. package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +26 -8
  218. package/src/adapters/generic-sql/migration/dialect/mysql.ts +46 -8
  219. package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +25 -7
  220. package/src/adapters/generic-sql/migration/dialect/postgres.ts +8 -4
  221. package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +47 -8
  222. package/src/adapters/generic-sql/migration/dialect/sqlite.ts +27 -12
  223. package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +128 -39
  224. package/src/adapters/generic-sql/migration/prepared-migrations.ts +15 -8
  225. package/src/adapters/generic-sql/migration/sql-generator.ts +142 -65
  226. package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +9 -6
  227. package/src/adapters/generic-sql/query/cursor-utils.test.ts +271 -0
  228. package/src/adapters/generic-sql/query/cursor-utils.ts +41 -6
  229. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +27 -27
  230. package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +38 -24
  231. package/src/adapters/generic-sql/query/select-builder.test.ts +15 -11
  232. package/src/adapters/generic-sql/query/select-builder.ts +6 -2
  233. package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +52 -2
  234. package/src/adapters/generic-sql/query/sql-query-compiler.ts +50 -15
  235. package/src/adapters/generic-sql/query/where-builder.test.ts +91 -17
  236. package/src/adapters/generic-sql/query/where-builder.ts +90 -38
  237. package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +6 -6
  238. package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +806 -0
  239. package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +11 -11
  240. package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +49 -35
  241. package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +48 -32
  242. package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +6 -6
  243. package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
  244. package/src/adapters/generic-sql/uow-decoder.test.ts +1 -1
  245. package/src/adapters/generic-sql/uow-decoder.ts +21 -3
  246. package/src/adapters/generic-sql/uow-encoder.test.ts +33 -2
  247. package/src/adapters/generic-sql/uow-encoder.ts +50 -11
  248. package/src/adapters/in-memory/condition-evaluator.test.ts +193 -0
  249. package/src/adapters/in-memory/condition-evaluator.ts +275 -0
  250. package/src/adapters/in-memory/errors.ts +20 -0
  251. package/src/adapters/in-memory/in-memory-adapter.ts +277 -0
  252. package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +296 -0
  253. package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +100 -0
  254. package/src/adapters/in-memory/in-memory-uow.ts +1348 -0
  255. package/src/adapters/in-memory/index.ts +3 -0
  256. package/src/adapters/in-memory/options.test.ts +41 -0
  257. package/src/adapters/in-memory/options.ts +87 -0
  258. package/src/adapters/in-memory/reference-resolution.test.ts +50 -0
  259. package/src/adapters/in-memory/reference-resolution.ts +67 -0
  260. package/src/adapters/in-memory/sorted-array-index.test.ts +123 -0
  261. package/src/adapters/in-memory/sorted-array-index.ts +228 -0
  262. package/src/adapters/in-memory/store.test.ts +68 -0
  263. package/src/adapters/in-memory/store.ts +145 -0
  264. package/src/adapters/in-memory/value-comparison.ts +53 -0
  265. package/src/adapters/in-memory/value-normalization.test.ts +57 -0
  266. package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1163 -0
  267. package/src/adapters/shared/from-unit-of-work-compiler.ts +3 -1
  268. package/src/adapters/shared/uow-operation-compiler.ts +26 -16
  269. package/src/adapters/sql/index.ts +12 -0
  270. package/src/db-fragment-definition-builder.test.ts +88 -54
  271. package/src/db-fragment-definition-builder.ts +201 -322
  272. package/src/db-fragment-instantiator.test.ts +169 -101
  273. package/src/db-fragment-integration.test.ts +301 -149
  274. package/src/dispatchers/cloudflare-do/index.test.ts +73 -0
  275. package/src/dispatchers/cloudflare-do/index.ts +104 -0
  276. package/src/dispatchers/node/index.test.ts +91 -0
  277. package/src/dispatchers/node/index.ts +87 -0
  278. package/src/fragments/internal-fragment.routes.ts +42 -0
  279. package/src/fragments/internal-fragment.schema.ts +51 -0
  280. package/src/fragments/internal-fragment.test.ts +730 -274
  281. package/src/fragments/internal-fragment.ts +447 -154
  282. package/src/hooks/durable-hooks-processor.test.ts +117 -0
  283. package/src/hooks/durable-hooks-processor.ts +67 -0
  284. package/src/hooks/hooks.test.ts +411 -259
  285. package/src/hooks/hooks.ts +265 -66
  286. package/src/migration-engine/auto-from-schema.test.ts +14 -14
  287. package/src/migration-engine/auto-from-schema.ts +5 -2
  288. package/src/migration-engine/create.test.ts +2 -2
  289. package/src/migration-engine/generation-engine.test.ts +229 -104
  290. package/src/migration-engine/generation-engine.ts +94 -64
  291. package/src/migration-engine/shared.ts +1 -0
  292. package/src/mod.ts +78 -30
  293. package/src/naming/sql-naming.ts +180 -0
  294. package/src/outbox/outbox-builder.ts +241 -0
  295. package/src/outbox/outbox.test.ts +253 -0
  296. package/src/outbox/outbox.ts +137 -0
  297. package/src/query/column-defaults.ts +41 -3
  298. package/src/query/condition-builder.test.ts +3 -3
  299. package/src/query/cursor.test.ts +116 -18
  300. package/src/query/cursor.ts +75 -26
  301. package/src/query/db-now.ts +6 -0
  302. package/src/query/query-type.test.ts +2 -2
  303. package/src/query/serialize/create-sql-serializer.ts +7 -2
  304. package/src/query/serialize/dialect/mysql-serializer.ts +12 -4
  305. package/src/query/serialize/dialect/postgres-serializer.ts +34 -4
  306. package/src/query/serialize/dialect/sqlite-serializer.test.ts +51 -1
  307. package/src/query/serialize/dialect/sqlite-serializer.ts +92 -9
  308. package/src/query/serialize/sql-serializer.ts +4 -4
  309. package/src/query/simple-query-interface.ts +5 -0
  310. package/src/query/unit-of-work/execute-unit-of-work.test.ts +1512 -1458
  311. package/src/query/unit-of-work/execute-unit-of-work.ts +1708 -596
  312. package/src/query/unit-of-work/tx-builder.test.ts +1041 -0
  313. package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +32 -32
  314. package/src/query/unit-of-work/unit-of-work-types.test.ts +1 -1
  315. package/src/query/unit-of-work/unit-of-work.test.ts +231 -36
  316. package/src/query/unit-of-work/unit-of-work.ts +229 -31
  317. package/src/query/value-decoding.test.ts +13 -2
  318. package/src/query/value-decoding.ts +17 -4
  319. package/src/query/value-encoding.test.ts +85 -2
  320. package/src/query/value-encoding.ts +56 -6
  321. package/src/schema/create.test.ts +129 -42
  322. package/src/schema/create.ts +187 -47
  323. package/src/schema/generate-id.test.ts +57 -0
  324. package/src/schema/generate-id.ts +38 -0
  325. package/src/schema/serialize.test.ts +14 -2
  326. package/src/schema/type-conversion/create-sql-type-mapper.ts +7 -2
  327. package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
  328. package/src/schema/type-conversion/type-mapping.test.ts +25 -1
  329. package/src/schema/validator.test.ts +197 -0
  330. package/src/schema/validator.ts +231 -0
  331. package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +179 -129
  332. package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +143 -93
  333. package/src/schema-output/prisma.test.ts +536 -0
  334. package/src/schema-output/prisma.ts +573 -0
  335. package/src/util/default-database-adapter.ts +106 -0
  336. package/src/with-database.ts +22 -3
  337. package/tsdown.config.ts +6 -4
  338. package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
  339. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
  340. package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
  341. package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
  342. package/dist/adapters/drizzle/generate.d.ts +0 -30
  343. package/dist/adapters/drizzle/generate.d.ts.map +0 -1
  344. package/dist/adapters/drizzle/generate.js.map +0 -1
  345. package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
  346. package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
  347. package/dist/adapters/kysely/kysely-adapter.js +0 -17
  348. package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
  349. package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
  350. package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
  351. package/dist/adapters/shared/table-name-mapper.js +0 -43
  352. package/dist/adapters/shared/table-name-mapper.js.map +0 -1
  353. package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
  354. package/dist/schema-generator/schema-generator.d.ts +0 -15
  355. package/dist/schema-generator/schema-generator.d.ts.map +0 -1
  356. package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
  357. package/src/adapters/kysely/kysely-adapter.ts +0 -27
  358. package/src/adapters/shared/table-name-mapper.ts +0 -50
  359. package/src/schema-generator/schema-generator.ts +0 -12
  360. package/src/shared/config.ts +0 -10
  361. package/src/shared/connection-pool.ts +0 -24
  362. package/src/shared/prisma.ts +0 -45
@@ -9,14 +9,66 @@ import { RequestMiddlewareInputContext, RequestMiddlewareOutputContext } from ".
9
9
  import { parseFragnoResponse } from "./fragno-response.js";
10
10
  import { RequestContextStorage } from "./request-context-storage.js";
11
11
  import { bindServicesToContext } from "./bind-services.js";
12
- import { addRoute, createRouter, findRoute } from "../../../../node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js";
12
+ import { recordTraceEvent } from "../internal/trace-context.js";
13
+ import { addRoute, createRouter, findRoute } from "../../../../node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.js";
13
14
 
14
15
  //#region ../fragno/dist/api/fragment-instantiator.js
16
+ const serializeHeadersForTrace = (headers) => Array.from(headers.entries()).sort(([a], [b]) => a.localeCompare(b));
17
+ const serializeQueryForTrace = (query) => Array.from(query.entries()).sort(([a], [b]) => a.localeCompare(b));
18
+ const serializeBodyForTrace = (body) => {
19
+ if (body instanceof FormData) return {
20
+ type: "form-data",
21
+ entries: Array.from(body.entries()).map(([key, value]) => {
22
+ if (value instanceof Blob) return [key, {
23
+ type: "blob",
24
+ size: value.size,
25
+ mime: value.type
26
+ }];
27
+ return [key, value];
28
+ })
29
+ };
30
+ if (body instanceof Blob) return {
31
+ type: "blob",
32
+ size: body.size,
33
+ mime: body.type
34
+ };
35
+ if (body instanceof ReadableStream) return { type: "stream" };
36
+ return body;
37
+ };
38
+ const INTERNAL_LINKED_FRAGMENT_NAME = "_fragno_internal";
39
+ const INTERNAL_ROUTE_PREFIX = "/_internal";
40
+ function normalizeRoutePrefix(prefix) {
41
+ if (!prefix.startsWith("/")) prefix = `/${prefix}`;
42
+ return prefix.endsWith("/") && prefix.length > 1 ? prefix.slice(0, -1) : prefix;
43
+ }
44
+ function joinRoutePath(prefix, path) {
45
+ const normalizedPrefix = normalizeRoutePrefix(prefix);
46
+ if (!path || path === "/") return normalizedPrefix;
47
+ return `${normalizedPrefix}${path.startsWith("/") ? path : `/${path}`}`;
48
+ }
49
+ function collectLinkedFragmentRoutes(linkedFragments) {
50
+ const linkedRoutes = [];
51
+ for (const [name, fragment] of Object.entries(linkedFragments)) {
52
+ if (name !== INTERNAL_LINKED_FRAGMENT_NAME) continue;
53
+ const internalRoutes = fragment.routes ?? [];
54
+ if (internalRoutes.length === 0) continue;
55
+ for (const route of internalRoutes) linkedRoutes.push({
56
+ ...route,
57
+ path: joinRoutePath(INTERNAL_ROUTE_PREFIX, route.path),
58
+ __internal: {
59
+ fragment,
60
+ originalPath: route.path,
61
+ routes: internalRoutes
62
+ }
63
+ });
64
+ }
65
+ return linkedRoutes;
66
+ }
15
67
  /**
16
68
  * Instantiated fragment class with encapsulated state.
17
69
  * Provides the same public API as the old FragnoInstantiatedFragment but with better encapsulation.
18
70
  */
19
- var FragnoInstantiatedFragment = class {
71
+ var FragnoInstantiatedFragment = class FragnoInstantiatedFragment$1 {
20
72
  [instantiatedFragmentFakeSymbol] = instantiatedFragmentFakeSymbol;
21
73
  #name;
22
74
  #routes;
@@ -31,6 +83,7 @@ var FragnoInstantiatedFragment = class {
31
83
  #createRequestStorage;
32
84
  #options;
33
85
  #linkedFragments;
86
+ #internalData;
34
87
  constructor(params) {
35
88
  this.#name = params.name;
36
89
  this.#routes = params.routes;
@@ -43,6 +96,7 @@ var FragnoInstantiatedFragment = class {
43
96
  this.#createRequestStorage = params.createRequestStorage;
44
97
  this.#options = params.options;
45
98
  this.#linkedFragments = params.linkedFragments ?? {};
99
+ this.#internalData = params.internalData ?? {};
46
100
  this.#router = createRouter();
47
101
  for (const routeConfig of this.#routes) addRoute(this.#router, routeConfig.method.toUpperCase(), routeConfig.path, routeConfig);
48
102
  this.handler = this.handler.bind(this);
@@ -66,7 +120,8 @@ var FragnoInstantiatedFragment = class {
66
120
  return {
67
121
  deps: this.#deps,
68
122
  options: this.#options,
69
- linkedFragments: this.#linkedFragments
123
+ linkedFragments: this.#linkedFragments,
124
+ ...this.#internalData
70
125
  };
71
126
  }
72
127
  /**
@@ -160,26 +215,65 @@ var FragnoInstantiatedFragment = class {
160
215
  error: `Fragno: Route for '${this.#name}' not found`,
161
216
  code: "ROUTE_NOT_FOUND"
162
217
  }, { status: 404 });
218
+ const routeConfig = route.data;
219
+ const expectedContentType = routeConfig.contentType ?? "application/json";
163
220
  let requestBody = void 0;
164
221
  let rawBody = void 0;
165
222
  if (req.body instanceof ReadableStream) {
166
- rawBody = await req.clone().text();
167
- if (rawBody) try {
168
- requestBody = JSON.parse(rawBody);
169
- } catch {
170
- requestBody = void 0;
223
+ const requestContentType = (req.headers.get("content-type") ?? "").toLowerCase();
224
+ if (expectedContentType === "multipart/form-data") {
225
+ if (!requestContentType.includes("multipart/form-data")) return Response.json({
226
+ error: `This endpoint expects multipart/form-data, but received: ${requestContentType || "no content-type"}`,
227
+ code: "UNSUPPORTED_MEDIA_TYPE"
228
+ }, { status: 415 });
229
+ try {
230
+ requestBody = await req.formData();
231
+ } catch {
232
+ return Response.json({
233
+ error: "Failed to parse multipart form data",
234
+ code: "INVALID_REQUEST_BODY"
235
+ }, { status: 400 });
236
+ }
237
+ } else if (expectedContentType === "application/octet-stream") {
238
+ if (!requestContentType.includes("application/octet-stream")) return Response.json({
239
+ error: `This endpoint expects application/octet-stream, but received: ${requestContentType || "no content-type"}`,
240
+ code: "UNSUPPORTED_MEDIA_TYPE"
241
+ }, { status: 415 });
242
+ requestBody = req.body ?? new ReadableStream();
243
+ } else {
244
+ if (requestContentType.includes("multipart/form-data")) return Response.json({
245
+ error: `This endpoint expects JSON, but received multipart/form-data. Use a route with contentType: "multipart/form-data" for file uploads.`,
246
+ code: "UNSUPPORTED_MEDIA_TYPE"
247
+ }, { status: 415 });
248
+ rawBody = await req.clone().text();
249
+ if (rawBody) try {
250
+ requestBody = JSON.parse(rawBody);
251
+ } catch {
252
+ requestBody = void 0;
253
+ }
171
254
  }
172
255
  }
256
+ const decodedRouteParams = {};
257
+ for (const [key, value] of Object.entries(route.params ?? {})) decodedRouteParams[key] = decodeURIComponent(value);
173
258
  const requestState = new MutableRequestState({
174
- pathParams: route.params ?? {},
259
+ pathParams: decodedRouteParams,
175
260
  searchParams: url.searchParams,
176
261
  body: requestBody,
177
262
  headers: new Headers(req.headers)
178
263
  });
179
264
  const executeRequest = async () => {
180
- if (this.#middlewareHandler) {
181
- const middlewareResult = await this.#executeMiddleware(req, route, requestState);
182
- if (middlewareResult !== void 0) return middlewareResult;
265
+ const middlewareResult = await this.#executeMiddleware(req, route, requestState);
266
+ if (middlewareResult !== void 0) return middlewareResult;
267
+ const internalMeta = routeConfig.__internal;
268
+ if (internalMeta) {
269
+ const internalResult = await FragnoInstantiatedFragment$1.#runMiddlewareForFragment(internalMeta.fragment, {
270
+ req,
271
+ method: routeConfig.method,
272
+ path: internalMeta.originalPath,
273
+ requestState,
274
+ routes: internalMeta.routes
275
+ });
276
+ if (internalResult !== void 0) return internalResult;
183
277
  }
184
278
  return this.#executeHandler(req, route, requestState, rawBody);
185
279
  };
@@ -215,6 +309,15 @@ var FragnoInstantiatedFragment = class {
215
309
  inputSchema: route.inputSchema,
216
310
  shouldValidateInput: true
217
311
  });
312
+ recordTraceEvent({
313
+ type: "route-input",
314
+ method: route.method,
315
+ path: route.path,
316
+ pathParams: pathParams ?? {},
317
+ queryParams: serializeQueryForTrace(searchParams),
318
+ headers: serializeHeadersForTrace(requestHeaders),
319
+ body: serializeBodyForTrace(body)
320
+ });
218
321
  const outputContext = new RequestOutputContext(route.outputSchema);
219
322
  const executeHandler = async () => {
220
323
  try {
@@ -236,20 +339,43 @@ var FragnoInstantiatedFragment = class {
236
339
  * Returns undefined if middleware allows the request to continue to the handler.
237
340
  */
238
341
  async #executeMiddleware(req, route, requestState) {
239
- if (!this.#middlewareHandler || !route) return;
342
+ if (!route) return;
240
343
  const { path } = route.data;
241
- const middlewareInputContext = new RequestMiddlewareInputContext(this.#routes, {
344
+ return FragnoInstantiatedFragment$1.#runMiddlewareForFragment(this, {
345
+ req,
242
346
  method: req.method,
243
347
  path,
244
- request: req,
245
- state: requestState
348
+ requestState
349
+ });
350
+ }
351
+ static async #runMiddlewareForFragment(fragment, options) {
352
+ if (!fragment.#middlewareHandler) return;
353
+ const middlewareInputContext = new RequestMiddlewareInputContext(options.routes ?? fragment.#routes, {
354
+ method: options.method,
355
+ path: options.path,
356
+ request: options.req,
357
+ state: options.requestState
246
358
  });
247
- const middlewareOutputContext = new RequestMiddlewareOutputContext(this.#deps, this.#services);
359
+ const middlewareOutputContext = new RequestMiddlewareOutputContext(fragment.#deps, fragment.#services);
248
360
  try {
249
- const middlewareResult = await this.#middlewareHandler(middlewareInputContext, middlewareOutputContext);
361
+ const middlewareResult = await fragment.#middlewareHandler(middlewareInputContext, middlewareOutputContext);
362
+ recordTraceEvent({
363
+ type: "middleware-decision",
364
+ method: options.method,
365
+ path: options.path,
366
+ outcome: middlewareResult ? "deny" : "allow",
367
+ status: middlewareResult?.status
368
+ });
250
369
  if (middlewareResult !== void 0) return middlewareResult;
251
370
  } catch (error) {
252
371
  console.error("Error in middleware", error);
372
+ recordTraceEvent({
373
+ type: "middleware-decision",
374
+ method: options.method,
375
+ path: options.path,
376
+ outcome: "deny",
377
+ status: error instanceof FragnoApiError ? error.status : 500
378
+ });
253
379
  if (error instanceof FragnoApiError) return error.toResponse();
254
380
  return Response.json({
255
381
  error: "Internal server error",
@@ -275,6 +401,15 @@ var FragnoInstantiatedFragment = class {
275
401
  state: requestState,
276
402
  rawBody
277
403
  });
404
+ recordTraceEvent({
405
+ type: "route-input",
406
+ method: req.method,
407
+ path,
408
+ pathParams: inputContext.pathParams,
409
+ queryParams: serializeQueryForTrace(requestState.searchParams),
410
+ headers: serializeHeadersForTrace(requestState.headers),
411
+ body: serializeBodyForTrace(requestState.body)
412
+ });
278
413
  const outputContext = new RequestOutputContext(outputSchema);
279
414
  try {
280
415
  const contextForHandler = this.#handlerThisContext ?? {};
@@ -397,6 +532,12 @@ function instantiateFragment(definition, config, routesOrFactories, options, ser
397
532
  });
398
533
  const serviceContext = contexts?.serviceContext;
399
534
  const handlerContext = contexts?.handlerContext;
535
+ const internalData = definition.internalDataFactory?.({
536
+ config,
537
+ options,
538
+ deps,
539
+ linkedFragments: linkedFragmentInstances
540
+ }) ?? {};
400
541
  const boundServices = serviceContext ? bindServicesToContext(services, serviceContext) : services;
401
542
  const routes = resolveRouteFactories({
402
543
  config,
@@ -404,6 +545,8 @@ function instantiateFragment(definition, config, routesOrFactories, options, ser
404
545
  services: boundServices,
405
546
  serviceDeps: serviceImplementations ?? {}
406
547
  }, routesOrFactories);
548
+ const linkedRoutes = collectLinkedFragmentRoutes(linkedFragmentInstances);
549
+ const finalRoutes = linkedRoutes.length > 0 ? [...routes, ...linkedRoutes] : routes;
407
550
  const mountRoute = getMountRoute({
408
551
  name: definition.name,
409
552
  mountRoute: options.mountRoute
@@ -415,7 +558,7 @@ function instantiateFragment(definition, config, routesOrFactories, options, ser
415
558
  }) : void 0;
416
559
  return new FragnoInstantiatedFragment({
417
560
  name: definition.name,
418
- routes,
561
+ routes: finalRoutes,
419
562
  deps,
420
563
  services: boundServices,
421
564
  mountRoute,
@@ -424,7 +567,8 @@ function instantiateFragment(definition, config, routesOrFactories, options, ser
424
567
  storage,
425
568
  createRequestStorage: createRequestStorageWithContext,
426
569
  options,
427
- linkedFragments: linkedFragmentInstances
570
+ linkedFragments: linkedFragmentInstances,
571
+ internalData
428
572
  });
429
573
  }
430
574
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"fragment-instantiator.js","names":["#name","#routes","#deps","#services","#mountRoute","#serviceThisContext","#handlerThisContext","#contextStorage","#createRequestStorage","#options","#linkedFragments","#router","#middlewareHandler","#withRequestStorage","#executeMiddleware","#executeHandler","FragmentInstantiationBuilder","#definition","#config"],"sources":["../../../../../../fragno/dist/api/fragment-instantiator.js"],"sourcesContent":["import { instantiatedFragmentFakeSymbol } from \"../internal/symbols.js\";\nimport { resolveRouteFactories } from \"./route.js\";\nimport { FragnoApiError } from \"./error.js\";\nimport { getMountRoute } from \"./internal/route.js\";\nimport { RequestInputContext } from \"./request-input-context.js\";\nimport { RequestOutputContext } from \"./request-output-context.js\";\nimport { MutableRequestState } from \"./mutable-request-state.js\";\nimport { RequestMiddlewareInputContext, RequestMiddlewareOutputContext } from \"./request-middleware.js\";\nimport { parseFragnoResponse } from \"./fragno-response.js\";\nimport { RequestContextStorage } from \"./request-context-storage.js\";\nimport { bindServicesToContext } from \"./bind-services.js\";\nimport { addRoute, createRouter, findRoute } from \"rou3\";\n\n//#region src/api/fragment-instantiator.ts\n/**\n* Instantiated fragment class with encapsulated state.\n* Provides the same public API as the old FragnoInstantiatedFragment but with better encapsulation.\n*/\nvar FragnoInstantiatedFragment = class {\n\t[instantiatedFragmentFakeSymbol] = instantiatedFragmentFakeSymbol;\n\t#name;\n\t#routes;\n\t#deps;\n\t#services;\n\t#mountRoute;\n\t#router;\n\t#middlewareHandler;\n\t#serviceThisContext;\n\t#handlerThisContext;\n\t#contextStorage;\n\t#createRequestStorage;\n\t#options;\n\t#linkedFragments;\n\tconstructor(params) {\n\t\tthis.#name = params.name;\n\t\tthis.#routes = params.routes;\n\t\tthis.#deps = params.deps;\n\t\tthis.#services = params.services;\n\t\tthis.#mountRoute = params.mountRoute;\n\t\tthis.#serviceThisContext = params.serviceThisContext;\n\t\tthis.#handlerThisContext = params.handlerThisContext;\n\t\tthis.#contextStorage = params.storage;\n\t\tthis.#createRequestStorage = params.createRequestStorage;\n\t\tthis.#options = params.options;\n\t\tthis.#linkedFragments = params.linkedFragments ?? {};\n\t\tthis.#router = createRouter();\n\t\tfor (const routeConfig of this.#routes) addRoute(this.#router, routeConfig.method.toUpperCase(), routeConfig.path, routeConfig);\n\t\tthis.handler = this.handler.bind(this);\n\t}\n\tget name() {\n\t\treturn this.#name;\n\t}\n\tget routes() {\n\t\treturn this.#routes;\n\t}\n\tget services() {\n\t\treturn this.#services;\n\t}\n\tget mountRoute() {\n\t\treturn this.#mountRoute;\n\t}\n\t/**\n\t* @internal\n\t*/\n\tget $internal() {\n\t\treturn {\n\t\t\tdeps: this.#deps,\n\t\t\toptions: this.#options,\n\t\t\tlinkedFragments: this.#linkedFragments\n\t\t};\n\t}\n\t/**\n\t* Add middleware to this fragment.\n\t* Middleware can inspect and modify requests before they reach handlers.\n\t*/\n\twithMiddleware(handler) {\n\t\tif (this.#middlewareHandler) throw new Error(\"Middleware already set\");\n\t\tthis.#middlewareHandler = handler;\n\t\treturn this;\n\t}\n\t#withRequestStorage(callback) {\n\t\tif (!this.#serviceThisContext && !this.#handlerThisContext) return callback();\n\t\tconst storageData = this.#createRequestStorage ? this.#createRequestStorage() : {};\n\t\treturn this.#contextStorage.run(storageData, callback);\n\t}\n\tinContext(callback) {\n\t\tif (this.#handlerThisContext) {\n\t\t\tconst boundCallback = callback.bind(this.#handlerThisContext);\n\t\t\treturn this.#withRequestStorage(boundCallback);\n\t\t}\n\t\treturn this.#withRequestStorage(callback);\n\t}\n\t/**\n\t* Get framework-specific handlers for this fragment.\n\t* Use this to integrate the fragment with different fullstack frameworks.\n\t*/\n\thandlersFor(framework) {\n\t\tconst handler = this.handler.bind(this);\n\t\tif (framework === \"h3\" || framework === \"nuxt\") throw new Error(`To get handlers for h3, use the 'fromWebHandler' utility function:\n import { fromWebHandler } from \"h3\";\n export default fromWebHandler(myFragment().handler);`);\n\t\treturn {\n\t\t\tastro: { ALL: handler },\n\t\t\t\"react-router\": {\n\t\t\t\tloader: ({ request }) => handler(request),\n\t\t\t\taction: ({ request }) => handler(request)\n\t\t\t},\n\t\t\t\"next-js\": {\n\t\t\t\tGET: handler,\n\t\t\t\tPOST: handler,\n\t\t\t\tPUT: handler,\n\t\t\t\tDELETE: handler,\n\t\t\t\tPATCH: handler,\n\t\t\t\tHEAD: handler,\n\t\t\t\tOPTIONS: handler\n\t\t\t},\n\t\t\t\"svelte-kit\": {\n\t\t\t\tGET: handler,\n\t\t\t\tPOST: handler,\n\t\t\t\tPUT: handler,\n\t\t\t\tDELETE: handler,\n\t\t\t\tPATCH: handler,\n\t\t\t\tHEAD: handler,\n\t\t\t\tOPTIONS: handler\n\t\t\t},\n\t\t\t\"solid-start\": {\n\t\t\t\tGET: ({ request }) => handler(request),\n\t\t\t\tPOST: ({ request }) => handler(request),\n\t\t\t\tPUT: ({ request }) => handler(request),\n\t\t\t\tDELETE: ({ request }) => handler(request),\n\t\t\t\tPATCH: ({ request }) => handler(request),\n\t\t\t\tHEAD: ({ request }) => handler(request),\n\t\t\t\tOPTIONS: ({ request }) => handler(request)\n\t\t\t},\n\t\t\t\"tanstack-start\": {\n\t\t\t\tGET: ({ request }) => handler(request),\n\t\t\t\tPOST: ({ request }) => handler(request),\n\t\t\t\tPUT: ({ request }) => handler(request),\n\t\t\t\tDELETE: ({ request }) => handler(request),\n\t\t\t\tPATCH: ({ request }) => handler(request),\n\t\t\t\tHEAD: ({ request }) => handler(request),\n\t\t\t\tOPTIONS: ({ request }) => handler(request)\n\t\t\t}\n\t\t}[framework];\n\t}\n\t/**\n\t* Main request handler for this fragment.\n\t* Handles routing, middleware, and error handling.\n\t*/\n\tasync handler(req) {\n\t\tconst url = new URL(req.url);\n\t\tconst pathname = url.pathname;\n\t\tconst matchRoute = pathname.startsWith(this.#mountRoute) ? pathname.slice(this.#mountRoute.length) : null;\n\t\tif (matchRoute === null) return Response.json({\n\t\t\terror: `Fragno: Route for '${this.#name}' not found. Is the fragment mounted on the right route? Expecting: '${this.#mountRoute}'.`,\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst route = findRoute(this.#router, req.method, matchRoute);\n\t\tif (!route) return Response.json({\n\t\t\terror: `Fragno: Route for '${this.#name}' not found`,\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tlet requestBody = void 0;\n\t\tlet rawBody = void 0;\n\t\tif (req.body instanceof ReadableStream) {\n\t\t\trawBody = await req.clone().text();\n\t\t\tif (rawBody) try {\n\t\t\t\trequestBody = JSON.parse(rawBody);\n\t\t\t} catch {\n\t\t\t\trequestBody = void 0;\n\t\t\t}\n\t\t}\n\t\tconst requestState = new MutableRequestState({\n\t\t\tpathParams: route.params ?? {},\n\t\t\tsearchParams: url.searchParams,\n\t\t\tbody: requestBody,\n\t\t\theaders: new Headers(req.headers)\n\t\t});\n\t\tconst executeRequest = async () => {\n\t\t\tif (this.#middlewareHandler) {\n\t\t\t\tconst middlewareResult = await this.#executeMiddleware(req, route, requestState);\n\t\t\t\tif (middlewareResult !== void 0) return middlewareResult;\n\t\t\t}\n\t\t\treturn this.#executeHandler(req, route, requestState, rawBody);\n\t\t};\n\t\treturn this.#withRequestStorage(executeRequest);\n\t}\n\t/**\n\t* Call a route directly with typed inputs and outputs.\n\t* Useful for testing and server-side route calls.\n\t*/\n\tasync callRoute(method, path, inputOptions) {\n\t\treturn parseFragnoResponse(await this.callRouteRaw(method, path, inputOptions));\n\t}\n\t/**\n\t* Call a route directly and get the raw Response object.\n\t* Useful for testing and server-side route calls.\n\t*/\n\tasync callRouteRaw(method, path, inputOptions) {\n\t\tconst route = this.#routes.find((r) => r.method === method && r.path === path);\n\t\tif (!route) return Response.json({\n\t\t\terror: `Route ${method} ${path} not found`,\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst { pathParams = {}, body, query, headers } = inputOptions || {};\n\t\tconst searchParams = query instanceof URLSearchParams ? query : query ? new URLSearchParams(query) : new URLSearchParams();\n\t\tconst requestHeaders = headers instanceof Headers ? headers : headers ? new Headers(headers) : new Headers();\n\t\tconst inputContext = new RequestInputContext({\n\t\t\tpath: route.path,\n\t\t\tmethod: route.method,\n\t\t\tpathParams,\n\t\t\tsearchParams,\n\t\t\theaders: requestHeaders,\n\t\t\tparsedBody: body,\n\t\t\tinputSchema: route.inputSchema,\n\t\t\tshouldValidateInput: true\n\t\t});\n\t\tconst outputContext = new RequestOutputContext(route.outputSchema);\n\t\tconst executeHandler = async () => {\n\t\t\ttry {\n\t\t\t\tconst thisContext = this.#handlerThisContext ?? {};\n\t\t\t\treturn await route.handler.call(thisContext, inputContext, outputContext);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Error in callRoute handler\", error);\n\t\t\t\tif (error instanceof FragnoApiError) return error.toResponse();\n\t\t\t\treturn Response.json({\n\t\t\t\t\terror: \"Internal server error\",\n\t\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\"\n\t\t\t\t}, { status: 500 });\n\t\t\t}\n\t\t};\n\t\treturn this.#withRequestStorage(executeHandler);\n\t}\n\t/**\n\t* Execute middleware for a request.\n\t* Returns undefined if middleware allows the request to continue to the handler.\n\t*/\n\tasync #executeMiddleware(req, route, requestState) {\n\t\tif (!this.#middlewareHandler || !route) return;\n\t\tconst { path } = route.data;\n\t\tconst middlewareInputContext = new RequestMiddlewareInputContext(this.#routes, {\n\t\t\tmethod: req.method,\n\t\t\tpath,\n\t\t\trequest: req,\n\t\t\tstate: requestState\n\t\t});\n\t\tconst middlewareOutputContext = new RequestMiddlewareOutputContext(this.#deps, this.#services);\n\t\ttry {\n\t\t\tconst middlewareResult = await this.#middlewareHandler(middlewareInputContext, middlewareOutputContext);\n\t\t\tif (middlewareResult !== void 0) return middlewareResult;\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error in middleware\", error);\n\t\t\tif (error instanceof FragnoApiError) return error.toResponse();\n\t\t\treturn Response.json({\n\t\t\t\terror: \"Internal server error\",\n\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\"\n\t\t\t}, { status: 500 });\n\t\t}\n\t}\n\t/**\n\t* Execute a route handler with proper error handling.\n\t*/\n\tasync #executeHandler(req, route, requestState, rawBody) {\n\t\tif (!route) return Response.json({\n\t\t\terror: \"Route not found\",\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst { handler, inputSchema, outputSchema, path } = route.data;\n\t\tconst inputContext = await RequestInputContext.fromRequest({\n\t\t\trequest: req,\n\t\t\tmethod: req.method,\n\t\t\tpath,\n\t\t\tpathParams: route.params ?? {},\n\t\t\tinputSchema,\n\t\t\tstate: requestState,\n\t\t\trawBody\n\t\t});\n\t\tconst outputContext = new RequestOutputContext(outputSchema);\n\t\ttry {\n\t\t\tconst contextForHandler = this.#handlerThisContext ?? {};\n\t\t\treturn await handler.call(contextForHandler, inputContext, outputContext);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error in handler\", error);\n\t\t\tif (error instanceof FragnoApiError) return error.toResponse();\n\t\t\treturn Response.json({\n\t\t\t\terror: \"Internal server error\",\n\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\"\n\t\t\t}, { status: 500 });\n\t\t}\n\t}\n};\n/**\n* Core instantiation function that creates a fragment instance from a definition.\n* This function validates dependencies, calls all callbacks, and wires everything together.\n*/\nfunction instantiateFragment(definition, config, routesOrFactories, options, serviceImplementations, instantiationOptions) {\n\tconst { dryRun = false } = instantiationOptions ?? {};\n\tconst serviceDependencies = definition.serviceDependencies;\n\tif (serviceDependencies) for (const [serviceName, meta] of Object.entries(serviceDependencies)) {\n\t\tconst metadata = meta;\n\t\tconst implementation = serviceImplementations?.[serviceName];\n\t\tif (metadata.required && !implementation) throw new Error(`Fragment '${definition.name}' requires service '${metadata.name}' but it was not provided`);\n\t}\n\tlet deps;\n\ttry {\n\t\tdeps = definition.dependencies?.({\n\t\t\tconfig,\n\t\t\toptions\n\t\t}) ?? {};\n\t} catch (error) {\n\t\tif (dryRun) {\n\t\t\tconsole.warn(\"Warning: Failed to initialize dependencies in dry run mode:\", error instanceof Error ? error.message : String(error));\n\t\t\tdeps = {};\n\t\t} else throw error;\n\t}\n\tconst linkedFragmentInstances = {};\n\tconst linkedFragmentServices = {};\n\tif (definition.linkedFragments) for (const [name, callback] of Object.entries(definition.linkedFragments)) {\n\t\tconst linkedFragment = callback({\n\t\t\tconfig,\n\t\t\toptions,\n\t\t\tserviceDependencies: serviceImplementations\n\t\t});\n\t\tlinkedFragmentInstances[name] = linkedFragment;\n\t\tconst services$1 = linkedFragment.services;\n\t\tfor (const [serviceName, service] of Object.entries(services$1)) linkedFragmentServices[serviceName] = service;\n\t}\n\tconst defineService = (services$1) => services$1;\n\tconst privateServices = { ...linkedFragmentServices };\n\tif (definition.privateServices) for (const [serviceName, factory] of Object.entries(definition.privateServices)) {\n\t\tconst serviceFactory = factory;\n\t\ttry {\n\t\t\tprivateServices[serviceName] = serviceFactory({\n\t\t\t\tconfig,\n\t\t\t\toptions,\n\t\t\t\tdeps,\n\t\t\t\tserviceDeps: serviceImplementations ?? {},\n\t\t\t\tprivateServices,\n\t\t\t\tdefineService\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (dryRun) {\n\t\t\t\tconsole.warn(`Warning: Failed to initialize private service '${serviceName}' in dry run mode:`, error instanceof Error ? error.message : String(error));\n\t\t\t\tprivateServices[serviceName] = {};\n\t\t\t} else throw error;\n\t\t}\n\t}\n\tlet baseServices;\n\ttry {\n\t\tbaseServices = definition.baseServices?.({\n\t\t\tconfig,\n\t\t\toptions,\n\t\t\tdeps,\n\t\t\tserviceDeps: serviceImplementations ?? {},\n\t\t\tprivateServices,\n\t\t\tdefineService\n\t\t}) ?? {};\n\t} catch (error) {\n\t\tif (dryRun) {\n\t\t\tconsole.warn(\"Warning: Failed to initialize base services in dry run mode:\", error instanceof Error ? error.message : String(error));\n\t\t\tbaseServices = {};\n\t\t} else throw error;\n\t}\n\tconst namedServices = {};\n\tif (definition.namedServices) for (const [serviceName, factory] of Object.entries(definition.namedServices)) {\n\t\tconst serviceFactory = factory;\n\t\ttry {\n\t\t\tnamedServices[serviceName] = serviceFactory({\n\t\t\t\tconfig,\n\t\t\t\toptions,\n\t\t\t\tdeps,\n\t\t\t\tserviceDeps: serviceImplementations ?? {},\n\t\t\t\tprivateServices,\n\t\t\t\tdefineService\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (dryRun) {\n\t\t\t\tconsole.warn(`Warning: Failed to initialize service '${serviceName}' in dry run mode:`, error instanceof Error ? error.message : String(error));\n\t\t\t\tnamedServices[serviceName] = {};\n\t\t\t} else throw error;\n\t\t}\n\t}\n\tconst services = {\n\t\t...baseServices,\n\t\t...namedServices\n\t};\n\tconst storage = definition.getExternalStorage ? definition.getExternalStorage({\n\t\tconfig,\n\t\toptions,\n\t\tdeps\n\t}) : new RequestContextStorage();\n\tconst contexts = definition.createThisContext?.({\n\t\tconfig,\n\t\toptions,\n\t\tdeps,\n\t\tstorage\n\t});\n\tconst serviceContext = contexts?.serviceContext;\n\tconst handlerContext = contexts?.handlerContext;\n\tconst boundServices = serviceContext ? bindServicesToContext(services, serviceContext) : services;\n\tconst routes = resolveRouteFactories({\n\t\tconfig,\n\t\tdeps,\n\t\tservices: boundServices,\n\t\tserviceDeps: serviceImplementations ?? {}\n\t}, routesOrFactories);\n\tconst mountRoute = getMountRoute({\n\t\tname: definition.name,\n\t\tmountRoute: options.mountRoute\n\t});\n\tconst createRequestStorageWithContext = definition.createRequestStorage ? () => definition.createRequestStorage({\n\t\tconfig,\n\t\toptions,\n\t\tdeps\n\t}) : void 0;\n\treturn new FragnoInstantiatedFragment({\n\t\tname: definition.name,\n\t\troutes,\n\t\tdeps,\n\t\tservices: boundServices,\n\t\tmountRoute,\n\t\tserviceThisContext: serviceContext,\n\t\thandlerThisContext: handlerContext,\n\t\tstorage,\n\t\tcreateRequestStorage: createRequestStorageWithContext,\n\t\toptions,\n\t\tlinkedFragments: linkedFragmentInstances\n\t});\n}\n/**\n* Fluent builder for instantiating fragments.\n* Provides a type-safe API for configuring and building fragment instances.\n*/\nvar FragmentInstantiationBuilder = class FragmentInstantiationBuilder {\n\t#definition;\n\t#config;\n\t#routes;\n\t#options;\n\t#services;\n\tconstructor(definition, routes) {\n\t\tthis.#definition = definition;\n\t\tthis.#routes = routes;\n\t}\n\t/**\n\t* Get the fragment definition\n\t*/\n\tget definition() {\n\t\treturn this.#definition;\n\t}\n\t/**\n\t* Get the configured routes\n\t*/\n\tget routes() {\n\t\treturn this.#routes ?? [];\n\t}\n\t/**\n\t* Get the configuration\n\t*/\n\tget config() {\n\t\treturn this.#config;\n\t}\n\t/**\n\t* Get the options\n\t*/\n\tget options() {\n\t\treturn this.#options;\n\t}\n\t/**\n\t* Set the configuration for the fragment\n\t*/\n\twithConfig(config) {\n\t\tthis.#config = config;\n\t\treturn this;\n\t}\n\t/**\n\t* Set the routes for the fragment\n\t*/\n\twithRoutes(routes) {\n\t\tconst newBuilder = new FragmentInstantiationBuilder(this.#definition, routes);\n\t\tnewBuilder.#config = this.#config;\n\t\tnewBuilder.#options = this.#options;\n\t\tnewBuilder.#services = this.#services;\n\t\treturn newBuilder;\n\t}\n\t/**\n\t* Set the options for the fragment (e.g., mountRoute, databaseAdapter)\n\t*/\n\twithOptions(options) {\n\t\tthis.#options = options;\n\t\treturn this;\n\t}\n\t/**\n\t* Provide implementations for services that this fragment uses\n\t*/\n\twithServices(services) {\n\t\tthis.#services = services;\n\t\treturn this;\n\t}\n\t/**\n\t* Build and return the instantiated fragment\n\t*/\n\tbuild() {\n\t\tconst dryRun = process.env[\"FRAGNO_INIT_DRY_RUN\"] === \"true\";\n\t\treturn instantiateFragment(this.#definition, this.#config ?? {}, this.#routes ?? [], this.#options ?? {}, this.#services, { dryRun });\n\t}\n};\n/**\n* Create a fluent builder for instantiating a fragment.\n*\n* @example\n* ```ts\n* const fragment = instantiate(myFragmentDefinition)\n* .withConfig({ apiKey: \"key\" })\n* .withRoutes([route1, route2])\n* .withOptions({ mountRoute: \"/api\" })\n* .build();\n* ```\n*/\nfunction instantiate(definition) {\n\treturn new FragmentInstantiationBuilder(definition);\n}\n\n//#endregion\nexport { FragmentInstantiationBuilder, FragnoInstantiatedFragment, instantiate, instantiateFragment };\n//# sourceMappingURL=fragment-instantiator.js.map"],"mappings":"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"}
1
+ {"version":3,"file":"fragment-instantiator.js","names":["FragnoInstantiatedFragment","#name","#routes","#deps","#services","#mountRoute","#serviceThisContext","#handlerThisContext","#contextStorage","#createRequestStorage","#options","#linkedFragments","#internalData","#router","#middlewareHandler","#withRequestStorage","#executeMiddleware","#runMiddlewareForFragment","#executeHandler","FragmentInstantiationBuilder","#definition","#config"],"sources":["../../../../../../fragno/dist/api/fragment-instantiator.js"],"sourcesContent":["import { instantiatedFragmentFakeSymbol } from \"../internal/symbols.js\";\nimport { resolveRouteFactories } from \"./route.js\";\nimport { FragnoApiError } from \"./error.js\";\nimport { getMountRoute } from \"./internal/route.js\";\nimport { RequestInputContext } from \"./request-input-context.js\";\nimport { RequestOutputContext } from \"./request-output-context.js\";\nimport { MutableRequestState } from \"./mutable-request-state.js\";\nimport { RequestMiddlewareInputContext, RequestMiddlewareOutputContext } from \"./request-middleware.js\";\nimport { parseFragnoResponse } from \"./fragno-response.js\";\nimport { RequestContextStorage } from \"./request-context-storage.js\";\nimport { bindServicesToContext } from \"./bind-services.js\";\nimport { recordTraceEvent } from \"../internal/trace-context.js\";\nimport { addRoute, createRouter, findRoute } from \"rou3\";\n\n//#region src/api/fragment-instantiator.ts\nconst serializeHeadersForTrace = (headers) => Array.from(headers.entries()).sort(([a], [b]) => a.localeCompare(b));\nconst serializeQueryForTrace = (query) => Array.from(query.entries()).sort(([a], [b]) => a.localeCompare(b));\nconst serializeBodyForTrace = (body) => {\n\tif (body instanceof FormData) return {\n\t\ttype: \"form-data\",\n\t\tentries: Array.from(body.entries()).map(([key, value]) => {\n\t\t\tif (value instanceof Blob) return [key, {\n\t\t\t\ttype: \"blob\",\n\t\t\t\tsize: value.size,\n\t\t\t\tmime: value.type\n\t\t\t}];\n\t\t\treturn [key, value];\n\t\t})\n\t};\n\tif (body instanceof Blob) return {\n\t\ttype: \"blob\",\n\t\tsize: body.size,\n\t\tmime: body.type\n\t};\n\tif (body instanceof ReadableStream) return { type: \"stream\" };\n\treturn body;\n};\nconst INTERNAL_LINKED_FRAGMENT_NAME = \"_fragno_internal\";\nconst INTERNAL_ROUTE_PREFIX = \"/_internal\";\nfunction normalizeRoutePrefix(prefix) {\n\tif (!prefix.startsWith(\"/\")) prefix = `/${prefix}`;\n\treturn prefix.endsWith(\"/\") && prefix.length > 1 ? prefix.slice(0, -1) : prefix;\n}\nfunction joinRoutePath(prefix, path) {\n\tconst normalizedPrefix = normalizeRoutePrefix(prefix);\n\tif (!path || path === \"/\") return normalizedPrefix;\n\treturn `${normalizedPrefix}${path.startsWith(\"/\") ? path : `/${path}`}`;\n}\nfunction collectLinkedFragmentRoutes(linkedFragments) {\n\tconst linkedRoutes = [];\n\tfor (const [name, fragment] of Object.entries(linkedFragments)) {\n\t\tif (name !== INTERNAL_LINKED_FRAGMENT_NAME) continue;\n\t\tconst internalRoutes = fragment.routes ?? [];\n\t\tif (internalRoutes.length === 0) continue;\n\t\tfor (const route of internalRoutes) linkedRoutes.push({\n\t\t\t...route,\n\t\t\tpath: joinRoutePath(INTERNAL_ROUTE_PREFIX, route.path),\n\t\t\t__internal: {\n\t\t\t\tfragment,\n\t\t\t\toriginalPath: route.path,\n\t\t\t\troutes: internalRoutes\n\t\t\t}\n\t\t});\n\t}\n\treturn linkedRoutes;\n}\n/**\n* Instantiated fragment class with encapsulated state.\n* Provides the same public API as the old FragnoInstantiatedFragment but with better encapsulation.\n*/\nvar FragnoInstantiatedFragment = class FragnoInstantiatedFragment {\n\t[instantiatedFragmentFakeSymbol] = instantiatedFragmentFakeSymbol;\n\t#name;\n\t#routes;\n\t#deps;\n\t#services;\n\t#mountRoute;\n\t#router;\n\t#middlewareHandler;\n\t#serviceThisContext;\n\t#handlerThisContext;\n\t#contextStorage;\n\t#createRequestStorage;\n\t#options;\n\t#linkedFragments;\n\t#internalData;\n\tconstructor(params) {\n\t\tthis.#name = params.name;\n\t\tthis.#routes = params.routes;\n\t\tthis.#deps = params.deps;\n\t\tthis.#services = params.services;\n\t\tthis.#mountRoute = params.mountRoute;\n\t\tthis.#serviceThisContext = params.serviceThisContext;\n\t\tthis.#handlerThisContext = params.handlerThisContext;\n\t\tthis.#contextStorage = params.storage;\n\t\tthis.#createRequestStorage = params.createRequestStorage;\n\t\tthis.#options = params.options;\n\t\tthis.#linkedFragments = params.linkedFragments ?? {};\n\t\tthis.#internalData = params.internalData ?? {};\n\t\tthis.#router = createRouter();\n\t\tfor (const routeConfig of this.#routes) addRoute(this.#router, routeConfig.method.toUpperCase(), routeConfig.path, routeConfig);\n\t\tthis.handler = this.handler.bind(this);\n\t}\n\tget name() {\n\t\treturn this.#name;\n\t}\n\tget routes() {\n\t\treturn this.#routes;\n\t}\n\tget services() {\n\t\treturn this.#services;\n\t}\n\tget mountRoute() {\n\t\treturn this.#mountRoute;\n\t}\n\t/**\n\t* @internal\n\t*/\n\tget $internal() {\n\t\treturn {\n\t\t\tdeps: this.#deps,\n\t\t\toptions: this.#options,\n\t\t\tlinkedFragments: this.#linkedFragments,\n\t\t\t...this.#internalData\n\t\t};\n\t}\n\t/**\n\t* Add middleware to this fragment.\n\t* Middleware can inspect and modify requests before they reach handlers.\n\t*/\n\twithMiddleware(handler) {\n\t\tif (this.#middlewareHandler) throw new Error(\"Middleware already set\");\n\t\tthis.#middlewareHandler = handler;\n\t\treturn this;\n\t}\n\t#withRequestStorage(callback) {\n\t\tif (!this.#serviceThisContext && !this.#handlerThisContext) return callback();\n\t\tconst storageData = this.#createRequestStorage ? this.#createRequestStorage() : {};\n\t\treturn this.#contextStorage.run(storageData, callback);\n\t}\n\tinContext(callback) {\n\t\tif (this.#handlerThisContext) {\n\t\t\tconst boundCallback = callback.bind(this.#handlerThisContext);\n\t\t\treturn this.#withRequestStorage(boundCallback);\n\t\t}\n\t\treturn this.#withRequestStorage(callback);\n\t}\n\t/**\n\t* Get framework-specific handlers for this fragment.\n\t* Use this to integrate the fragment with different fullstack frameworks.\n\t*/\n\thandlersFor(framework) {\n\t\tconst handler = this.handler.bind(this);\n\t\tif (framework === \"h3\" || framework === \"nuxt\") throw new Error(`To get handlers for h3, use the 'fromWebHandler' utility function:\n import { fromWebHandler } from \"h3\";\n export default fromWebHandler(myFragment().handler);`);\n\t\treturn {\n\t\t\tastro: { ALL: handler },\n\t\t\t\"react-router\": {\n\t\t\t\tloader: ({ request }) => handler(request),\n\t\t\t\taction: ({ request }) => handler(request)\n\t\t\t},\n\t\t\t\"next-js\": {\n\t\t\t\tGET: handler,\n\t\t\t\tPOST: handler,\n\t\t\t\tPUT: handler,\n\t\t\t\tDELETE: handler,\n\t\t\t\tPATCH: handler,\n\t\t\t\tHEAD: handler,\n\t\t\t\tOPTIONS: handler\n\t\t\t},\n\t\t\t\"svelte-kit\": {\n\t\t\t\tGET: handler,\n\t\t\t\tPOST: handler,\n\t\t\t\tPUT: handler,\n\t\t\t\tDELETE: handler,\n\t\t\t\tPATCH: handler,\n\t\t\t\tHEAD: handler,\n\t\t\t\tOPTIONS: handler\n\t\t\t},\n\t\t\t\"solid-start\": {\n\t\t\t\tGET: ({ request }) => handler(request),\n\t\t\t\tPOST: ({ request }) => handler(request),\n\t\t\t\tPUT: ({ request }) => handler(request),\n\t\t\t\tDELETE: ({ request }) => handler(request),\n\t\t\t\tPATCH: ({ request }) => handler(request),\n\t\t\t\tHEAD: ({ request }) => handler(request),\n\t\t\t\tOPTIONS: ({ request }) => handler(request)\n\t\t\t},\n\t\t\t\"tanstack-start\": {\n\t\t\t\tGET: ({ request }) => handler(request),\n\t\t\t\tPOST: ({ request }) => handler(request),\n\t\t\t\tPUT: ({ request }) => handler(request),\n\t\t\t\tDELETE: ({ request }) => handler(request),\n\t\t\t\tPATCH: ({ request }) => handler(request),\n\t\t\t\tHEAD: ({ request }) => handler(request),\n\t\t\t\tOPTIONS: ({ request }) => handler(request)\n\t\t\t}\n\t\t}[framework];\n\t}\n\t/**\n\t* Main request handler for this fragment.\n\t* Handles routing, middleware, and error handling.\n\t*/\n\tasync handler(req) {\n\t\tconst url = new URL(req.url);\n\t\tconst pathname = url.pathname;\n\t\tconst matchRoute = pathname.startsWith(this.#mountRoute) ? pathname.slice(this.#mountRoute.length) : null;\n\t\tif (matchRoute === null) return Response.json({\n\t\t\terror: `Fragno: Route for '${this.#name}' not found. Is the fragment mounted on the right route? Expecting: '${this.#mountRoute}'.`,\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst route = findRoute(this.#router, req.method, matchRoute);\n\t\tif (!route) return Response.json({\n\t\t\terror: `Fragno: Route for '${this.#name}' not found`,\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst routeConfig = route.data;\n\t\tconst expectedContentType = routeConfig.contentType ?? \"application/json\";\n\t\tlet requestBody = void 0;\n\t\tlet rawBody = void 0;\n\t\tif (req.body instanceof ReadableStream) {\n\t\t\tconst requestContentType = (req.headers.get(\"content-type\") ?? \"\").toLowerCase();\n\t\t\tif (expectedContentType === \"multipart/form-data\") {\n\t\t\t\tif (!requestContentType.includes(\"multipart/form-data\")) return Response.json({\n\t\t\t\t\terror: `This endpoint expects multipart/form-data, but received: ${requestContentType || \"no content-type\"}`,\n\t\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\"\n\t\t\t\t}, { status: 415 });\n\t\t\t\ttry {\n\t\t\t\t\trequestBody = await req.formData();\n\t\t\t\t} catch {\n\t\t\t\t\treturn Response.json({\n\t\t\t\t\t\terror: \"Failed to parse multipart form data\",\n\t\t\t\t\t\tcode: \"INVALID_REQUEST_BODY\"\n\t\t\t\t\t}, { status: 400 });\n\t\t\t\t}\n\t\t\t} else if (expectedContentType === \"application/octet-stream\") {\n\t\t\t\tif (!requestContentType.includes(\"application/octet-stream\")) return Response.json({\n\t\t\t\t\terror: `This endpoint expects application/octet-stream, but received: ${requestContentType || \"no content-type\"}`,\n\t\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\"\n\t\t\t\t}, { status: 415 });\n\t\t\t\trequestBody = req.body ?? new ReadableStream();\n\t\t\t} else {\n\t\t\t\tif (requestContentType.includes(\"multipart/form-data\")) return Response.json({\n\t\t\t\t\terror: `This endpoint expects JSON, but received multipart/form-data. Use a route with contentType: \"multipart/form-data\" for file uploads.`,\n\t\t\t\t\tcode: \"UNSUPPORTED_MEDIA_TYPE\"\n\t\t\t\t}, { status: 415 });\n\t\t\t\trawBody = await req.clone().text();\n\t\t\t\tif (rawBody) try {\n\t\t\t\t\trequestBody = JSON.parse(rawBody);\n\t\t\t\t} catch {\n\t\t\t\t\trequestBody = void 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst decodedRouteParams = {};\n\t\tfor (const [key, value] of Object.entries(route.params ?? {})) decodedRouteParams[key] = decodeURIComponent(value);\n\t\tconst requestState = new MutableRequestState({\n\t\t\tpathParams: decodedRouteParams,\n\t\t\tsearchParams: url.searchParams,\n\t\t\tbody: requestBody,\n\t\t\theaders: new Headers(req.headers)\n\t\t});\n\t\tconst executeRequest = async () => {\n\t\t\tconst middlewareResult = await this.#executeMiddleware(req, route, requestState);\n\t\t\tif (middlewareResult !== void 0) return middlewareResult;\n\t\t\tconst internalMeta = routeConfig.__internal;\n\t\t\tif (internalMeta) {\n\t\t\t\tconst internalResult = await FragnoInstantiatedFragment.#runMiddlewareForFragment(internalMeta.fragment, {\n\t\t\t\t\treq,\n\t\t\t\t\tmethod: routeConfig.method,\n\t\t\t\t\tpath: internalMeta.originalPath,\n\t\t\t\t\trequestState,\n\t\t\t\t\troutes: internalMeta.routes\n\t\t\t\t});\n\t\t\t\tif (internalResult !== void 0) return internalResult;\n\t\t\t}\n\t\t\treturn this.#executeHandler(req, route, requestState, rawBody);\n\t\t};\n\t\treturn this.#withRequestStorage(executeRequest);\n\t}\n\t/**\n\t* Call a route directly with typed inputs and outputs.\n\t* Useful for testing and server-side route calls.\n\t*/\n\tasync callRoute(method, path, inputOptions) {\n\t\treturn parseFragnoResponse(await this.callRouteRaw(method, path, inputOptions));\n\t}\n\t/**\n\t* Call a route directly and get the raw Response object.\n\t* Useful for testing and server-side route calls.\n\t*/\n\tasync callRouteRaw(method, path, inputOptions) {\n\t\tconst route = this.#routes.find((r) => r.method === method && r.path === path);\n\t\tif (!route) return Response.json({\n\t\t\terror: `Route ${method} ${path} not found`,\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst { pathParams = {}, body, query, headers } = inputOptions || {};\n\t\tconst searchParams = query instanceof URLSearchParams ? query : query ? new URLSearchParams(query) : new URLSearchParams();\n\t\tconst requestHeaders = headers instanceof Headers ? headers : headers ? new Headers(headers) : new Headers();\n\t\tconst inputContext = new RequestInputContext({\n\t\t\tpath: route.path,\n\t\t\tmethod: route.method,\n\t\t\tpathParams,\n\t\t\tsearchParams,\n\t\t\theaders: requestHeaders,\n\t\t\tparsedBody: body,\n\t\t\tinputSchema: route.inputSchema,\n\t\t\tshouldValidateInput: true\n\t\t});\n\t\trecordTraceEvent({\n\t\t\ttype: \"route-input\",\n\t\t\tmethod: route.method,\n\t\t\tpath: route.path,\n\t\t\tpathParams: pathParams ?? {},\n\t\t\tqueryParams: serializeQueryForTrace(searchParams),\n\t\t\theaders: serializeHeadersForTrace(requestHeaders),\n\t\t\tbody: serializeBodyForTrace(body)\n\t\t});\n\t\tconst outputContext = new RequestOutputContext(route.outputSchema);\n\t\tconst executeHandler = async () => {\n\t\t\ttry {\n\t\t\t\tconst thisContext = this.#handlerThisContext ?? {};\n\t\t\t\treturn await route.handler.call(thisContext, inputContext, outputContext);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Error in callRoute handler\", error);\n\t\t\t\tif (error instanceof FragnoApiError) return error.toResponse();\n\t\t\t\treturn Response.json({\n\t\t\t\t\terror: \"Internal server error\",\n\t\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\"\n\t\t\t\t}, { status: 500 });\n\t\t\t}\n\t\t};\n\t\treturn this.#withRequestStorage(executeHandler);\n\t}\n\t/**\n\t* Execute middleware for a request.\n\t* Returns undefined if middleware allows the request to continue to the handler.\n\t*/\n\tasync #executeMiddleware(req, route, requestState) {\n\t\tif (!route) return;\n\t\tconst { path } = route.data;\n\t\treturn FragnoInstantiatedFragment.#runMiddlewareForFragment(this, {\n\t\t\treq,\n\t\t\tmethod: req.method,\n\t\t\tpath,\n\t\t\trequestState\n\t\t});\n\t}\n\tstatic async #runMiddlewareForFragment(fragment, options) {\n\t\tif (!fragment.#middlewareHandler) return;\n\t\tconst middlewareInputContext = new RequestMiddlewareInputContext(options.routes ?? fragment.#routes, {\n\t\t\tmethod: options.method,\n\t\t\tpath: options.path,\n\t\t\trequest: options.req,\n\t\t\tstate: options.requestState\n\t\t});\n\t\tconst middlewareOutputContext = new RequestMiddlewareOutputContext(fragment.#deps, fragment.#services);\n\t\ttry {\n\t\t\tconst middlewareResult = await fragment.#middlewareHandler(middlewareInputContext, middlewareOutputContext);\n\t\t\trecordTraceEvent({\n\t\t\t\ttype: \"middleware-decision\",\n\t\t\t\tmethod: options.method,\n\t\t\t\tpath: options.path,\n\t\t\t\toutcome: middlewareResult ? \"deny\" : \"allow\",\n\t\t\t\tstatus: middlewareResult?.status\n\t\t\t});\n\t\t\tif (middlewareResult !== void 0) return middlewareResult;\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error in middleware\", error);\n\t\t\trecordTraceEvent({\n\t\t\t\ttype: \"middleware-decision\",\n\t\t\t\tmethod: options.method,\n\t\t\t\tpath: options.path,\n\t\t\t\toutcome: \"deny\",\n\t\t\t\tstatus: error instanceof FragnoApiError ? error.status : 500\n\t\t\t});\n\t\t\tif (error instanceof FragnoApiError) return error.toResponse();\n\t\t\treturn Response.json({\n\t\t\t\terror: \"Internal server error\",\n\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\"\n\t\t\t}, { status: 500 });\n\t\t}\n\t}\n\t/**\n\t* Execute a route handler with proper error handling.\n\t*/\n\tasync #executeHandler(req, route, requestState, rawBody) {\n\t\tif (!route) return Response.json({\n\t\t\terror: \"Route not found\",\n\t\t\tcode: \"ROUTE_NOT_FOUND\"\n\t\t}, { status: 404 });\n\t\tconst { handler, inputSchema, outputSchema, path } = route.data;\n\t\tconst inputContext = await RequestInputContext.fromRequest({\n\t\t\trequest: req,\n\t\t\tmethod: req.method,\n\t\t\tpath,\n\t\t\tpathParams: route.params ?? {},\n\t\t\tinputSchema,\n\t\t\tstate: requestState,\n\t\t\trawBody\n\t\t});\n\t\trecordTraceEvent({\n\t\t\ttype: \"route-input\",\n\t\t\tmethod: req.method,\n\t\t\tpath,\n\t\t\tpathParams: inputContext.pathParams,\n\t\t\tqueryParams: serializeQueryForTrace(requestState.searchParams),\n\t\t\theaders: serializeHeadersForTrace(requestState.headers),\n\t\t\tbody: serializeBodyForTrace(requestState.body)\n\t\t});\n\t\tconst outputContext = new RequestOutputContext(outputSchema);\n\t\ttry {\n\t\t\tconst contextForHandler = this.#handlerThisContext ?? {};\n\t\t\treturn await handler.call(contextForHandler, inputContext, outputContext);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error in handler\", error);\n\t\t\tif (error instanceof FragnoApiError) return error.toResponse();\n\t\t\treturn Response.json({\n\t\t\t\terror: \"Internal server error\",\n\t\t\t\tcode: \"INTERNAL_SERVER_ERROR\"\n\t\t\t}, { status: 500 });\n\t\t}\n\t}\n};\n/**\n* Core instantiation function that creates a fragment instance from a definition.\n* This function validates dependencies, calls all callbacks, and wires everything together.\n*/\nfunction instantiateFragment(definition, config, routesOrFactories, options, serviceImplementations, instantiationOptions) {\n\tconst { dryRun = false } = instantiationOptions ?? {};\n\tconst serviceDependencies = definition.serviceDependencies;\n\tif (serviceDependencies) for (const [serviceName, meta] of Object.entries(serviceDependencies)) {\n\t\tconst metadata = meta;\n\t\tconst implementation = serviceImplementations?.[serviceName];\n\t\tif (metadata.required && !implementation) throw new Error(`Fragment '${definition.name}' requires service '${metadata.name}' but it was not provided`);\n\t}\n\tlet deps;\n\ttry {\n\t\tdeps = definition.dependencies?.({\n\t\t\tconfig,\n\t\t\toptions\n\t\t}) ?? {};\n\t} catch (error) {\n\t\tif (dryRun) {\n\t\t\tconsole.warn(\"Warning: Failed to initialize dependencies in dry run mode:\", error instanceof Error ? error.message : String(error));\n\t\t\tdeps = {};\n\t\t} else throw error;\n\t}\n\tconst linkedFragmentInstances = {};\n\tconst linkedFragmentServices = {};\n\tif (definition.linkedFragments) for (const [name, callback] of Object.entries(definition.linkedFragments)) {\n\t\tconst linkedFragment = callback({\n\t\t\tconfig,\n\t\t\toptions,\n\t\t\tserviceDependencies: serviceImplementations\n\t\t});\n\t\tlinkedFragmentInstances[name] = linkedFragment;\n\t\tconst services$1 = linkedFragment.services;\n\t\tfor (const [serviceName, service] of Object.entries(services$1)) linkedFragmentServices[serviceName] = service;\n\t}\n\tconst defineService = (services$1) => services$1;\n\tconst privateServices = { ...linkedFragmentServices };\n\tif (definition.privateServices) for (const [serviceName, factory] of Object.entries(definition.privateServices)) {\n\t\tconst serviceFactory = factory;\n\t\ttry {\n\t\t\tprivateServices[serviceName] = serviceFactory({\n\t\t\t\tconfig,\n\t\t\t\toptions,\n\t\t\t\tdeps,\n\t\t\t\tserviceDeps: serviceImplementations ?? {},\n\t\t\t\tprivateServices,\n\t\t\t\tdefineService\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (dryRun) {\n\t\t\t\tconsole.warn(`Warning: Failed to initialize private service '${serviceName}' in dry run mode:`, error instanceof Error ? error.message : String(error));\n\t\t\t\tprivateServices[serviceName] = {};\n\t\t\t} else throw error;\n\t\t}\n\t}\n\tlet baseServices;\n\ttry {\n\t\tbaseServices = definition.baseServices?.({\n\t\t\tconfig,\n\t\t\toptions,\n\t\t\tdeps,\n\t\t\tserviceDeps: serviceImplementations ?? {},\n\t\t\tprivateServices,\n\t\t\tdefineService\n\t\t}) ?? {};\n\t} catch (error) {\n\t\tif (dryRun) {\n\t\t\tconsole.warn(\"Warning: Failed to initialize base services in dry run mode:\", error instanceof Error ? error.message : String(error));\n\t\t\tbaseServices = {};\n\t\t} else throw error;\n\t}\n\tconst namedServices = {};\n\tif (definition.namedServices) for (const [serviceName, factory] of Object.entries(definition.namedServices)) {\n\t\tconst serviceFactory = factory;\n\t\ttry {\n\t\t\tnamedServices[serviceName] = serviceFactory({\n\t\t\t\tconfig,\n\t\t\t\toptions,\n\t\t\t\tdeps,\n\t\t\t\tserviceDeps: serviceImplementations ?? {},\n\t\t\t\tprivateServices,\n\t\t\t\tdefineService\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (dryRun) {\n\t\t\t\tconsole.warn(`Warning: Failed to initialize service '${serviceName}' in dry run mode:`, error instanceof Error ? error.message : String(error));\n\t\t\t\tnamedServices[serviceName] = {};\n\t\t\t} else throw error;\n\t\t}\n\t}\n\tconst services = {\n\t\t...baseServices,\n\t\t...namedServices\n\t};\n\tconst storage = definition.getExternalStorage ? definition.getExternalStorage({\n\t\tconfig,\n\t\toptions,\n\t\tdeps\n\t}) : new RequestContextStorage();\n\tconst contexts = definition.createThisContext?.({\n\t\tconfig,\n\t\toptions,\n\t\tdeps,\n\t\tstorage\n\t});\n\tconst serviceContext = contexts?.serviceContext;\n\tconst handlerContext = contexts?.handlerContext;\n\tconst internalData = definition.internalDataFactory?.({\n\t\tconfig,\n\t\toptions,\n\t\tdeps,\n\t\tlinkedFragments: linkedFragmentInstances\n\t}) ?? {};\n\tconst boundServices = serviceContext ? bindServicesToContext(services, serviceContext) : services;\n\tconst routes = resolveRouteFactories({\n\t\tconfig,\n\t\tdeps,\n\t\tservices: boundServices,\n\t\tserviceDeps: serviceImplementations ?? {}\n\t}, routesOrFactories);\n\tconst linkedRoutes = collectLinkedFragmentRoutes(linkedFragmentInstances);\n\tconst finalRoutes = linkedRoutes.length > 0 ? [...routes, ...linkedRoutes] : routes;\n\tconst mountRoute = getMountRoute({\n\t\tname: definition.name,\n\t\tmountRoute: options.mountRoute\n\t});\n\tconst createRequestStorageWithContext = definition.createRequestStorage ? () => definition.createRequestStorage({\n\t\tconfig,\n\t\toptions,\n\t\tdeps\n\t}) : void 0;\n\treturn new FragnoInstantiatedFragment({\n\t\tname: definition.name,\n\t\troutes: finalRoutes,\n\t\tdeps,\n\t\tservices: boundServices,\n\t\tmountRoute,\n\t\tserviceThisContext: serviceContext,\n\t\thandlerThisContext: handlerContext,\n\t\tstorage,\n\t\tcreateRequestStorage: createRequestStorageWithContext,\n\t\toptions,\n\t\tlinkedFragments: linkedFragmentInstances,\n\t\tinternalData\n\t});\n}\n/**\n* Fluent builder for instantiating fragments.\n* Provides a type-safe API for configuring and building fragment instances.\n*/\nvar FragmentInstantiationBuilder = class FragmentInstantiationBuilder {\n\t#definition;\n\t#config;\n\t#routes;\n\t#options;\n\t#services;\n\tconstructor(definition, routes) {\n\t\tthis.#definition = definition;\n\t\tthis.#routes = routes;\n\t}\n\t/**\n\t* Get the fragment definition\n\t*/\n\tget definition() {\n\t\treturn this.#definition;\n\t}\n\t/**\n\t* Get the configured routes\n\t*/\n\tget routes() {\n\t\treturn this.#routes ?? [];\n\t}\n\t/**\n\t* Get the configuration\n\t*/\n\tget config() {\n\t\treturn this.#config;\n\t}\n\t/**\n\t* Get the options\n\t*/\n\tget options() {\n\t\treturn this.#options;\n\t}\n\t/**\n\t* Set the configuration for the fragment\n\t*/\n\twithConfig(config) {\n\t\tthis.#config = config;\n\t\treturn this;\n\t}\n\t/**\n\t* Set the routes for the fragment\n\t*/\n\twithRoutes(routes) {\n\t\tconst newBuilder = new FragmentInstantiationBuilder(this.#definition, routes);\n\t\tnewBuilder.#config = this.#config;\n\t\tnewBuilder.#options = this.#options;\n\t\tnewBuilder.#services = this.#services;\n\t\treturn newBuilder;\n\t}\n\t/**\n\t* Set the options for the fragment (e.g., mountRoute, databaseAdapter)\n\t*/\n\twithOptions(options) {\n\t\tthis.#options = options;\n\t\treturn this;\n\t}\n\t/**\n\t* Provide implementations for services that this fragment uses\n\t*/\n\twithServices(services) {\n\t\tthis.#services = services;\n\t\treturn this;\n\t}\n\t/**\n\t* Build and return the instantiated fragment\n\t*/\n\tbuild() {\n\t\tconst dryRun = process.env[\"FRAGNO_INIT_DRY_RUN\"] === \"true\";\n\t\treturn instantiateFragment(this.#definition, this.#config ?? {}, this.#routes ?? [], this.#options ?? {}, this.#services, { dryRun });\n\t}\n};\n/**\n* Create a fluent builder for instantiating a fragment.\n*\n* @example\n* ```ts\n* const fragment = instantiate(myFragmentDefinition)\n* .withConfig({ apiKey: \"key\" })\n* .withRoutes([route1, route2])\n* .withOptions({ mountRoute: \"/api\" })\n* .build();\n* ```\n*/\nfunction instantiate(definition) {\n\treturn new FragmentInstantiationBuilder(definition);\n}\n\n//#endregion\nexport { FragmentInstantiationBuilder, FragnoInstantiatedFragment, instantiate, instantiateFragment };\n//# sourceMappingURL=fragment-instantiator.js.map"],"mappings":"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"}
@@ -91,6 +91,72 @@ var RequestInputContext = class RequestInputContext$1 {
91
91
  return this.#body;
92
92
  }
93
93
  /**
94
+ * Access the request body as FormData.
95
+ *
96
+ * Use this method when handling file uploads or multipart form submissions.
97
+ * The request must have been sent with Content-Type: multipart/form-data.
98
+ *
99
+ * @throws Error if the request body is not FormData
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * defineRoute({
104
+ * method: "POST",
105
+ * path: "/upload",
106
+ * async handler(ctx, res) {
107
+ * const formData = ctx.formData();
108
+ * const file = formData.get("file") as File;
109
+ * const description = formData.get("description") as string;
110
+ * // ... process file
111
+ * }
112
+ * });
113
+ * ```
114
+ */
115
+ formData() {
116
+ if (!(this.#parsedBody instanceof FormData)) throw new Error("Request body is not FormData. Ensure the request was sent with Content-Type: multipart/form-data.");
117
+ return this.#parsedBody;
118
+ }
119
+ /**
120
+ * Check if the request body is FormData.
121
+ *
122
+ * Useful for routes that accept both JSON and FormData payloads.
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * defineRoute({
127
+ * method: "POST",
128
+ * path: "/upload",
129
+ * async handler(ctx, res) {
130
+ * if (ctx.isFormData()) {
131
+ * const formData = ctx.formData();
132
+ * // handle file upload
133
+ * } else {
134
+ * const json = await ctx.input.valid();
135
+ * // handle JSON payload
136
+ * }
137
+ * }
138
+ * });
139
+ * ```
140
+ */
141
+ isFormData() {
142
+ return this.#parsedBody instanceof FormData;
143
+ }
144
+ /**
145
+ * Access the request body as a ReadableStream (application/octet-stream).
146
+ *
147
+ * @throws Error if the request body is not a ReadableStream
148
+ */
149
+ bodyStream() {
150
+ if (!(this.#parsedBody instanceof ReadableStream)) throw new Error("Request body is not a ReadableStream. Ensure the request was sent with Content-Type: application/octet-stream.");
151
+ return this.#parsedBody;
152
+ }
153
+ /**
154
+ * Check if the request body is a ReadableStream.
155
+ */
156
+ isBodyStream() {
157
+ return this.#parsedBody instanceof ReadableStream;
158
+ }
159
+ /**
94
160
  * Input validation context (only if inputSchema is defined)
95
161
  * @remarks `InputContext`
96
162
  */
@@ -107,6 +173,7 @@ var RequestInputContext = class RequestInputContext$1 {
107
173
  async #validateInput() {
108
174
  if (!this.#inputSchema) throw new Error("No input schema defined for this route");
109
175
  if (this.#parsedBody instanceof FormData || this.#parsedBody instanceof Blob) throw new Error("Schema validation is only supported for JSON data, not FormData or Blob");
176
+ if (this.#parsedBody instanceof ReadableStream) throw new Error("Schema validation is only supported for JSON data, not FormData, Blob, or ReadableStream");
110
177
  const result = await this.#inputSchema["~standard"].validate(this.#parsedBody);
111
178
  if (result.issues) throw new FragnoApiValidationError("Validation failed", result.issues);
112
179
  return result.value;
@@ -1 +1 @@
1
- {"version":3,"file":"request-input-context.js","names":["RequestInputContext","#path","#method","#pathParams","#searchParams","#headers","#body","#parsedBody","#inputSchema","#shouldValidateInput","#validateInput"],"sources":["../../../../../../fragno/dist/api/request-input-context.js"],"sourcesContent":["import { FragnoApiValidationError } from \"./error.js\";\n\n//#region src/api/request-input-context.ts\nvar RequestInputContext = class RequestInputContext {\n\t#path;\n\t#method;\n\t#pathParams;\n\t#searchParams;\n\t#headers;\n\t#body;\n\t#parsedBody;\n\t#inputSchema;\n\t#shouldValidateInput;\n\tconstructor(config) {\n\t\tthis.#path = config.path;\n\t\tthis.#method = config.method;\n\t\tthis.#pathParams = config.pathParams;\n\t\tthis.#searchParams = config.searchParams;\n\t\tthis.#headers = config.headers;\n\t\tthis.#body = config.rawBody;\n\t\tthis.#parsedBody = config.parsedBody;\n\t\tthis.#inputSchema = config.inputSchema;\n\t\tthis.#shouldValidateInput = config.shouldValidateInput ?? true;\n\t}\n\t/**\n\t* Create a RequestContext from a Request object for server-side handling\n\t*/\n\tstatic async fromRequest(config) {\n\t\treturn new RequestInputContext({\n\t\t\tmethod: config.method,\n\t\t\tpath: config.path,\n\t\t\tpathParams: config.state.pathParams,\n\t\t\tsearchParams: config.state.searchParams,\n\t\t\theaders: config.state.headers,\n\t\t\tparsedBody: config.state.body,\n\t\t\trawBody: config.rawBody,\n\t\t\tinputSchema: config.inputSchema,\n\t\t\tshouldValidateInput: config.shouldValidateInput\n\t\t});\n\t}\n\t/**\n\t* Create a RequestContext for server-side rendering contexts (no Request object)\n\t*/\n\tstatic fromSSRContext(config) {\n\t\treturn new RequestInputContext({\n\t\t\tmethod: config.method,\n\t\t\tpath: config.path,\n\t\t\tpathParams: config.pathParams,\n\t\t\tsearchParams: config.searchParams ?? new URLSearchParams(),\n\t\t\theaders: config.headers ?? new Headers(),\n\t\t\tparsedBody: \"body\" in config ? config.body : void 0,\n\t\t\tinputSchema: \"inputSchema\" in config ? config.inputSchema : void 0,\n\t\t\tshouldValidateInput: false\n\t\t});\n\t}\n\t/**\n\t* The HTTP method as string (e.g., `GET`, `POST`)\n\t*/\n\tget method() {\n\t\treturn this.#method;\n\t}\n\t/**\n\t* The matched route path (e.g., `/users/:id`)\n\t* @remarks `string`\n\t*/\n\tget path() {\n\t\treturn this.#path;\n\t}\n\t/**\n\t* Extracted path parameters as object (e.g., `{ id: '123' }`)\n\t* @remarks `Record<string, string>`\n\t*/\n\tget pathParams() {\n\t\treturn this.#pathParams;\n\t}\n\t/**\n\t* [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object for query parameters\n\t* @remarks `URLSearchParams`\n\t*/\n\tget query() {\n\t\treturn this.#searchParams;\n\t}\n\t/**\n\t* [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object for request headers\n\t* @remarks `Headers`\n\t*/\n\tget headers() {\n\t\treturn this.#headers;\n\t}\n\tget rawBody() {\n\t\treturn this.#body;\n\t}\n\t/**\n\t* Input validation context (only if inputSchema is defined)\n\t* @remarks `InputContext`\n\t*/\n\tget input() {\n\t\tif (!this.#inputSchema) return;\n\t\treturn {\n\t\t\tschema: this.#inputSchema,\n\t\t\tvalid: async () => {\n\t\t\t\tif (!this.#shouldValidateInput) return this.#parsedBody;\n\t\t\t\treturn this.#validateInput();\n\t\t\t}\n\t\t};\n\t}\n\tasync #validateInput() {\n\t\tif (!this.#inputSchema) throw new Error(\"No input schema defined for this route\");\n\t\tif (this.#parsedBody instanceof FormData || this.#parsedBody instanceof Blob) throw new Error(\"Schema validation is only supported for JSON data, not FormData or Blob\");\n\t\tconst result = await this.#inputSchema[\"~standard\"].validate(this.#parsedBody);\n\t\tif (result.issues) throw new FragnoApiValidationError(\"Validation failed\", result.issues);\n\t\treturn result.value;\n\t}\n};\n\n//#endregion\nexport { RequestInputContext };\n//# sourceMappingURL=request-input-context.js.map"],"mappings":";;;AAGA,IAAI,sBAAsB,MAAMA,sBAAoB;CACnD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,QAAQ;AACnB,QAAKC,OAAQ,OAAO;AACpB,QAAKC,SAAU,OAAO;AACtB,QAAKC,aAAc,OAAO;AAC1B,QAAKC,eAAgB,OAAO;AAC5B,QAAKC,UAAW,OAAO;AACvB,QAAKC,OAAQ,OAAO;AACpB,QAAKC,aAAc,OAAO;AAC1B,QAAKC,cAAe,OAAO;AAC3B,QAAKC,sBAAuB,OAAO,uBAAuB;;;;;CAK3D,aAAa,YAAY,QAAQ;AAChC,SAAO,IAAIT,sBAAoB;GAC9B,QAAQ,OAAO;GACf,MAAM,OAAO;GACb,YAAY,OAAO,MAAM;GACzB,cAAc,OAAO,MAAM;GAC3B,SAAS,OAAO,MAAM;GACtB,YAAY,OAAO,MAAM;GACzB,SAAS,OAAO;GAChB,aAAa,OAAO;GACpB,qBAAqB,OAAO;GAC5B,CAAC;;;;;CAKH,OAAO,eAAe,QAAQ;AAC7B,SAAO,IAAIA,sBAAoB;GAC9B,QAAQ,OAAO;GACf,MAAM,OAAO;GACb,YAAY,OAAO;GACnB,cAAc,OAAO,gBAAgB,IAAI,iBAAiB;GAC1D,SAAS,OAAO,WAAW,IAAI,SAAS;GACxC,YAAY,UAAU,SAAS,OAAO,OAAO,KAAK;GAClD,aAAa,iBAAiB,SAAS,OAAO,cAAc,KAAK;GACjE,qBAAqB;GACrB,CAAC;;;;;CAKH,IAAI,SAAS;AACZ,SAAO,MAAKE;;;;;;CAMb,IAAI,OAAO;AACV,SAAO,MAAKD;;;;;;CAMb,IAAI,aAAa;AAChB,SAAO,MAAKE;;;;;;CAMb,IAAI,QAAQ;AACX,SAAO,MAAKC;;;;;;CAMb,IAAI,UAAU;AACb,SAAO,MAAKC;;CAEb,IAAI,UAAU;AACb,SAAO,MAAKC;;;;;;CAMb,IAAI,QAAQ;AACX,MAAI,CAAC,MAAKE,YAAc;AACxB,SAAO;GACN,QAAQ,MAAKA;GACb,OAAO,YAAY;AAClB,QAAI,CAAC,MAAKC,oBAAsB,QAAO,MAAKF;AAC5C,WAAO,MAAKG,eAAgB;;GAE7B;;CAEF,OAAMA,gBAAiB;AACtB,MAAI,CAAC,MAAKF,YAAc,OAAM,IAAI,MAAM,yCAAyC;AACjF,MAAI,MAAKD,sBAAuB,YAAY,MAAKA,sBAAuB,KAAM,OAAM,IAAI,MAAM,0EAA0E;EACxK,MAAM,SAAS,MAAM,MAAKC,YAAa,aAAa,SAAS,MAAKD,WAAY;AAC9E,MAAI,OAAO,OAAQ,OAAM,IAAI,yBAAyB,qBAAqB,OAAO,OAAO;AACzF,SAAO,OAAO"}
1
+ {"version":3,"file":"request-input-context.js","names":["RequestInputContext","#path","#method","#pathParams","#searchParams","#headers","#body","#parsedBody","#inputSchema","#shouldValidateInput","#validateInput"],"sources":["../../../../../../fragno/dist/api/request-input-context.js"],"sourcesContent":["import { FragnoApiValidationError } from \"./error.js\";\n\n//#region src/api/request-input-context.ts\nvar RequestInputContext = class RequestInputContext {\n\t#path;\n\t#method;\n\t#pathParams;\n\t#searchParams;\n\t#headers;\n\t#body;\n\t#parsedBody;\n\t#inputSchema;\n\t#shouldValidateInput;\n\tconstructor(config) {\n\t\tthis.#path = config.path;\n\t\tthis.#method = config.method;\n\t\tthis.#pathParams = config.pathParams;\n\t\tthis.#searchParams = config.searchParams;\n\t\tthis.#headers = config.headers;\n\t\tthis.#body = config.rawBody;\n\t\tthis.#parsedBody = config.parsedBody;\n\t\tthis.#inputSchema = config.inputSchema;\n\t\tthis.#shouldValidateInput = config.shouldValidateInput ?? true;\n\t}\n\t/**\n\t* Create a RequestContext from a Request object for server-side handling\n\t*/\n\tstatic async fromRequest(config) {\n\t\treturn new RequestInputContext({\n\t\t\tmethod: config.method,\n\t\t\tpath: config.path,\n\t\t\tpathParams: config.state.pathParams,\n\t\t\tsearchParams: config.state.searchParams,\n\t\t\theaders: config.state.headers,\n\t\t\tparsedBody: config.state.body,\n\t\t\trawBody: config.rawBody,\n\t\t\tinputSchema: config.inputSchema,\n\t\t\tshouldValidateInput: config.shouldValidateInput\n\t\t});\n\t}\n\t/**\n\t* Create a RequestContext for server-side rendering contexts (no Request object)\n\t*/\n\tstatic fromSSRContext(config) {\n\t\treturn new RequestInputContext({\n\t\t\tmethod: config.method,\n\t\t\tpath: config.path,\n\t\t\tpathParams: config.pathParams,\n\t\t\tsearchParams: config.searchParams ?? new URLSearchParams(),\n\t\t\theaders: config.headers ?? new Headers(),\n\t\t\tparsedBody: \"body\" in config ? config.body : void 0,\n\t\t\tinputSchema: \"inputSchema\" in config ? config.inputSchema : void 0,\n\t\t\tshouldValidateInput: false\n\t\t});\n\t}\n\t/**\n\t* The HTTP method as string (e.g., `GET`, `POST`)\n\t*/\n\tget method() {\n\t\treturn this.#method;\n\t}\n\t/**\n\t* The matched route path (e.g., `/users/:id`)\n\t* @remarks `string`\n\t*/\n\tget path() {\n\t\treturn this.#path;\n\t}\n\t/**\n\t* Extracted path parameters as object (e.g., `{ id: '123' }`)\n\t* @remarks `Record<string, string>`\n\t*/\n\tget pathParams() {\n\t\treturn this.#pathParams;\n\t}\n\t/**\n\t* [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object for query parameters\n\t* @remarks `URLSearchParams`\n\t*/\n\tget query() {\n\t\treturn this.#searchParams;\n\t}\n\t/**\n\t* [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object for request headers\n\t* @remarks `Headers`\n\t*/\n\tget headers() {\n\t\treturn this.#headers;\n\t}\n\tget rawBody() {\n\t\treturn this.#body;\n\t}\n\t/**\n\t* Access the request body as FormData.\n\t*\n\t* Use this method when handling file uploads or multipart form submissions.\n\t* The request must have been sent with Content-Type: multipart/form-data.\n\t*\n\t* @throws Error if the request body is not FormData\n\t*\n\t* @example\n\t* ```typescript\n\t* defineRoute({\n\t* method: \"POST\",\n\t* path: \"/upload\",\n\t* async handler(ctx, res) {\n\t* const formData = ctx.formData();\n\t* const file = formData.get(\"file\") as File;\n\t* const description = formData.get(\"description\") as string;\n\t* // ... process file\n\t* }\n\t* });\n\t* ```\n\t*/\n\tformData() {\n\t\tif (!(this.#parsedBody instanceof FormData)) throw new Error(\"Request body is not FormData. Ensure the request was sent with Content-Type: multipart/form-data.\");\n\t\treturn this.#parsedBody;\n\t}\n\t/**\n\t* Check if the request body is FormData.\n\t*\n\t* Useful for routes that accept both JSON and FormData payloads.\n\t*\n\t* @example\n\t* ```typescript\n\t* defineRoute({\n\t* method: \"POST\",\n\t* path: \"/upload\",\n\t* async handler(ctx, res) {\n\t* if (ctx.isFormData()) {\n\t* const formData = ctx.formData();\n\t* // handle file upload\n\t* } else {\n\t* const json = await ctx.input.valid();\n\t* // handle JSON payload\n\t* }\n\t* }\n\t* });\n\t* ```\n\t*/\n\tisFormData() {\n\t\treturn this.#parsedBody instanceof FormData;\n\t}\n\t/**\n\t* Access the request body as a ReadableStream (application/octet-stream).\n\t*\n\t* @throws Error if the request body is not a ReadableStream\n\t*/\n\tbodyStream() {\n\t\tif (!(this.#parsedBody instanceof ReadableStream)) throw new Error(\"Request body is not a ReadableStream. Ensure the request was sent with Content-Type: application/octet-stream.\");\n\t\treturn this.#parsedBody;\n\t}\n\t/**\n\t* Check if the request body is a ReadableStream.\n\t*/\n\tisBodyStream() {\n\t\treturn this.#parsedBody instanceof ReadableStream;\n\t}\n\t/**\n\t* Input validation context (only if inputSchema is defined)\n\t* @remarks `InputContext`\n\t*/\n\tget input() {\n\t\tif (!this.#inputSchema) return;\n\t\treturn {\n\t\t\tschema: this.#inputSchema,\n\t\t\tvalid: async () => {\n\t\t\t\tif (!this.#shouldValidateInput) return this.#parsedBody;\n\t\t\t\treturn this.#validateInput();\n\t\t\t}\n\t\t};\n\t}\n\tasync #validateInput() {\n\t\tif (!this.#inputSchema) throw new Error(\"No input schema defined for this route\");\n\t\tif (this.#parsedBody instanceof FormData || this.#parsedBody instanceof Blob) throw new Error(\"Schema validation is only supported for JSON data, not FormData or Blob\");\n\t\tif (this.#parsedBody instanceof ReadableStream) throw new Error(\"Schema validation is only supported for JSON data, not FormData, Blob, or ReadableStream\");\n\t\tconst result = await this.#inputSchema[\"~standard\"].validate(this.#parsedBody);\n\t\tif (result.issues) throw new FragnoApiValidationError(\"Validation failed\", result.issues);\n\t\treturn result.value;\n\t}\n};\n\n//#endregion\nexport { RequestInputContext };\n//# sourceMappingURL=request-input-context.js.map"],"mappings":";;;AAGA,IAAI,sBAAsB,MAAMA,sBAAoB;CACnD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,YAAY,QAAQ;AACnB,QAAKC,OAAQ,OAAO;AACpB,QAAKC,SAAU,OAAO;AACtB,QAAKC,aAAc,OAAO;AAC1B,QAAKC,eAAgB,OAAO;AAC5B,QAAKC,UAAW,OAAO;AACvB,QAAKC,OAAQ,OAAO;AACpB,QAAKC,aAAc,OAAO;AAC1B,QAAKC,cAAe,OAAO;AAC3B,QAAKC,sBAAuB,OAAO,uBAAuB;;;;;CAK3D,aAAa,YAAY,QAAQ;AAChC,SAAO,IAAIT,sBAAoB;GAC9B,QAAQ,OAAO;GACf,MAAM,OAAO;GACb,YAAY,OAAO,MAAM;GACzB,cAAc,OAAO,MAAM;GAC3B,SAAS,OAAO,MAAM;GACtB,YAAY,OAAO,MAAM;GACzB,SAAS,OAAO;GAChB,aAAa,OAAO;GACpB,qBAAqB,OAAO;GAC5B,CAAC;;;;;CAKH,OAAO,eAAe,QAAQ;AAC7B,SAAO,IAAIA,sBAAoB;GAC9B,QAAQ,OAAO;GACf,MAAM,OAAO;GACb,YAAY,OAAO;GACnB,cAAc,OAAO,gBAAgB,IAAI,iBAAiB;GAC1D,SAAS,OAAO,WAAW,IAAI,SAAS;GACxC,YAAY,UAAU,SAAS,OAAO,OAAO,KAAK;GAClD,aAAa,iBAAiB,SAAS,OAAO,cAAc,KAAK;GACjE,qBAAqB;GACrB,CAAC;;;;;CAKH,IAAI,SAAS;AACZ,SAAO,MAAKE;;;;;;CAMb,IAAI,OAAO;AACV,SAAO,MAAKD;;;;;;CAMb,IAAI,aAAa;AAChB,SAAO,MAAKE;;;;;;CAMb,IAAI,QAAQ;AACX,SAAO,MAAKC;;;;;;CAMb,IAAI,UAAU;AACb,SAAO,MAAKC;;CAEb,IAAI,UAAU;AACb,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;CAwBb,WAAW;AACV,MAAI,EAAE,MAAKC,sBAAuB,UAAW,OAAM,IAAI,MAAM,oGAAoG;AACjK,SAAO,MAAKA;;;;;;;;;;;;;;;;;;;;;;;;CAwBb,aAAa;AACZ,SAAO,MAAKA,sBAAuB;;;;;;;CAOpC,aAAa;AACZ,MAAI,EAAE,MAAKA,sBAAuB,gBAAiB,OAAM,IAAI,MAAM,iHAAiH;AACpL,SAAO,MAAKA;;;;;CAKb,eAAe;AACd,SAAO,MAAKA,sBAAuB;;;;;;CAMpC,IAAI,QAAQ;AACX,MAAI,CAAC,MAAKC,YAAc;AACxB,SAAO;GACN,QAAQ,MAAKA;GACb,OAAO,YAAY;AAClB,QAAI,CAAC,MAAKC,oBAAsB,QAAO,MAAKF;AAC5C,WAAO,MAAKG,eAAgB;;GAE7B;;CAEF,OAAMA,gBAAiB;AACtB,MAAI,CAAC,MAAKF,YAAc,OAAM,IAAI,MAAM,yCAAyC;AACjF,MAAI,MAAKD,sBAAuB,YAAY,MAAKA,sBAAuB,KAAM,OAAM,IAAI,MAAM,0EAA0E;AACxK,MAAI,MAAKA,sBAAuB,eAAgB,OAAM,IAAI,MAAM,2FAA2F;EAC3J,MAAM,SAAS,MAAM,MAAKC,YAAa,aAAa,SAAS,MAAKD,WAAY;AAC9E,MAAI,OAAO,OAAQ,OAAM,IAAI,yBAAyB,qBAAqB,OAAO,OAAO;AACzF,SAAO,OAAO"}
@@ -11,7 +11,20 @@ function resolveRouteFactories(context, routesOrFactories) {
11
11
  } else routes.push(item);
12
12
  return routes;
13
13
  }
14
+ function defineRoute(config) {
15
+ return config;
16
+ }
17
+ function defineRoutes(_definition) {
18
+ return { create: (fn) => {
19
+ return (ctx) => {
20
+ return fn({
21
+ ...ctx,
22
+ defineRoute
23
+ });
24
+ };
25
+ } };
26
+ }
14
27
 
15
28
  //#endregion
16
- export { resolveRouteFactories };
29
+ export { defineRoutes, resolveRouteFactories };
17
30
  //# sourceMappingURL=route.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","names":[],"sources":["../../../../../../fragno/dist/api/route.js"],"sourcesContent":["//#region src/api/route.ts\n/**\n* Helper to resolve route factories into routes\n* @internal\n*/\nfunction resolveRouteFactories(context, routesOrFactories) {\n\tconst routes = [];\n\tfor (const item of routesOrFactories) if (typeof item === \"function\") {\n\t\tconst factoryRoutes = item(context);\n\t\troutes.push(...factoryRoutes);\n\t} else routes.push(item);\n\treturn routes;\n}\nfunction defineRoute(config) {\n\treturn config;\n}\nfunction defineRoutes(_definition) {\n\treturn { create: (fn) => {\n\t\treturn (ctx) => {\n\t\t\treturn fn({\n\t\t\t\t...ctx,\n\t\t\t\tdefineRoute\n\t\t\t});\n\t\t};\n\t} };\n}\n\n//#endregion\nexport { defineRoute, defineRoutes, resolveRouteFactories };\n//# sourceMappingURL=route.js.map"],"mappings":";;;;;AAKA,SAAS,sBAAsB,SAAS,mBAAmB;CAC1D,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,QAAQ,kBAAmB,KAAI,OAAO,SAAS,YAAY;EACrE,MAAM,gBAAgB,KAAK,QAAQ;AACnC,SAAO,KAAK,GAAG,cAAc;OACvB,QAAO,KAAK,KAAK;AACxB,QAAO"}
1
+ {"version":3,"file":"route.js","names":[],"sources":["../../../../../../fragno/dist/api/route.js"],"sourcesContent":["//#region src/api/route.ts\n/**\n* Helper to resolve route factories into routes\n* @internal\n*/\nfunction resolveRouteFactories(context, routesOrFactories) {\n\tconst routes = [];\n\tfor (const item of routesOrFactories) if (typeof item === \"function\") {\n\t\tconst factoryRoutes = item(context);\n\t\troutes.push(...factoryRoutes);\n\t} else routes.push(item);\n\treturn routes;\n}\nfunction defineRoute(config) {\n\treturn config;\n}\nfunction defineRoutes(_definition) {\n\treturn { create: (fn) => {\n\t\treturn (ctx) => {\n\t\t\treturn fn({\n\t\t\t\t...ctx,\n\t\t\t\tdefineRoute\n\t\t\t});\n\t\t};\n\t} };\n}\n\n//#endregion\nexport { defineRoute, defineRoutes, resolveRouteFactories };\n//# sourceMappingURL=route.js.map"],"mappings":";;;;;AAKA,SAAS,sBAAsB,SAAS,mBAAmB;CAC1D,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,QAAQ,kBAAmB,KAAI,OAAO,SAAS,YAAY;EACrE,MAAM,gBAAgB,KAAK,QAAQ;AACnC,SAAO,KAAK,GAAG,cAAc;OACvB,QAAO,KAAK,KAAK;AACxB,QAAO;;AAER,SAAS,YAAY,QAAQ;AAC5B,QAAO;;AAER,SAAS,aAAa,aAAa;AAClC,QAAO,EAAE,SAAS,OAAO;AACxB,UAAQ,QAAQ;AACf,UAAO,GAAG;IACT,GAAG;IACH;IACA,CAAC;;IAED"}
@@ -0,0 +1,12 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ //#region ../fragno/dist/internal/trace-context.js
4
+ const traceStorage = new AsyncLocalStorage();
5
+ const recordTraceEvent = (event) => {
6
+ const recorder = traceStorage.getStore();
7
+ if (recorder) recorder(event);
8
+ };
9
+
10
+ //#endregion
11
+ export { recordTraceEvent };
12
+ //# sourceMappingURL=trace-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-context.js","names":[],"sources":["../../../../../../fragno/dist/internal/trace-context.js"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\n//#region src/internal/trace-context.ts\nconst traceStorage = new AsyncLocalStorage();\nconst runWithTraceRecorder = (recorder, callback) => traceStorage.run(recorder, callback);\nconst getTraceRecorder = () => traceStorage.getStore();\nconst recordTraceEvent = (event) => {\n\tconst recorder = traceStorage.getStore();\n\tif (recorder) recorder(event);\n};\n\n//#endregion\nexport { getTraceRecorder, recordTraceEvent, runWithTraceRecorder };\n//# sourceMappingURL=trace-context.js.map"],"mappings":";;;AAGA,MAAM,eAAe,IAAI,mBAAmB;AAG5C,MAAM,oBAAoB,UAAU;CACnC,MAAM,WAAW,aAAa,UAAU;AACxC,KAAI,SAAU,UAAS,MAAM"}
@@ -12,16 +12,32 @@ import { createId } from "../id.js";
12
12
  *
13
13
  * @internal
14
14
  */
15
- function generateRuntimeDefault(column) {
15
+ function generateRuntimeDefault(column, context = {}) {
16
16
  if (!column.default) return;
17
17
  if ("value" in column.default) return;
18
18
  if ("dbSpecial" in column.default) return;
19
19
  const runtime = column.default.runtime;
20
- if (runtime === "cuid") return createId();
21
- if (runtime === "now") return /* @__PURE__ */ new Date();
20
+ if (runtime === "cuid") return (context.createId ?? createId)();
21
+ if (runtime === "now") return (context.now ?? (() => /* @__PURE__ */ new Date()))();
22
22
  if (typeof runtime === "function") return runtime();
23
23
  }
24
+ /**
25
+ * Generate a fallback value for database-level defaults.
26
+ *
27
+ * This is used by adapters that cannot rely on database DEFAULT constraints,
28
+ * such as the in-memory adapter.
29
+ *
30
+ * @internal
31
+ */
32
+ function generateDatabaseDefault(column, context = {}) {
33
+ if (!column.default) return;
34
+ if ("value" in column.default) return column.default.value;
35
+ if ("dbSpecial" in column.default) {
36
+ if (column.default.dbSpecial === "now") return (context.now ?? (() => /* @__PURE__ */ new Date()))();
37
+ return;
38
+ }
39
+ }
24
40
 
25
41
  //#endregion
26
- export { generateRuntimeDefault };
42
+ export { generateDatabaseDefault, generateRuntimeDefault };
27
43
  //# sourceMappingURL=column-defaults.js.map