@timber-js/app 0.2.0-alpha.97 → 0.2.0-alpha.99

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 (372) hide show
  1. package/dist/_chunks/actions-CQ8Z8VGL.js +1061 -0
  2. package/dist/_chunks/actions-CQ8Z8VGL.js.map +1 -0
  3. package/dist/_chunks/build-output-helper-DXnW0qjz.js +61 -0
  4. package/dist/_chunks/build-output-helper-DXnW0qjz.js.map +1 -0
  5. package/dist/_chunks/{define-Itxvcd7F.js → define-B-Q_UMOD.js} +19 -23
  6. package/dist/_chunks/define-B-Q_UMOD.js.map +1 -0
  7. package/dist/_chunks/{define-C77ScO0m.js → define-CfBPoJb0.js} +24 -7
  8. package/dist/_chunks/define-CfBPoJb0.js.map +1 -0
  9. package/dist/_chunks/define-cookie-BjpIt4UC.js +194 -0
  10. package/dist/_chunks/define-cookie-BjpIt4UC.js.map +1 -0
  11. package/dist/_chunks/{format-CYBGxKtc.js → format-Bcn-Iv1x.js} +1 -1
  12. package/dist/_chunks/{format-CYBGxKtc.js.map → format-Bcn-Iv1x.js.map} +1 -1
  13. package/dist/_chunks/handler-store-B-lqaGyh.js +54 -0
  14. package/dist/_chunks/handler-store-B-lqaGyh.js.map +1 -0
  15. package/dist/_chunks/logger-0m8MsKdc.js +291 -0
  16. package/dist/_chunks/logger-0m8MsKdc.js.map +1 -0
  17. package/dist/_chunks/merge-search-params-BphMdht_.js +122 -0
  18. package/dist/_chunks/merge-search-params-BphMdht_.js.map +1 -0
  19. package/dist/_chunks/{metadata-routes-DS3eKNmf.js → metadata-routes-BU684ls2.js} +1 -1
  20. package/dist/_chunks/{metadata-routes-DS3eKNmf.js.map → metadata-routes-BU684ls2.js.map} +1 -1
  21. package/dist/_chunks/navigation-root-BCYczjml.js +96 -0
  22. package/dist/_chunks/navigation-root-BCYczjml.js.map +1 -0
  23. package/dist/_chunks/registry-I2ss-lvy.js +20 -0
  24. package/dist/_chunks/registry-I2ss-lvy.js.map +1 -0
  25. package/dist/_chunks/router-ref-h3-UaCQv.js +28 -0
  26. package/dist/_chunks/router-ref-h3-UaCQv.js.map +1 -0
  27. package/dist/_chunks/{schema-bridge-C3xl_vfb.js → schema-bridge-Cxu4l-7p.js} +1 -1
  28. package/dist/_chunks/{schema-bridge-C3xl_vfb.js.map → schema-bridge-Cxu4l-7p.js.map} +1 -1
  29. package/dist/_chunks/segment-classify-BjfuctV2.js +137 -0
  30. package/dist/_chunks/segment-classify-BjfuctV2.js.map +1 -0
  31. package/dist/_chunks/{segment-context-fHFLF1PE.js → segment-context-Dx_OizxD.js} +1 -1
  32. package/dist/_chunks/{segment-context-fHFLF1PE.js.map → segment-context-Dx_OizxD.js.map} +1 -1
  33. package/dist/_chunks/{router-ref-C8OCm7g7.js → ssr-data-B4CdH7rE.js} +2 -26
  34. package/dist/_chunks/ssr-data-B4CdH7rE.js.map +1 -0
  35. package/dist/_chunks/{stale-reload-BX5gL1r-.js → stale-reload-Bab885FO.js} +1 -1
  36. package/dist/_chunks/{stale-reload-BX5gL1r-.js.map → stale-reload-Bab885FO.js.map} +1 -1
  37. package/dist/_chunks/tracing-C8V-YGsP.js +329 -0
  38. package/dist/_chunks/tracing-C8V-YGsP.js.map +1 -0
  39. package/dist/_chunks/{use-query-states-BiV5GJgm.js → use-query-states-B2XTqxDR.js} +3 -19
  40. package/dist/_chunks/use-query-states-B2XTqxDR.js.map +1 -0
  41. package/dist/_chunks/{use-params-IOPu7E8t.js → use-segment-params-BkpKAQ7D.js} +9 -95
  42. package/dist/_chunks/use-segment-params-BkpKAQ7D.js.map +1 -0
  43. package/dist/_chunks/{interception-BbqMCVXa.js → walkers-Tg0Alwcg.js} +66 -87
  44. package/dist/_chunks/walkers-Tg0Alwcg.js.map +1 -0
  45. package/dist/_chunks/{dev-warnings-DpGRGoDi.js → warnings-Cg47l5sk.js} +3 -3
  46. package/dist/_chunks/warnings-Cg47l5sk.js.map +1 -0
  47. package/dist/adapters/build-output-helper.d.ts +28 -0
  48. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  49. package/dist/adapters/cloudflare.d.ts.map +1 -1
  50. package/dist/adapters/cloudflare.js +8 -28
  51. package/dist/adapters/cloudflare.js.map +1 -1
  52. package/dist/adapters/nitro.d.ts.map +1 -1
  53. package/dist/adapters/nitro.js +63 -31
  54. package/dist/adapters/nitro.js.map +1 -1
  55. package/dist/adapters/shared.d.ts +16 -0
  56. package/dist/adapters/shared.d.ts.map +1 -0
  57. package/dist/cache/index.js +9 -2
  58. package/dist/cache/index.js.map +1 -1
  59. package/dist/cache/timber-cache.d.ts.map +1 -1
  60. package/dist/client/error-boundary.js +2 -1
  61. package/dist/client/error-boundary.js.map +1 -1
  62. package/dist/client/form.d.ts +10 -24
  63. package/dist/client/form.d.ts.map +1 -1
  64. package/dist/client/index.d.ts +1 -5
  65. package/dist/client/index.d.ts.map +1 -1
  66. package/dist/client/index.js +41 -91
  67. package/dist/client/index.js.map +1 -1
  68. package/dist/client/internal.d.ts +2 -1
  69. package/dist/client/internal.d.ts.map +1 -1
  70. package/dist/client/internal.js +81 -7
  71. package/dist/client/internal.js.map +1 -1
  72. package/dist/client/rsc-fetch.d.ts.map +1 -1
  73. package/dist/client/state.d.ts +1 -1
  74. package/dist/client/use-cookie.d.ts +8 -0
  75. package/dist/client/use-cookie.d.ts.map +1 -1
  76. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +1 -1
  77. package/dist/client/use-segment-params.d.ts.map +1 -0
  78. package/dist/codec.d.ts +1 -1
  79. package/dist/codec.d.ts.map +1 -1
  80. package/dist/codec.js +2 -2
  81. package/dist/config-types.d.ts +28 -0
  82. package/dist/config-types.d.ts.map +1 -1
  83. package/dist/cookies/define-cookie.d.ts +87 -35
  84. package/dist/cookies/define-cookie.d.ts.map +1 -1
  85. package/dist/cookies/index.d.ts +2 -1
  86. package/dist/cookies/index.d.ts.map +1 -1
  87. package/dist/cookies/index.js +48 -2
  88. package/dist/cookies/index.js.map +1 -0
  89. package/dist/cookies/json-cookie.d.ts +64 -0
  90. package/dist/cookies/json-cookie.d.ts.map +1 -0
  91. package/dist/cookies/validation.d.ts +46 -0
  92. package/dist/cookies/validation.d.ts.map +1 -0
  93. package/dist/{plugins/dev-404-page.d.ts → dev-tools/404-page.d.ts} +9 -19
  94. package/dist/dev-tools/404-page.d.ts.map +1 -0
  95. package/dist/{plugins/dev-browser-logs.d.ts → dev-tools/browser-logs.d.ts} +1 -1
  96. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  97. package/dist/{plugins/dev-error-page.d.ts → dev-tools/error-page.d.ts} +2 -2
  98. package/dist/dev-tools/error-page.d.ts.map +1 -0
  99. package/dist/{server/dev-holding-server.d.ts → dev-tools/holding-server.d.ts} +5 -3
  100. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  101. package/dist/dev-tools/index.d.ts +31 -0
  102. package/dist/dev-tools/index.d.ts.map +1 -0
  103. package/dist/{server/dev-span-processor.d.ts → dev-tools/instrumentation.d.ts} +26 -6
  104. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  105. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  106. package/dist/dev-tools/logger.d.ts.map +1 -0
  107. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +1 -1
  108. package/dist/dev-tools/logs.d.ts.map +1 -0
  109. package/dist/{plugins/dev-error-overlay.d.ts → dev-tools/overlay.d.ts} +3 -12
  110. package/dist/dev-tools/overlay.d.ts.map +1 -0
  111. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  112. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  113. package/dist/{plugins/dev-terminal-error.d.ts → dev-tools/terminal.d.ts} +2 -2
  114. package/dist/dev-tools/terminal.d.ts.map +1 -0
  115. package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +1 -1
  116. package/dist/dev-tools/warnings.d.ts.map +1 -0
  117. package/dist/index.d.ts +1 -0
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +285 -133
  120. package/dist/index.js.map +1 -1
  121. package/dist/plugin-context.d.ts +1 -1
  122. package/dist/plugin-context.d.ts.map +1 -1
  123. package/dist/plugins/adapter-build.d.ts.map +1 -1
  124. package/dist/plugins/build-report.d.ts +6 -4
  125. package/dist/plugins/build-report.d.ts.map +1 -1
  126. package/dist/routing/convention-lint.d.ts.map +1 -1
  127. package/dist/routing/index.d.ts +5 -3
  128. package/dist/routing/index.d.ts.map +1 -1
  129. package/dist/routing/index.js +3 -3
  130. package/dist/routing/scanner.d.ts +1 -10
  131. package/dist/routing/scanner.d.ts.map +1 -1
  132. package/dist/routing/segment-classify.d.ts +37 -8
  133. package/dist/routing/segment-classify.d.ts.map +1 -1
  134. package/dist/routing/status-file-lint.d.ts.map +1 -1
  135. package/dist/routing/types.d.ts +63 -23
  136. package/dist/routing/types.d.ts.map +1 -1
  137. package/dist/routing/walkers.d.ts +51 -0
  138. package/dist/routing/walkers.d.ts.map +1 -0
  139. package/dist/search-params/define.d.ts +25 -7
  140. package/dist/search-params/define.d.ts.map +1 -1
  141. package/dist/search-params/index.js +5 -3
  142. package/dist/search-params/index.js.map +1 -1
  143. package/dist/search-params/wrappers.d.ts +2 -2
  144. package/dist/search-params/wrappers.d.ts.map +1 -1
  145. package/dist/segment-params/define.d.ts +23 -6
  146. package/dist/segment-params/define.d.ts.map +1 -1
  147. package/dist/segment-params/index.js +1 -1
  148. package/dist/server/access-gate.d.ts +4 -3
  149. package/dist/server/access-gate.d.ts.map +1 -1
  150. package/dist/server/action-handler.d.ts +15 -6
  151. package/dist/server/action-handler.d.ts.map +1 -1
  152. package/dist/server/als-registry.d.ts +5 -5
  153. package/dist/server/als-registry.d.ts.map +1 -1
  154. package/dist/server/asset-headers.d.ts +1 -15
  155. package/dist/server/asset-headers.d.ts.map +1 -1
  156. package/dist/server/cookie-context.d.ts +170 -0
  157. package/dist/server/cookie-context.d.ts.map +1 -0
  158. package/dist/server/cookie-parsing.d.ts +51 -0
  159. package/dist/server/cookie-parsing.d.ts.map +1 -0
  160. package/dist/server/deny-boundary.d.ts +90 -0
  161. package/dist/server/deny-boundary.d.ts.map +1 -0
  162. package/dist/server/deny-renderer.d.ts.map +1 -1
  163. package/dist/server/early-hints-sender.d.ts.map +1 -1
  164. package/dist/server/html-injector-core.d.ts +212 -0
  165. package/dist/server/html-injector-core.d.ts.map +1 -0
  166. package/dist/server/html-injectors.d.ts +59 -59
  167. package/dist/server/html-injectors.d.ts.map +1 -1
  168. package/dist/server/index.d.ts +5 -4
  169. package/dist/server/index.d.ts.map +1 -1
  170. package/dist/server/index.js +4 -149
  171. package/dist/server/index.js.map +1 -1
  172. package/dist/server/internal.d.ts +6 -4
  173. package/dist/server/internal.d.ts.map +1 -1
  174. package/dist/server/internal.js +852 -852
  175. package/dist/server/internal.js.map +1 -1
  176. package/dist/server/logger.d.ts +14 -0
  177. package/dist/server/logger.d.ts.map +1 -1
  178. package/dist/server/middleware-runner.d.ts +17 -0
  179. package/dist/server/middleware-runner.d.ts.map +1 -1
  180. package/dist/server/node-stream-transforms.d.ts +46 -49
  181. package/dist/server/node-stream-transforms.d.ts.map +1 -1
  182. package/dist/server/param-coercion.d.ts +26 -0
  183. package/dist/server/param-coercion.d.ts.map +1 -0
  184. package/dist/server/pipeline-helpers.d.ts +95 -0
  185. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  186. package/dist/server/pipeline-outcome.d.ts +49 -0
  187. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  188. package/dist/server/pipeline-phases.d.ts +52 -0
  189. package/dist/server/pipeline-phases.d.ts.map +1 -0
  190. package/dist/server/pipeline.d.ts +51 -32
  191. package/dist/server/pipeline.d.ts.map +1 -1
  192. package/dist/server/port-resolution.d.ts +117 -0
  193. package/dist/server/port-resolution.d.ts.map +1 -0
  194. package/dist/server/request-context.d.ts +22 -159
  195. package/dist/server/request-context.d.ts.map +1 -1
  196. package/dist/server/route-element-builder.d.ts.map +1 -1
  197. package/dist/server/route-matcher.d.ts +20 -47
  198. package/dist/server/route-matcher.d.ts.map +1 -1
  199. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  200. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  201. package/dist/server/rsc-entry/helpers.d.ts +1 -1
  202. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  203. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  204. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  205. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  206. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  207. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  208. package/dist/server/state-tree-diff.d.ts.map +1 -1
  209. package/dist/server/status-code-resolver.d.ts +16 -11
  210. package/dist/server/status-code-resolver.d.ts.map +1 -1
  211. package/dist/server/tracing.d.ts +1 -1
  212. package/dist/server/tracing.d.ts.map +1 -1
  213. package/dist/server/tree-builder.d.ts +45 -16
  214. package/dist/server/tree-builder.d.ts.map +1 -1
  215. package/dist/server/types.d.ts +48 -0
  216. package/dist/server/types.d.ts.map +1 -1
  217. package/dist/server/utils/escape-html.d.ts +14 -0
  218. package/dist/server/utils/escape-html.d.ts.map +1 -0
  219. package/dist/shims/headers.d.ts +2 -2
  220. package/dist/shims/headers.d.ts.map +1 -1
  221. package/dist/shims/navigation-client.d.ts +3 -1
  222. package/dist/shims/navigation-client.d.ts.map +1 -1
  223. package/dist/shims/navigation.d.ts +9 -4
  224. package/dist/shims/navigation.d.ts.map +1 -1
  225. package/dist/utils/directive-parser.d.ts +0 -45
  226. package/dist/utils/directive-parser.d.ts.map +1 -1
  227. package/package.json +1 -1
  228. package/src/adapters/build-output-helper.ts +77 -0
  229. package/src/adapters/cloudflare.ts +10 -50
  230. package/src/adapters/nitro.ts +66 -50
  231. package/src/adapters/shared.ts +40 -0
  232. package/src/cache/timber-cache.ts +3 -2
  233. package/src/client/form.tsx +17 -25
  234. package/src/client/index.ts +16 -9
  235. package/src/client/internal.ts +3 -2
  236. package/src/client/router.ts +1 -1
  237. package/src/client/rsc-fetch.ts +15 -0
  238. package/src/client/state.ts +2 -2
  239. package/src/client/use-cookie.ts +29 -0
  240. package/src/codec.ts +3 -7
  241. package/src/config-types.ts +28 -0
  242. package/src/cookies/define-cookie.ts +271 -78
  243. package/src/cookies/index.ts +11 -8
  244. package/src/cookies/json-cookie.ts +105 -0
  245. package/src/cookies/validation.ts +134 -0
  246. package/src/{plugins/dev-404-page.ts → dev-tools/404-page.ts} +17 -48
  247. package/src/{plugins/dev-error-page.ts → dev-tools/error-page.ts} +5 -32
  248. package/src/{server/dev-holding-server.ts → dev-tools/holding-server.ts} +4 -2
  249. package/src/dev-tools/index.ts +90 -0
  250. package/src/dev-tools/instrumentation.ts +176 -0
  251. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +2 -2
  252. package/src/{plugins/dev-error-overlay.ts → dev-tools/overlay.ts} +5 -23
  253. package/src/dev-tools/stack-classifier.ts +75 -0
  254. package/src/{plugins/dev-terminal-error.ts → dev-tools/terminal.ts} +4 -38
  255. package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +1 -1
  256. package/src/index.ts +95 -34
  257. package/src/plugin-context.ts +1 -1
  258. package/src/plugins/adapter-build.ts +3 -1
  259. package/src/plugins/build-report.ts +13 -22
  260. package/src/plugins/dev-server.ts +3 -3
  261. package/src/plugins/routing.ts +14 -12
  262. package/src/plugins/shims.ts +1 -1
  263. package/src/plugins/static-build.ts +1 -1
  264. package/src/routing/codegen.ts +1 -1
  265. package/src/routing/convention-lint.ts +9 -8
  266. package/src/routing/index.ts +5 -3
  267. package/src/routing/interception.ts +1 -1
  268. package/src/routing/scanner.ts +22 -95
  269. package/src/routing/segment-classify.ts +107 -8
  270. package/src/routing/status-file-lint.ts +7 -5
  271. package/src/routing/types.ts +63 -23
  272. package/src/routing/walkers.ts +90 -0
  273. package/src/search-params/define.ts +71 -15
  274. package/src/search-params/wrappers.ts +9 -2
  275. package/src/segment-params/define.ts +66 -13
  276. package/src/server/access-gate.tsx +9 -8
  277. package/src/server/action-handler.ts +34 -38
  278. package/src/server/als-registry.ts +5 -5
  279. package/src/server/asset-headers.ts +8 -34
  280. package/src/server/cookie-context.ts +468 -0
  281. package/src/server/cookie-parsing.ts +135 -0
  282. package/src/server/{deny-page-resolver.ts → deny-boundary.ts} +78 -14
  283. package/src/server/deny-renderer.ts +7 -12
  284. package/src/server/early-hints-sender.ts +3 -2
  285. package/src/server/fallback-error.ts +2 -2
  286. package/src/server/html-injector-core.ts +403 -0
  287. package/src/server/html-injectors.ts +158 -297
  288. package/src/server/index.ts +13 -14
  289. package/src/server/internal.ts +10 -3
  290. package/src/server/logger.ts +23 -0
  291. package/src/server/middleware-runner.ts +44 -0
  292. package/src/server/node-stream-transforms.ts +108 -248
  293. package/src/server/param-coercion.ts +76 -0
  294. package/src/server/pipeline-helpers.ts +204 -0
  295. package/src/server/pipeline-outcome.ts +167 -0
  296. package/src/server/pipeline-phases.ts +409 -0
  297. package/src/server/pipeline.ts +70 -540
  298. package/src/server/port-resolution.ts +215 -0
  299. package/src/server/request-context.ts +46 -451
  300. package/src/server/route-element-builder.ts +8 -4
  301. package/src/server/route-matcher.ts +28 -60
  302. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  303. package/src/server/rsc-entry/api-handler.ts +2 -2
  304. package/src/server/rsc-entry/error-renderer.ts +2 -2
  305. package/src/server/rsc-entry/helpers.ts +2 -7
  306. package/src/server/rsc-entry/index.ts +81 -366
  307. package/src/server/rsc-entry/render-route.ts +304 -0
  308. package/src/server/rsc-entry/rsc-payload.ts +1 -1
  309. package/src/server/rsc-entry/ssr-renderer.ts +2 -2
  310. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  311. package/src/server/sitemap-generator.ts +1 -1
  312. package/src/server/slot-resolver.ts +1 -1
  313. package/src/server/ssr-entry.ts +1 -1
  314. package/src/server/state-tree-diff.ts +4 -1
  315. package/src/server/status-code-resolver.ts +112 -128
  316. package/src/server/tracing.ts +3 -3
  317. package/src/server/tree-builder.ts +134 -56
  318. package/src/server/types.ts +52 -0
  319. package/src/server/utils/escape-html.ts +20 -0
  320. package/src/shims/headers.ts +3 -3
  321. package/src/shims/navigation-client.ts +4 -3
  322. package/src/shims/navigation.ts +9 -7
  323. package/src/utils/directive-parser.ts +0 -392
  324. package/dist/_chunks/actions-DLnUaR65.js +0 -421
  325. package/dist/_chunks/actions-DLnUaR65.js.map +0 -1
  326. package/dist/_chunks/als-registry-HS0LGUl2.js +0 -41
  327. package/dist/_chunks/als-registry-HS0LGUl2.js.map +0 -1
  328. package/dist/_chunks/debug-ECi_61pb.js +0 -108
  329. package/dist/_chunks/debug-ECi_61pb.js.map +0 -1
  330. package/dist/_chunks/define-C77ScO0m.js.map +0 -1
  331. package/dist/_chunks/define-Itxvcd7F.js.map +0 -1
  332. package/dist/_chunks/define-cookie-BowvzoP0.js +0 -94
  333. package/dist/_chunks/define-cookie-BowvzoP0.js.map +0 -1
  334. package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +0 -1
  335. package/dist/_chunks/interception-BbqMCVXa.js.map +0 -1
  336. package/dist/_chunks/merge-search-params-Cm_KIWDX.js +0 -41
  337. package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +0 -1
  338. package/dist/_chunks/request-context-CK5tZqIP.js +0 -478
  339. package/dist/_chunks/request-context-CK5tZqIP.js.map +0 -1
  340. package/dist/_chunks/router-ref-C8OCm7g7.js.map +0 -1
  341. package/dist/_chunks/segment-classify-BDNn6EzD.js +0 -65
  342. package/dist/_chunks/segment-classify-BDNn6EzD.js.map +0 -1
  343. package/dist/_chunks/tracing-CCYbKn5n.js +0 -238
  344. package/dist/_chunks/tracing-CCYbKn5n.js.map +0 -1
  345. package/dist/_chunks/use-params-IOPu7E8t.js.map +0 -1
  346. package/dist/_chunks/use-query-states-BiV5GJgm.js.map +0 -1
  347. package/dist/client/use-params.d.ts.map +0 -1
  348. package/dist/plugins/dev-404-page.d.ts.map +0 -1
  349. package/dist/plugins/dev-browser-logs.d.ts.map +0 -1
  350. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  351. package/dist/plugins/dev-error-page.d.ts.map +0 -1
  352. package/dist/plugins/dev-logs.d.ts.map +0 -1
  353. package/dist/plugins/dev-terminal-error.d.ts.map +0 -1
  354. package/dist/server/deny-page-resolver.d.ts +0 -52
  355. package/dist/server/deny-page-resolver.d.ts.map +0 -1
  356. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  357. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  358. package/dist/server/dev-holding-server.d.ts.map +0 -1
  359. package/dist/server/dev-logger.d.ts.map +0 -1
  360. package/dist/server/dev-span-processor.d.ts.map +0 -1
  361. package/dist/server/dev-warnings.d.ts.map +0 -1
  362. package/dist/server/manifest-status-resolver.d.ts +0 -58
  363. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  364. package/dist/server/page-deny-boundary.d.ts +0 -31
  365. package/dist/server/page-deny-boundary.d.ts.map +0 -1
  366. package/src/server/dev-fetch-instrumentation.ts +0 -96
  367. package/src/server/dev-span-processor.ts +0 -78
  368. package/src/server/manifest-status-resolver.ts +0 -215
  369. package/src/server/page-deny-boundary.tsx +0 -56
  370. /package/src/client/{use-params.ts → use-segment-params.ts} +0 -0
  371. /package/src/{plugins/dev-browser-logs.ts → dev-tools/browser-logs.ts} +0 -0
  372. /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
