@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
@@ -1,19 +1,25 @@
1
1
  /**
2
- * Request Context — per-request ALS store for getHeaders() and getCookies().
2
+ * Request Context — per-request ALS store for headers, search params,
3
+ * segment params, and request scope lifecycle.
3
4
  *
4
5
  * Follows the same pattern as tracing.ts: a module-level AsyncLocalStorage
5
6
  * instance, public accessor functions that throw outside request scope,
6
7
  * and a framework-internal `runWithRequestContext()` to establish scope.
7
8
  *
9
+ * Cookie state lives in `cookie-context.ts` (split out in TIM-853). The
10
+ * scope set up here owns the cookie jar / parsedCookies fields on the
11
+ * store, but the cookie API and helpers are in the cookie module.
12
+ *
8
13
  * See design/04-authorization.md §"AccessContext does not include cookies or headers"
9
14
  * and design/11-platform.md §"AsyncLocalStorage".
10
- * See design/29-cookies.md for cookie mutation semantics.
11
15
  */
12
16
 
13
- import { requestContextAls, type RequestContextStore, type CookieEntry } from './als-registry.js';
14
- import { isDebug } from './debug.js';
17
+ import { requestContextAls, type RequestContextStore } from './als-registry.js';
15
18
  import { _setGetSearchParamsFn } from '../search-params/define.js';
16
19
  import { _setGetSegmentParamsFn } from '../segment-params/define.js';
20
+ import { consumeSeededCookies, getCookieJar } from './cookie-context.js';
21
+ import { _registerServerCookieImpl, _registerFromSchema } from '../cookies/define-cookie.js';
22
+ import { fromSchema } from '../schema-bridge.js';
17
23
 
18
24
  // Re-export the ALS for framework-internal consumers that need direct access.
19
25
  export { requestContextAls };
@@ -30,7 +36,7 @@ export { requestContextAls };
30
36
  * Available in middleware, access checks, server components, and server actions.