@@ -0,0 +1,449 @@
1
+ /**
2
+ * Action-dispatch wrapper around the route pipeline.
3
+ *
4
+ * Extracted from rsc-entry/index.ts so the wiring can be unit-tested in
5
+ * isolation from Vite's virtual modules. The wrapper is responsible for
6
+ * four things, in order:
7
+ *
8
+ * 1. **Pipeline-boundary CSRF validation** — runs on EVERY unsafe-method
9
+ * request, before any dispatch decision. This is the only line of
10
+ * defense for `route.ts` API handlers, which never see the action
11
+ * handler. See LOCAL-773.
12
+ *
13
+ * 2. **Middleware-on-actions execution** — when the request is a server
14
+ * action POST and `actions.runMiddleware !== false`, the matched
15
+ * route's `middleware.ts` chain runs BEFORE the action body. This
16
+ * closes the Next.js CVE-2025-29927 class of bug, where developers
17
+ * reasonably believe `middleware.ts` runs on every request and find
18
+ * out (the hard way) that actions silently bypass it. Middleware can
19
+ * short-circuit with a `Response`, `redirect()`, or `deny()`; can
20
+ * mutate cookies; and can inject request headers visible to the
21
+ * action body via `getHeaders()`. See TIM-871.
22
+ *
23
+ * 3. **Server action interception** — POST requests carrying an
24
+ * `x-rsc-action` header or React's `$ACTION_REF` form fields are
25
+ * handed to `handleActionRequest`, which executes the action and
26
+ * returns either an RSC response or a no-JS rerender signal.
27
+ *
28
+ * 4. **No-JS validation rerender** — when an action returns flash data
29
+ * instead of a redirect, the wrapper re-runs the page render via the
30
+ * pipeline with the post-action cookie state and `runWithFormFlash`
31
+ * so server components can read the flash. The synthetic GET is
32
+ * marked via `markRequestBypassMiddleware` so the pipeline does not
33
+ * double-execute middleware on it. See TIM-836 / TIM-837 / TIM-871.
34
+ *
35
+ * Anything else falls through to `pipeline(req)` for normal route handling.
36
+ *
37
+ * The wrapper takes its dependencies as parameters (no module-level
38
+ * imports of virtual modules) so tests can construct it with stub
39
+ * pipelines, stub revalidate renderers, and stub route matchers.
40
+ */
41
+
42
+ import type { FormRerender } from '../action-handler.js';
43
+ import { handleActionRequest, isActionRequest } from '../action-handler.js';
44
+ import type { BodyLimitsConfig } from '../body-limits.js';
45
+ import { validateCsrf, type CsrfConfig } from '../csrf.js';
46
+ import { runWithFormFlash } from '../form-flash.js';
47
+ import { seedRequestCookies } from '../cookie-context.js';
48
+ import { markRequestBypassMiddleware } from '../middleware-runner.js';
49
+ import { DenySignal } from '../primitives.js';
50
+ import { canonicalize } from '../canonicalize.js';
51
+ import {
52
+ buildRedirectResponse,
53
+ cloneWithMutableHeaders,
54
+ fireOnRequestError,
55
+ } from '../pipeline-helpers.js';
56
+ import { logRenderError } from '../logger.js';
57
+ import type { RouteMatch, RouteMatcher } from '../pipeline.js';
58
+ import type { SensitiveFieldsOption } from '../sensitive-fields.js';
59
+ import type { RevalidateRenderer } from '../actions.js';
60
+ import { runMiddlewareForAction, type CoerceSegmentParamsFn } from './action-middleware-runner.js';
61
+
62
+ // ─── Types ────────────────────────────────────────────────────────────────
63
+
64
+ /**
65
+ * Build a `RevalidateRenderer` for a specific request.
66
+ *
67
+ * The renderer needs to forward cookies/headers from the originating
68
+ * request when fetching the revalidated route. We pass the request in
69
+ * via a builder so the wrapper doesn't need to know about route matching,
70
+ * segment param coercion, or element building — those concerns stay in
71
+ * `rsc-entry/index.ts`.
72
+ */
73
+ export type RevalidateRendererFactory = (req: Request) => RevalidateRenderer;
74
+
75
+ /** Optional renderer for fallback deny pages — mirrors `PipelineConfig.renderDenyFallback`. */
76
+ export type RenderDenyFallbackFn = (
77
+ deny: DenySignal,
78
+ req: Request,
79
+ responseHeaders: Headers,
80
+ match?: RouteMatch
81
+ ) => Response | Promise<Response>;
82
+
83
+ /** Dependencies for the action-dispatch wrapper. */
84
+ export interface ActionDispatchDeps {
85
+ /** CSRF configuration (Origin allow-list, on/off switch). */
86
+ csrfConfig: CsrfConfig;
87
+ /** Body size limits forwarded to `handleActionRequest`. */
88
+ bodyLimits?: BodyLimitsConfig['limits'];
89
+ /** Sensitive-field deny-list forwarded to `handleActionRequest`. */
90
+ sensitiveFields?: SensitiveFieldsOption;
91
+ /** Per-request factory that builds a `RevalidateRenderer`. */
92
+ buildRevalidateRenderer: RevalidateRendererFactory;
93
+ /**
94
+ * Route matcher — when present, enables middleware-on-actions execution.
95
+ * Mirrors `PipelineConfig.matchRoute`. Tests that don't exercise the
96
+ * middleware path may omit this; the wrapper falls back to the legacy
97
+ * "actions skip middleware" behavior.
98
+ */
99
+ matchRoute?: RouteMatcher;
100
+ /**
101
+ * Segment-param coercer — runs the matched route's `params.ts` codecs
102
+ * so the middleware context sees typed `segmentParams`. Required when
103
+ * `matchRoute` is provided.
104
+ */
105
+ coerceSegmentParams?: CoerceSegmentParamsFn;
106
+ /**
107
+ * Renderer for fallback deny pages — used when middleware throws a
108
+ * `DenySignal` and the framework wants to render `403.tsx` / `404.tsx`
109
+ * instead of returning a bare empty Response. Optional — when omitted
110
+ * the wrapper falls back to a bare status response.
111
+ */
112
+ renderDenyFallback?: RenderDenyFallbackFn;
113
+ /**
114
+ * Whether to run `middleware.ts` on server action requests. Defaults
115
+ * to `true` (the safe default). Controlled by
116
+ * `actions.runMiddleware` in `timber.config.ts`. See TIM-871.
117
+ */
118
+ runMiddleware?: boolean;
119
+ /**
120
+ * Whether to strip trailing slashes during pathname canonicalization
121
+ * for route matching. Mirrors `PipelineConfig.stripTrailingSlash`;
122
+ * defaults to `true` when omitted, matching the page pipeline. The
123
+ * wrapper MUST canonicalize before matching so non-canonical action
124
+ * POSTs (`/admin/`, `/admin//`, encoded separators) cannot bypass the
125
+ * middleware gate by missing the route match and falling through to
126
+ * the legacy path. See TIM-871 / codex review.
127
+ */
128
+ stripTrailingSlash?: boolean;
129
+ }
130
+
131
+ // ─── Implementation ───────────────────────────────────────────────────────
132
+
133
+ /**
134
+ * Wrap a pipeline function with CSRF validation and server-action dispatch.
135
+ *
136
+ * The returned handler is the framework's outermost request entry point.
137
+ * Its responsibilities are documented in the file header.
138
+ *
139
+ * The duplicate `validateCsrf` call inside `handleActionRequest` is left in
140
+ * place as defense-in-depth (no-op on the happy path) so the action handler
141
+ * remains safe to call from any future entry point that bypasses this
142
+ * wrapper. See LOCAL-773.
143
+ */
144
+ export function wrapPipelineWithActionDispatch(
145
+ pipeline: (req: Request) => Promise<Response>,
146
+ deps: ActionDispatchDeps
147
+ ): (req: Request) => Promise<Response> {
148
+ const middlewareEnabled = deps.runMiddleware !== false;
149
+ const stripTrailingSlash = deps.stripTrailingSlash ?? true;
150
+
151
+ return async (req: Request): Promise<Response> => {
152
+ // ─── 1. Pipeline-boundary CSRF validation (LOCAL-773) ─────────────
153
+ //
154
+ // Runs on EVERY unsafe-method request, before any dispatch decision.
155
+ // Without this, `route.ts` PUT/PATCH/DELETE handlers and POSTs with
156
+ // `Content-Type: application/json` or `text/plain` would reach the
157
+ // route handler with no Origin check at all — `isActionRequest` only
158
+ // matches POST + form/multipart/x-rsc-action.
159
+ //
160
+ // `text/plain` POST is a CORS-simple request, so a cross-site
161
+ // `<form enctype="text/plain">` submission carries `SameSite=Lax`
162
+ // cookies (the framework's own default).
163
+ const csrfResult = validateCsrf(req, deps.csrfConfig);
164
+ if (!csrfResult.ok) {
165
+ return new Response(null, { status: csrfResult.status });
166
+ }
167
+
168
+ // ─── 2. Server action interception ────────────────────────────────
169
+ if (isActionRequest(req)) {
170
+ // ─── 2a. Route-type check + canonicalize (TIM-870) ──────────────
171
+ //
172
+ // Canonicalize and match the route BEFORE any body parsing. If the
173
+ // matched route is an API route (route.ts), skip action detection
174
+ // entirely and dispatch straight to the pipeline. Server actions
175
+ // only live on page routes; POSTs to route.ts are API requests
176
+ // whose body must reach the handler untouched — not pre-parsed
177
+ // looking for $ACTION_REF fields.
178
+ //
179
+ // This also avoids allocating a full formData() parse over large
180
+ // multipart uploads (e.g. 50 MB file uploads to /api/upload) that
181
+ // would otherwise be buffered and discarded by handleFormAction.
182
+ //
183
+ // The same canonicalized match is reused for the middleware-on-
184
+ // actions path below, avoiding a redundant match.
185
+ let match: RouteMatch | null = null;
186
+
187
+ if (deps.matchRoute) {
188
+ // Canonicalize the pathname BEFORE matching, with the exact same
189
+ // rules the page pipeline uses (`canonicalize()` in
190
+ // `pipeline-phases.ts` stage 1). Without this, an attacker could
191
+ // POST to a non-canonical variant of an authenticated route —
192
+ // `/admin/` with a trailing slash, `/admin//` with a doubled
193
+ // slash, `/adm%69n` with percent-escapes, `/admin%2fnested` with
194
+ // an encoded separator — fail the match here, fall through to
195
+ // the legacy "no middleware" path, and still reach the action
196
+ // handler. The canonicalization step closes that bypass and
197
+ // guarantees the wrapper matches EXACTLY the same route the page
198
+ // pipeline would match. A canonicalize failure (encoded
199
+ // separator, null byte, malformed escape, `..` escaping root)
200
+ // returns the canonicalizer's status directly — the request is
201
+ // malformed, never dispatched. See TIM-871 (codex review).
202
+ const url = new URL(req.url);
203
+ const canonical = canonicalize(url.pathname, stripTrailingSlash);
204
+ if (!canonical.ok) {
205
+ return new Response(null, { status: canonical.status });
206
+ }
207
+ match = deps.matchRoute(canonical.pathname);
208
+
209
+ // Skip action detection for route.ts API handlers (TIM-870).
210
+ // Server actions only target page routes. A POST to a route.ts
211
+ // path is an API request — the full body should reach the route
212
+ // handler without being pre-parsed by handleFormAction.
213
+ if (match) {
214
+ const leaf = match.segments[match.segments.length - 1];
215
+ if (leaf?.route) {
216
+ return pipeline(req);
217
+ }
218
+ }
219
+ }
220
+
221
+ // ─── 2b. Middleware-on-actions (TIM-871) ────────────────────────
222
+ //
223
+ // When middleware execution is enabled and the request matches a
224
+ // known route, run the matched chain BEFORE the action handler.
225
+ // The middleware run happens inside its own `runWithRequestContext`
226
+ // scope so middleware can read/write cookies and inject request
227
+ // headers via the standard ALS APIs. Mutations are captured at the
228
+ // end of the scope and threaded into the action handler's own ALS
229
+ // scope via `seedRequestCookies` + a request rebuilt with overlay
230
+ // headers merged in.
231
+ let downstreamReq = req;
232
+ let middlewareSetCookieHeaders: string[] = [];
233
+
234
+ if (
235
+ middlewareEnabled &&
236
+ deps.coerceSegmentParams &&
237
+ match &&
238
+ match.middlewareChain.length > 0
239
+ ) {
240
+ const outcome = await runMiddlewareForAction(req, match, deps.coerceSegmentParams);
241
+
242
+ // ─── Translate middleware outcome ─────────────────────────
243
+ if (outcome.kind === 'param-coercion-error') {
244
+ // Bad segment params → 404. Matches the page pipeline.
245
+ return new Response(null, { status: 404 });
246
+ }
247
+ if (outcome.kind === 'error') {
248
+ // Unhandled middleware error → 500.
249
+ return new Response(null, { status: 500 });
250
+ }
251
+ if (outcome.kind === 'short-circuit') {
252
+ // Middleware returned a Response. Apply its Set-Cookie
253
+ // snapshot before returning. Clone unconditionally so the
254
+ // header bag is mutable.
255
+ const finalResponse = cloneWithMutableHeaders(outcome.response);
256
+ for (const value of outcome.setCookieHeaders) {
257
+ finalResponse.headers.append('Set-Cookie', value);
258
+ }
259
+ return finalResponse;
260
+ }
261
+ if (outcome.kind === 'redirect') {
262
+ // RedirectSignal from middleware → standard redirect Response.
263
+ // Use `buildRedirectResponse` so the with-JS path produces a
264
+ // 204 + X-Timber-Redirect (SPA navigation) and the no-JS path
265
+ // produces a real HTTP 30x — exactly the same translation
266
+ // the page pipeline applies in `outcomeToResponse`.
267
+ const headers = new Headers();
268
+ for (const value of outcome.setCookieHeaders) {
269
+ headers.append('Set-Cookie', value);
270
+ }
271
+ return buildRedirectResponse(outcome.signal, req, headers);
272
+ }
273
+ if (outcome.kind === 'deny') {
274
+ // DenySignal from middleware → render the matched route's
275
+ // colocated deny page if available, otherwise a bare empty
276
+ // status response. Mirrors the page pipeline's deny handling.
277
+ const headers = new Headers();
278
+ for (const value of outcome.setCookieHeaders) {
279
+ headers.append('Set-Cookie', value);
280
+ }
281
+ if (deps.renderDenyFallback) {
282
+ try {
283
+ return cloneWithMutableHeaders(
284
+ await deps.renderDenyFallback(outcome.signal, req, headers, outcome.match)
285
+ );
286
+ } catch (denyRenderError) {
287
+ // Deny page rendering failed — log before falling through to bare
288
+ // response. Without this, a crashing deny page on the action path
289
+ // produces a blank response with zero server-side signal. See TIM-876.
290
+ const url = new URL(req.url);
291
+ logRenderError({ method: req.method, path: url.pathname, error: denyRenderError });
292
+ await fireOnRequestError(denyRenderError, req, 'render');
293
+ }
294
+ }
295
+ return new Response(null, { status: outcome.signal.status, headers });
296
+ }
297
+
298
+ // ─── Continue: middleware passed ──────────────────────────
299
+ //
300
+ // Build a downstream Request that the action handler will see:
301
+ // - Original headers + middleware's request-header overlay
302
+ // merged on top, so `getHeaders()` inside the action body
303
+ // observes the injected values.
304
+ // - Cookie header dropped; the post-middleware RYW cookie
305
+ // state is threaded directly into the action handler's
306
+ // request context via `seedRequestCookies`. This avoids
307
+ // a Cookie-header round-trip that would re-parse via
308
+ // `parseCookieHeader` — the same H-3 smuggling primitive
309
+ // mitigated by TIM-868. The action's own cookie reads
310
+ // therefore observe both the original cookies and any
311
+ // middleware mutations, with no cleartext encoding step
312
+ // in between.
313
+ // - Body forwarded as-is so the action handler can decode it.
314
+ // - Method preserved (POST).
315
+ //
316
+ // We hold the middleware Set-Cookie snapshot to prepend to the
317
+ // final response below — middleware writes precede action
318
+ // writes in the response order so the browser's last-wins
319
+ // resolution lets the action override middleware on conflict.
320
+ const mergedHeaders = new Headers(req.headers);
321
+ outcome.overlay.forEach((value, key) => {
322
+ mergedHeaders.set(key, value);
323
+ });
324
+ mergedHeaders.delete('cookie');
325
+ downstreamReq = new Request(req.url, {
326
+ method: req.method,
327
+ headers: mergedHeaders,
328
+ body: req.body,
329
+ // Required by undici when constructing a Request with a
330
+ // streaming body — `req.body` is a ReadableStream and the
331
+ // fetch spec needs an explicit half-duplex declaration.
332
+ // @ts-expect-error — `duplex` is not in the standard Request init type yet.
333
+ duplex: 'half',
334
+ });
335
+ seedRequestCookies(downstreamReq, outcome.cookies);
336
+ middlewareSetCookieHeaders = outcome.setCookieHeaders;
337
+ }
338
+
339
+ // ─── 2c. Action handler dispatch ────────────────────────────────
340
+ //
341
+ // The revalidate renderer is built from the ORIGINAL request, not
342
+ // `downstreamReq`. The downstream request had its `cookie` header
343
+ // stripped (the post-middleware RYW cookie state is threaded
344
+ // through ALS via `seedRequestCookies` instead, to preserve the
345
+ // H-3 smuggling invariant from TIM-868). But the revalidate
346
+ // renderer in `rsc-entry/index.ts` forwards `req.headers` onto the
347
+ // synthetic revalidation Request it builds for the target path —
348
+ // if we passed `downstreamReq` here, that synthetic request would
349
+ // carry no cookies, and an action that calls `revalidatePath()`
350
+ // would re-render the target route with no session / tenant / auth
351
+ // context. Using `req` (the unmodified inbound request) preserves
352
+ // the original cookie header for the revalidation side channel
353
+ // while `seedRequestCookies` handles the middleware RYW state for
354
+ // the action body itself. See TIM-871 (codex review).
355
+ const actionResponse = await handleActionRequest(downstreamReq, {
356
+ csrf: deps.csrfConfig,
357
+ bodyLimits: { limits: deps.bodyLimits },
358
+ sensitiveFields: deps.sensitiveFields,
359
+ revalidateRenderer: deps.buildRevalidateRenderer(req),
360
+ });
361
+
362
+ if (actionResponse) {
363
+ // ─── 3. No-JS validation rerender ─────────────────────────────
364
+ if ('rerender' in actionResponse) {
365
+ const formRerender = actionResponse as FormRerender;
366
+ // Build a synthetic GET request for the rerender pipeline:
367
+ // - Same URL (so route matching lands on the same page)
368
+ // - Cookie header DROPPED entirely. The post-action RYW state
369
+ // is threaded into the rerender request context as a parsed
370
+ // `Map<string, string>` via `seedRequestCookies` below, so
371
+ // `parseCookieHeader` is never called for this request.
372
+ // This eliminates the value-smuggling primitive that the
373
+ // previous string round-trip exposed: a `;`-laden cookie
374
+ // value would otherwise split into sibling cookies during
375
+ // re-parse and let an attacker inject `role=admin` /
376
+ // forged session cookies into the rerender response. See
377
+ // ONGOING_SECURITY.md H-3 (TIM-868) and TIM-837.
378
+ // - Method GET because the rerender is conceptually a page
379
+ // render, not a re-POST. The pipeline doesn't branch on
380
+ // method for page rendering, and constructing a POST without
381
+ // a body is awkward across Request implementations.
382
+ // - Marked via `markRequestBypassMiddleware` so the pipeline
383
+ // skips its middleware phase on this synthetic request.
384
+ // Middleware already ran once on the inbound POST (above);
385
+ // letting the pipeline run it again would double-execute
386
+ // auth, rate limiting, and request-header injection. See
387
+ // TIM-871.
388
+ const rerenderHeaders = new Headers(req.headers);
389
+ rerenderHeaders.delete('cookie');
390
+ const rerenderReq = new Request(req.url, {
391
+ method: 'GET',
392
+ headers: rerenderHeaders,
393
+ });
394
+ // Seed BEFORE pipeline() runs — runWithRequestContext consumes
395
+ // the seed when it constructs the per-request store.
396
+ seedRequestCookies(rerenderReq, formRerender.cookies);
397
+ markRequestBypassMiddleware(rerenderReq);
398
+ const response = await runWithFormFlash(formRerender.rerender, () =>
399
+ pipeline(rerenderReq)
400
+ );
401
+ // Apply Set-Cookie headers snapshotted from the action's ALS scope.
402
+ // The pipeline above runs in its own request context with a fresh
403
+ // cookie jar, so cookies set inside the action would otherwise be
404
+ // silently dropped on the no-JS rerender path. See TIM-836
405
+ // (LOCAL-740). Middleware-set cookies are prepended first so
406
+ // browser last-wins still lets action writes override.
407
+ for (const value of middlewareSetCookieHeaders) {
408
+ response.headers.append('Set-Cookie', value);
409
+ }
410
+ for (const value of formRerender.setCookieHeaders) {
411
+ response.headers.append('Set-Cookie', value);
412
+ }
413
+ return response;
414
+ }
415
+ // Apply middleware Set-Cookie snapshot to the action's RSC
416
+ // response. Action's own cookies were already appended inside
417
+ // `handleActionRequest` via `getSetCookieHeaders()` before the
418
+ // action ALS scope exited; we prepend middleware writes so
419
+ // browser last-wins lets action writes take precedence on
420
+ // conflicting names.
421
+ if (middlewareSetCookieHeaders.length > 0) {
422
+ // Middleware writes go FIRST in the response order, so we
423
+ // build a fresh Headers and rebuild the Response. Cloning the
424
+ // Response keeps the body stream intact.
425
+ const mergedHeaders = new Headers();
426
+ for (const value of middlewareSetCookieHeaders) {
427
+ mergedHeaders.append('Set-Cookie', value);
428
+ }
429
+ actionResponse.headers.forEach((value, key) => {
430
+ if (key.toLowerCase() === 'set-cookie') {
431
+ mergedHeaders.append('Set-Cookie', value);
432
+ } else {
433
+ mergedHeaders.set(key, value);
434
+ }
435
+ });
436
+ return new Response(actionResponse.body, {
437
+ status: actionResponse.status,
438
+ statusText: actionResponse.statusText,
439
+ headers: mergedHeaders,
440
+ });
441
+ }
442
+ return actionResponse;
443
+ }
444
+ }
445
+
446
+ // ─── 4. Normal route dispatch ─────────────────────────────────────
447
+ return pipeline(req);
448
+ };
449
+ }
@@ -334,5 +334,5 @@ export async function generateSitemap(
334
334
  */
335
335
  export function hasUserSitemap(root: SegmentNode): boolean {
336
336
  if (!root.metadataRoutes) return false;
337
- return root.metadataRoutes.has('sitemap');
337
+ return 'sitemap' in root.metadataRoutes;
338
338
  }
@@ -352,7 +352,7 @@ interface SlotMatchResult {
352
352
  * to find the deepest matching page.
353
353
  */
354
354
  function findSlotMatch(slotNode: ManifestSegmentNode, match: RouteMatch): SlotMatchResult | null {
355
- const segments = match.segments as unknown as ManifestSegmentNode[];
355
+ const segments = match.segments;
356
356
 
357
357
  // Find the parent segment that owns this slot by comparing urlPaths.
358
358
  // The slot's urlPath matches its parent's urlPath (slots don't add URL depth).
@@ -37,7 +37,7 @@ import { SsrStreamError } from './primitives.js';
37
37
  import { createBufferedTransformStream, injectHead, injectRscPayload } from './html-injectors.js';
38
38
  import { wrapSsrElement } from './ssr-wrappers.js';
39
39
  import { withSpan } from './tracing.js';
40
- import { setCurrentParams } from '../client/use-params.js';
40
+ import { setCurrentParams } from '../client/use-segment-params.js';
41
41
  import { registerSsrDataProvider, type SsrData } from '../client/ssr-data.js';
42
42
 
43
43
  // Pre-import Node.js stream modules at module load time — not per-request.
@@ -14,6 +14,8 @@
14
14
  * See design/13-security.md §"State tree manipulation"
15
15
  */
16
16
 
17
+ import { swallow } from './logger.js';
18
+
17
19
  /**
18
20
  * Parse the X-Timber-State-Tree header from a request.
19
21
  *
@@ -33,7 +35,8 @@ export function parseClientStateTree(req: Request): Set<string> | null {
33
35
  return null;
34
36
  }
35
37
  return new Set(parsed.segments as string[]);
36
- } catch {
38
+ } catch (err) {
39
+ swallow(err, 'malformed X-Timber-State-Tree header');
37
40
  return null;
38
41
  }
39
42
  }