31
37
  * Throws if called outside a request context (security principle #2: no global fallback).
32
38
  */
33
- export function getHeaders(): Promise<ReadonlyHeaders> {
39
+ export function getHeaders(): ReadonlyHeaders {
34
40
  const store = requestContextAls.getStore();
35
41
  if (!store) {
36
42
  throw new Error(
@@ -38,199 +44,28 @@ export function getHeaders(): Promise<ReadonlyHeaders> {
38
44
  'It can only be used in middleware, access checks, server components, and server actions.'
39
45
  );
40
46
  }
41
- return Promise.resolve(store.headers);
47
+ return store.headers;
42
48
  }
43
49
 
44
50
  /**
45
51
  * Returns the value of a single request header, or undefined if absent.
46
52
  *
47
- * Thin wrapper over `(await getHeaders()).get(name)` for the common
48
- * case where you need exactly one header.
49
- *
50
- * ```ts
51
- * import { getHeader } from '@timber-js/app/server'
53
+ * Thin wrapper over `getHeaders().get(name)` for the common case where
54
+ * you need exactly one header.
52
55
  *
53
- * export default async function Page() {
54
- * const auth = await getHeader('authorization');
55
- * }
56
- * ```
56
+ * @internal not part of the public API. Use `getHeaders().get(name)` instead.
57
57
  */
58
- export async function getHeader(name: string): Promise<string | undefined> {
59
- const headers = await getHeaders();
58
+ export function getHeader(name: string): string | undefined {
59
+ const headers = getHeaders();
60
60
  return headers.get(name) ?? undefined;
61
61
  }
62
62
 
63
63
  /**
64
- * Returns a cookie accessor for the current request.
65
- *
66
- * Available in middleware, access checks, server components, and server actions.
67
- * Throws if called outside a request context (security principle #2: no global fallback).
68
- *
69
- * Read methods (.get, .has, .getAll) are always available and reflect
70
- * read-your-own-writes from .set() calls in the same request.
71
- *
72
- * Mutation methods (.set, .delete, .clear) are only available in mutable
73
- * contexts (middleware.ts, server actions, route.ts handlers). Calling them
74
- * in read-only contexts (access.ts, server components) throws.
75
- *
76
- * See design/29-cookies.md
77
- */
78
- export function getCookies(): Promise<RequestCookies> {
79
- const store = requestContextAls.getStore();
80
- if (!store) {
81
- throw new Error(
82
- '[timber] getCookies() called outside of a request context. ' +
83
- 'It can only be used in middleware, access checks, server components, and server actions.'
84
- );
85
- }
86
-
87
- // Parse cookies lazily on first access
88
- if (!store.parsedCookies) {
89
- store.parsedCookies = parseCookieHeader(store.cookieHeader);
90
- }
91
-
92
- const map = store.parsedCookies;
93
- return Promise.resolve({
94
- get(name: string): string | undefined {
95
- return map.get(name);
96
- },
97
- has(name: string): boolean {
98
- return map.has(name);
99
- },
100
- getAll(): Array<{ name: string; value: string }> {
101
- return Array.from(map.entries()).map(([name, value]) => ({ name, value }));
102
- },
103
- get size(): number {
104
- return map.size;
105
- },
106
-
107
- set(name: string, value: string, options?: CookieOptions): void {
108
- assertMutable(store, 'set');
109
- if (store.flushed) {
110
- if (isDebug()) {
111
- console.warn(
112
- `[timber] warn: getCookies().set('${name}') called after response headers were committed.\n` +
113
- ` The cookie will NOT be sent. Move cookie mutations to middleware.ts, a server action,\n` +
114
- ` or a route.ts handler.`
115
- );
116
- }
117
- return;
118
- }
119
- const opts = { ...DEFAULT_COOKIE_OPTIONS, ...options };
120
- store.cookieJar.set(name, { name, value, options: opts });
121
- // Read-your-own-writes: update the parsed cookies map
122
- map.set(name, value);
123
- },
124
-
125
- setFromHeaders(headers: Headers): void {
126
- assertMutable(store, 'setFromHeaders');
127
- if (store.flushed) {
128
- console.warn(
129
- `[timber] warn: getCookies().setFromHeaders() called after response headers were committed.\n` +
130
- ` The cookies will NOT be sent. Move cookie mutations to middleware.ts, a server action,\n` +
131
- ` or a route.ts handler.`
132
- );
133
- return;
134
- }
135
- // Headers.getSetCookie() returns individual Set-Cookie strings,
136
- // avoiding the fragile comma-splitting that raw .get() requires.
137
- for (const raw of headers.getSetCookie()) {
138
- const parsed = parseSetCookie(raw);
139
- if (parsed) {
140
- // Use setRaw to preserve the original header's attributes without
141
- // merging DEFAULT_COOKIE_OPTIONS (parseSetCookie intentionally
142
- // does not apply defaults — see its doc comment).
143
- setRaw(store, map, parsed.name, parsed.value, parsed.options);
144
- }
145
- }
146
- },
147
-
148
- delete(name: string, options?: Pick<CookieOptions, 'path' | 'domain'>): void {
149
- assertMutable(store, 'delete');
150
- if (store.flushed) {
151
- if (isDebug()) {
152
- console.warn(
153
- `[timber] warn: getCookies().delete('${name}') called after response headers were committed.\n` +
154
- ` The cookie will NOT be deleted. Move cookie mutations to middleware.ts, a server action,\n` +
155
- ` or a route.ts handler.`
156
- );
157
- }
158
- return;
159
- }
160
- const opts: CookieOptions = {
161
- ...DEFAULT_COOKIE_OPTIONS,
162
- ...options,
163
- maxAge: 0,
164
- expires: new Date(0),
165
- };
166
- store.cookieJar.set(name, { name, value: '', options: opts });
167
- // Remove from read view
168
- map.delete(name);
169
- },
170
-
171
- clear(): void {
172
- assertMutable(store, 'clear');
173
- if (store.flushed) return;
174
- // Delete every incoming cookie
175
- for (const name of Array.from(map.keys())) {
176
- store.cookieJar.set(name, {
177
- name,
178
- value: '',
179
- options: { ...DEFAULT_COOKIE_OPTIONS, maxAge: 0, expires: new Date(0) },
180
- });
181
- }
182
- map.clear();
183
- },
184
-
185
- toString(): string {
186
- return Array.from(map.entries())
187
- .map(([name, value]) => `${name}=${value}`)
188
- .join('; ');
189
- },
190
- });
191
- }
192
-
193
- /**
194
- * Returns the value of a single cookie, or undefined if absent.
195
- *
196
- * Thin wrapper over `(await getCookies()).get(name)` for the common
197
- * case where you need exactly one cookie.
198
- *
199
- * ```ts
200
- * import { getCookie } from '@timber-js/app/server'
201
- *
202
- * export default async function Page() {
203
- * const session = await getCookie('session_id');
204
- * }
205
- * ```
206
- */
207
- export async function getCookie(name: string): Promise<string | undefined> {
208
- const cookies = await getCookies();
209
- return cookies.get(name);
210
- }
211
-
212
- /**
213
- * Returns a Promise resolving to the current request's raw URLSearchParams.
214
- *
215
- * For typed, parsed search params, import the definition from params.ts
216
- * and call `.load()` or `.parse()`:
217
- *
218
- * ```ts
219
- * import { searchParams } from './params'
220
- * const parsed = await searchParams.get()
221
- * ```
222
- *
223
- * Or explicitly:
64
+ * Returns the current request's raw URLSearchParams.
224
65
  *
225
- * ```ts
226
- * import { getSearchParams } from '@timber-js/app/server'
227
- * import { searchParams } from './params'
228
- * const parsed = searchParams.parse(await getSearchParams())
229
- * ```
230
- *
231
- * Throws if called outside a request context.
66
+ * @internal — not part of the public API. Use `defineSearchParams().get()` instead.
232
67
  */
233
- export function getSearchParams(): Promise<URLSearchParams> {
68
+ export function getSearchParams(): URLSearchParams {
234
69
  const store = requestContextAls.getStore();
235
70
  if (!store) {
236
71
  throw new Error(
@@ -238,42 +73,31 @@ export function getSearchParams(): Promise<URLSearchParams> {
238
73
  'It can only be used in middleware, access checks, server components, and server actions.'
239
74
  );
240
75
  }
241
- return store.searchParamsPromise;
76
+ return store.searchParams;
242
77
  }
243
78
 
244
79
  // Eagerly register getSearchParams with the search-params module so
245
- // searchParams.get() can call it synchronously without a dynamic import.
80
+ // searchParams.get() can call it without a dynamic import.
246
81
  // Dynamic imports lose ALS context in React's RSC Flight renderer,
247
82
  // breaking getSearchParams() in parallel slot pages. See TIM-523.
248
83
  _setGetSearchParamsFn(getSearchParams);
249
84
 
250
85
  // Eagerly register getSegmentParams with the segment-params module so
251
- // segmentParams.get() can call it synchronously without a dynamic import.
86
+ // segmentParams.get() can call it without a dynamic import.
252
87
  // Same pattern as search params — dynamic imports lose ALS context. See TIM-523.
253
88
  _setGetSegmentParamsFn(getSegmentParams);
254
89
 
90
+ // Eagerly register the server cookie impl with defineCookie so
91
+ // .get()/.set()/.delete() are sync without dynamic imports.
92
+ _registerServerCookieImpl({ getCookieJar });
93
+ _registerFromSchema(fromSchema);
94
+
255
95
  /**
256
- * Returns a Promise resolving to the current request's coerced segment params.
257
- *
258
- * Segment params are set by the pipeline after route matching and param
259
- * coercion (via params.ts codecs). When no params.ts exists, values are
260
- * raw strings. When codecs are defined, values are already coerced
261
- * (e.g., `id` is a `number` if `defineSegmentParams({ id: z.coerce.number() })`).
262
- *
263
- * This is the primary way page and layout components access route params:
96
+ * Returns the current request's coerced segment params.
264
97
  *
265
- * ```ts
266
- * import { getSegmentParams } from '@timber-js/app/server'
267
- *
268
- * export default async function Page() {
269
- * const { slug } = await getSegmentParams()
270
- * // ...
271
- * }
272
- * ```
273
- *
274
- * Throws if called outside a request context.
98
+ * @internal — not part of the public API. Use `defineSegmentParams().get()` instead.
275
99
  */
276
- export function getSegmentParams(): Promise<Record<string, string | string[]>> {
100
+ export function getSegmentParams(): Record<string, string | string[]> {
277
101
  const store = requestContextAls.getStore();
278
102
  if (!store) {
279
103
  throw new Error(
@@ -281,13 +105,13 @@ export function getSegmentParams(): Promise<Record<string, string | string[]>> {
281
105
  'It can only be used in middleware, access checks, server components, and server actions.'
282
106
  );
283
107
  }
284
- if (!store.segmentParamsPromise) {
108
+ if (!store.segmentParams) {
285
109
  throw new Error(
286
110
  '[timber] getSegmentParams() called before route matching completed. ' +
287
111
  'Segment params are not available until after the route is matched.'
288
112
  );
289
113
  }
290
- return store.segmentParamsPromise;
114
+ return store.segmentParams;
291
115
  }
292
116
 
293
117
  /**
@@ -301,7 +125,7 @@ export function setSegmentParams(params: Record<string, string | string[]>): voi
301
125
  if (!store) {
302
126
  throw new Error('[timber] setSegmentParams() called outside of a request context.');
303
127
  }
304
- store.segmentParamsPromise = Promise.resolve(params);
128
+ store.segmentParams = params;
305
129
  }
306
130
 
307
131
  /**
@@ -330,169 +154,33 @@ export type ReadonlyHeaders = Pick<
330
154
  'get' | 'has' | 'entries' | 'keys' | 'values' | 'forEach' | typeof Symbol.iterator
331
155
  >;
332
156
 
333
- /** Options for setting a cookie. See design/29-cookies.md. */
334
- export interface CookieOptions {
335
- /** Domain scope. Default: omitted (current domain only). */
336
- domain?: string;
337
- /** URL path scope. Default: '/'. */
338
- path?: string;
339
- /** Expiration date. Mutually exclusive with maxAge. */
340
- expires?: Date;
341
- /** Max age in seconds. Mutually exclusive with expires. */
342
- maxAge?: number;
343
- /** Prevent client-side JS access. Default: true. */
344
- httpOnly?: boolean;
345
- /** Only send over HTTPS. Default: true. */
346
- secure?: boolean;
347
- /** Cross-site request policy. Default: 'lax'. */
348
- sameSite?: 'strict' | 'lax' | 'none';
349
- /** Partitioned (CHIPS) — isolate cookie per top-level site. Default: false. */
350
- partitioned?: boolean;
351
- }
352
-
353
- const DEFAULT_COOKIE_OPTIONS: CookieOptions = {
354
- path: '/',
355
- httpOnly: true,
356
- secure: true,
357
- sameSite: 'lax',
358
- };
359
-
360
- /**
361
- * Write a cookie to the jar WITHOUT merging DEFAULT_COOKIE_OPTIONS.
362
- * Used by setFromHeaders to preserve the original header's attributes exactly.
363
- *
364
- * For deletion cookies (maxAge=0), the jar entry is still created so the
365
- * Set-Cookie header is emitted, but the cookie is NOT added to the read map
366
- * (it would be misleading — the cookie is being deleted).
367
- */
368
- function setRaw(
369
- store: RequestContextStore,
370
- readMap: Map<string, string>,
371
- name: string,
372
- value: string,
373
- options: CookieOptions
374
- ): void {
375
- store.cookieJar.set(name, { name, value, options });
376
- // Deletion cookies (Max-Age=0) should not appear in the read map
377
- if (options.maxAge === 0) {
378
- readMap.delete(name);
379
- } else {
380
- readMap.set(name, value);
381
- }
382
- }
383
-
384
- /**
385
- * Parse a raw `Set-Cookie` header string into name, value, and options.
386
- * Handles all standard attributes: Path, Domain, Max-Age, Expires,
387
- * SameSite, Secure, HttpOnly, Partitioned.
388
- *
389
- * Does NOT apply DEFAULT_COOKIE_OPTIONS — the caller decides whether
390
- * to merge defaults (e.g. `set()` does, but `setRaw()` should preserve
391
- * the original header's intent).
392
- */
393
- function parseSetCookie(
394
- header: string
395
- ): { name: string; value: string; options: CookieOptions } | null {
396
- const segments = header.split(';');
397
- const nameValue = segments[0];
398
- const eqIdx = nameValue.indexOf('=');
399
- if (eqIdx <= 0) return null;
400
-
401
- const name = nameValue.slice(0, eqIdx).trim();
402
- const value = nameValue.slice(eqIdx + 1).trim();
403
- const options: CookieOptions = {};
404
-
405
- for (let i = 1; i < segments.length; i++) {
406
- const seg = segments[i].trim();
407
- if (!seg) continue;
408
- const [attrName, ...rest] = seg.split('=');
409
- const key = attrName.trim().toLowerCase();
410
- const val = rest.join('=').trim();
411
- switch (key) {
412
- case 'path':
413
- options.path = val || '/';
414
- break;
415
- case 'domain':
416
- options.domain = val;
417
- break;
418
- case 'max-age':
419
- options.maxAge = Number(val);
420
- break;
421
- case 'expires':
422
- options.expires = new Date(val);
423
- break;
424
- case 'samesite':
425
- options.sameSite = val.toLowerCase() as 'strict' | 'lax' | 'none';
426
- break;
427
- case 'secure':
428
- options.secure = true;
429
- break;
430
- case 'httponly':
431
- options.httpOnly = true;
432
- break;
433
- case 'partitioned':
434
- options.partitioned = true;
435
- break;
436
- }
437
- }
438
-
439
- return { name, value, options };
440
- }
441
-
442
- /**
443
- * Cookie accessor returned by `getCookies()`.
444
- *
445
- * Read methods are always available. Mutation methods throw in read-only
446
- * contexts (access.ts, server components).
447
- */
448
- export interface RequestCookies {
449
- /** Get a cookie value by name. Returns undefined if not present. */
450
- get(name: string): string | undefined;
451
- /** Check if a cookie exists. */
452
- has(name: string): boolean;
453
- /** Get all cookies as an array of { name, value } pairs. */
454
- getAll(): Array<{ name: string; value: string }>;
455
- /** Number of cookies. */
456
- readonly size: number;
457
- /** Set a cookie. Only available in mutable contexts (middleware, actions, route handlers). */
458
- set(name: string, value: string, options?: CookieOptions): void;
459
- /**
460
- * Copy all `Set-Cookie` headers from a `Headers` object.
461
- * Parses each header and forwards name, value, and all attributes
462
- * (path, domain, max-age, expires, sameSite, secure, httpOnly, partitioned).
463
- *
464
- * Useful when forwarding cookies from an internal `fetch()` or auth handler:
465
- * ```ts
466
- * const response = await auth.handler(req);
467
- * getCookies().then(c => c.setFromHeaders(response.headers));
468
- * ```
469
- */
470
- setFromHeaders(headers: Headers): void;
471
- /** Delete a cookie. Only available in mutable contexts. */
472
- delete(name: string, options?: Pick<CookieOptions, 'path' | 'domain'>): void;
473
- /** Delete all cookies. Only available in mutable contexts. */
474
- clear(): void;
475
- /** Serialize cookies as a Cookie header string. */
476
- toString(): string;
477
- }
478
-
479
157
  // ─── Framework-Internal Helpers ───────────────────────────────────────────
480
158
 
481
159
  /**
482
160
  * Run a callback within a request context. Used by the pipeline to establish
483
161
  * per-request ALS scope so that `getHeaders()` and `getCookies()` work.
484
162
  *
163
+ * If the request was previously registered via `seedRequestCookies`, the
164
+ * resulting context's `parsedCookies` map is initialized from the seed and
165
+ * the raw `cookieHeader` is left empty — `parseCookieHeader` is never called
166
+ * for that request. This is the no-JS form-rerender path. See TIM-868.
167
+ *
485
168
  * @param req - The incoming Request object.
486
169
  * @param fn - The function to run within the request context.
487
170
  */
488
171
  export function runWithRequestContext<T>(req: Request, fn: () => T): T {
489
172
  const originalCopy = new Headers(req.headers);
490
173
  const parsedUrl = new URL(req.url);
174
+ const seed = consumeSeededCookies(req);
491
175
  const store: RequestContextStore = {
492
176
  headers: freezeHeaders(req.headers),
493
177
  originalHeaders: originalCopy,
494
- cookieHeader: req.headers.get('cookie') ?? '',
495
- searchParamsPromise: Promise.resolve(parsedUrl.searchParams),
178
+ // When seeded, leave the raw header empty — parseCookieHeader is the
179
+ // exact code path the smuggling primitive abused, and lazy parsing is
180
+ // gated on `parsedCookies` being undefined.
181
+ cookieHeader: seed ? '' : (req.headers.get('cookie') ?? ''),
182
+ parsedCookies: seed,
183
+ searchParams: parsedUrl.searchParams,
496
184
  searchString: parsedUrl.search,
497
185
  cookieJar: new Map(),
498
186
  flushed: false,
@@ -527,47 +215,6 @@ export function markResponseFlushed(): void {
527
215
  }
528
216
  }
529
217
 
530
- /**
531
- * Build a Map of cookie name → value reflecting the current request's
532
- * read-your-own-writes state. Includes incoming cookies plus any
533
- * mutations from getCookies().set() / getCookies().delete() in the same request.
534
- *
535
- * Used by SSR renderers to populate NavContext.cookies so that
536
- * useCookie()'s server snapshot matches the actual response state.
537
- *
538
- * See design/29-cookies.md §"Read-Your-Own-Writes"
539
- * See design/triage/TIM-441-cookie-api-triage.md §4
540
- */
541
- export function getCookiesForSsr(): Map<string, string> {
542
- const store = requestContextAls.getStore();
543
- if (!store) {
544
- throw new Error('[timber] getCookiesForSsr() called outside of a request context.');
545
- }
546
-
547
- // Trigger lazy parsing if not yet done
548
- if (!store.parsedCookies) {
549
- store.parsedCookies = parseCookieHeader(store.cookieHeader);
550
- }
551
-
552
- // The parsedCookies map already reflects read-your-own-writes:
553
- // - getCookies().set() updates the map via map.set(name, value)
554
- // - getCookies().delete() removes from the map via map.delete(name)
555
- // Return a copy so callers can't mutate the internal map.
556
- return new Map(store.parsedCookies);
557
- }
558
-
559
- /**
560
- * Collect all Set-Cookie headers from the cookie jar.
561
- * Called by the framework at flush time to apply cookies to the response.
562
- *
563
- * Returns an array of serialized Set-Cookie header values.
564
- */
565
- export function getSetCookieHeaders(): string[] {
566
- const store = requestContextAls.getStore();
567
- if (!store) return [];
568
- return Array.from(store.cookieJar.values()).map(serializeCookieEntry);
569
- }
570
-
571
218
  /**
572
219
  * Apply middleware-injected request headers to the current request context.
573
220
  *
@@ -635,55 +282,3 @@ function freezeHeaders(source: Headers): Headers {
635
282
  },
636
283
  });
637
284
  }
638
-
639
- // ─── Cookie Helpers ───────────────────────────────────────────────────────
640
-
641
- /** Throw if cookie mutation is attempted in a read-only context. */
642
- function assertMutable(store: RequestContextStore, method: string): void {
643
- if (!store.mutableContext) {
644
- throw new Error(
645
- `(timber] getCookies().${method}() cannot be called in this context.\n` +
646
- ` Set cookies in middleware.ts, server actions, or route.ts handlers.`
647
- );
648
- }
649
- }
650
-
651
- /**
652
- * Parse a Cookie header string into a Map of name → value pairs.
653
- * Follows RFC 6265 §4.2.1: cookies are semicolon-separated key=value pairs.
654
- */
655
- function parseCookieHeader(header: string): Map<string, string> {
656
- const map = new Map<string, string>();
657
- if (!header) return map;
658
-
659
- for (const pair of header.split(';')) {
660
- const eqIndex = pair.indexOf('=');
661
- if (eqIndex === -1) continue;
662
- const name = pair.slice(0, eqIndex).trim();
663
- const value = pair.slice(eqIndex + 1).trim();
664
- if (name) {
665
- map.set(name, value);
666
- }
667
- }
668
-
669
- return map;
670
- }
671
-
672
- /** Serialize a CookieEntry into a Set-Cookie header value. */
673
- function serializeCookieEntry(entry: CookieEntry): string {
674
- const parts = [`${entry.name}=${entry.value}`];
675
- const opts = entry.options;
676
-
677
- if (opts.domain) parts.push(`Domain=${opts.domain}`);
678
- if (opts.path) parts.push(`Path=${opts.path}`);
679
- if (opts.expires) parts.push(`Expires=${opts.expires.toUTCString()}`);
680
- if (opts.maxAge !== undefined) parts.push(`Max-Age=${opts.maxAge}`);
681
- if (opts.httpOnly) parts.push('HttpOnly');
682
- if (opts.secure) parts.push('Secure');
683
- if (opts.sameSite) {
684
- parts.push(`SameSite=${opts.sameSite.charAt(0).toUpperCase()}${opts.sameSite.slice(1)}`);
685
- }
686
- if (opts.partitioned) parts.push('Partitioned');
687
-
688
- return parts.join('; ');
689
- }
@@ -27,9 +27,13 @@ import type { Metadata } from './types.js';
27
27
  import { METADATA_ROUTE_CONVENTIONS, getMetadataRouteAutoLink } from './metadata-routes.js';
28
28
  import { DenySignal, RedirectSignal } from './primitives.js';
29
29
  import { AccessGate } from './access-gate.js';
30
- import { PageDenyBoundary } from './page-deny-boundary.js';
31
- import { buildDenyPageChain, renderMatchingDenyPage, setDenyStatus } from './deny-page-resolver.js';
32
- import type { DenyPageEntry } from './deny-page-resolver.js';
30
+ import {
31
+ PageDenyBoundary,
32
+ buildDenyPageChain,
33
+ renderMatchingDenyPage,
34
+ setDenyStatus,
35
+ } from './deny-boundary.js';
36
+ import type { DenyPageEntry } from './deny-boundary.js';
33
37
  import { resolveSlotElement } from './slot-resolver.js';
34
38
  import { SegmentProvider } from '../client/segment-context.js';
35
39
 
@@ -213,7 +217,7 @@ export async function buildRouteElement(
213
217
  interception?: InterceptionContext,
214
218
  clientStateTree?: Set<string> | null
215
219
  ): Promise<RouteElementResult> {
216
- const segments = match.segments as unknown as ManifestSegmentNode[];
220
+ const segments = match.segments;
217
221
 
218
222
  // Load all modules along the segment chain
219
223
  const metadataEntries: Array<{ metadata: Metadata; isPage: boolean }> = [];