@timber-js/app 0.2.0-alpha.16 → 0.2.0-alpha.160

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 (985) hide show
  1. package/LICENSE +8 -0
  2. package/agent-skill.md +344 -0
  3. package/dist/_chunks/actions-C9yAuoX3.js +314 -0
  4. package/dist/_chunks/actions-C9yAuoX3.js.map +1 -0
  5. package/dist/_chunks/build-output-helper-DF5uScqS.js +158 -0
  6. package/dist/_chunks/build-output-helper-DF5uScqS.js.map +1 -0
  7. package/dist/_chunks/cache-api-swbefQ6F.js +1125 -0
  8. package/dist/_chunks/cache-api-swbefQ6F.js.map +1 -0
  9. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → canonicalize-P41GR6tY.js} +94 -18
  10. package/dist/_chunks/canonicalize-P41GR6tY.js.map +1 -0
  11. package/dist/_chunks/cli-schema-sync-BhYDz_-x.js +638 -0
  12. package/dist/_chunks/cli-schema-sync-BhYDz_-x.js.map +1 -0
  13. package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
  14. package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
  15. package/dist/_chunks/define-Bssfp6ot.js +82 -0
  16. package/dist/_chunks/define-Bssfp6ot.js.map +1 -0
  17. package/dist/_chunks/define-CFmvb4Bt.js +203 -0
  18. package/dist/_chunks/define-CFmvb4Bt.js.map +1 -0
  19. package/dist/_chunks/dist-BA3u1z3W.js +423 -0
  20. package/dist/_chunks/dist-BA3u1z3W.js.map +1 -0
  21. package/dist/_chunks/fast-hash-D6hIVt1Y.js +36 -0
  22. package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +1 -0
  23. package/dist/_chunks/format-CfwjgPz9.js +14 -0
  24. package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
  25. package/dist/_chunks/href-validation-CMc5JRls.js +141 -0
  26. package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -0
  27. package/dist/_chunks/logger-CPoQkGK6.js +1523 -0
  28. package/dist/_chunks/logger-CPoQkGK6.js.map +1 -0
  29. package/dist/_chunks/navigation-root-bUDZLw74.js +124 -0
  30. package/dist/_chunks/navigation-root-bUDZLw74.js.map +1 -0
  31. package/dist/_chunks/plugin-context-DeAxFRMq.js +280 -0
  32. package/dist/_chunks/plugin-context-DeAxFRMq.js.map +1 -0
  33. package/dist/_chunks/registry-DbJPKoBp.js +20 -0
  34. package/dist/_chunks/registry-DbJPKoBp.js.map +1 -0
  35. package/dist/_chunks/resolve-schema-3iUvBV5T.js +50 -0
  36. package/dist/_chunks/resolve-schema-3iUvBV5T.js.map +1 -0
  37. package/dist/_chunks/router-ref-CtmF-aPv.js +28 -0
  38. package/dist/_chunks/router-ref-CtmF-aPv.js.map +1 -0
  39. package/dist/_chunks/schema-bridge-BY3QLBL7.js +119 -0
  40. package/dist/_chunks/schema-bridge-BY3QLBL7.js.map +1 -0
  41. package/dist/_chunks/segment-classify-CDDRVKs7.js +137 -0
  42. package/dist/_chunks/segment-classify-CDDRVKs7.js.map +1 -0
  43. package/dist/_chunks/segment-context-ZDnXDkbz.js +34 -0
  44. package/dist/_chunks/segment-context-ZDnXDkbz.js.map +1 -0
  45. package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
  46. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
  47. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-BOWsq18U.js} +1 -1
  48. package/dist/_chunks/ssr-data-BOWsq18U.js.map +1 -0
  49. package/dist/_chunks/tree-match-D2l830j2.js +102 -0
  50. package/dist/_chunks/tree-match-D2l830j2.js.map +1 -0
  51. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-CbeQmext.js} +7 -20
  52. package/dist/_chunks/use-query-states-CbeQmext.js.map +1 -0
  53. package/dist/_chunks/use-segment-params-D1CzlgBo.js +151 -0
  54. package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +1 -0
  55. package/dist/_chunks/walkers-c8aReVgo.js +988 -0
  56. package/dist/_chunks/walkers-c8aReVgo.js.map +1 -0
  57. package/dist/adapters/build-output-helper.d.ts +29 -0
  58. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  59. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  60. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  61. package/dist/adapters/cloudflare-dev.js +73 -0
  62. package/dist/adapters/cloudflare-dev.js.map +1 -0
  63. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  64. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  65. package/dist/adapters/cloudflare-kv-cache.js +117 -0
  66. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  67. package/dist/adapters/cloudflare.d.ts +177 -20
  68. package/dist/adapters/cloudflare.d.ts.map +1 -1
  69. package/dist/adapters/cloudflare.js +342 -67
  70. package/dist/adapters/cloudflare.js.map +1 -1
  71. package/dist/adapters/compress-module.d.ts +5 -4
  72. package/dist/adapters/compress-module.d.ts.map +1 -1
  73. package/dist/adapters/nitro.d.ts +1 -3
  74. package/dist/adapters/nitro.d.ts.map +1 -1
  75. package/dist/adapters/nitro.js +143 -144
  76. package/dist/adapters/nitro.js.map +1 -1
  77. package/dist/adapters/shared.d.ts +6 -0
  78. package/dist/adapters/shared.d.ts.map +1 -0
  79. package/dist/cache/cache-api.d.ts +26 -0
  80. package/dist/cache/cache-api.d.ts.map +1 -0
  81. package/dist/cache/handler-store.d.ts +33 -0
  82. package/dist/cache/handler-store.d.ts.map +1 -0
  83. package/dist/cache/index.d.ts +27 -7
  84. package/dist/cache/index.d.ts.map +1 -1
  85. package/dist/cache/index.js +3 -326
  86. package/dist/cache/invalidation-epoch.d.ts +43 -0
  87. package/dist/cache/invalidation-epoch.d.ts.map +1 -0
  88. package/dist/cache/redis-handler.d.ts +97 -8
  89. package/dist/cache/redis-handler.d.ts.map +1 -1
  90. package/dist/cache/singleflight.d.ts +19 -2
  91. package/dist/cache/singleflight.d.ts.map +1 -1
  92. package/dist/cache/sizeof.d.ts +22 -0
  93. package/dist/cache/sizeof.d.ts.map +1 -0
  94. package/dist/cache/stable-stringify.d.ts +9 -0
  95. package/dist/cache/stable-stringify.d.ts.map +1 -1
  96. package/dist/cache/store.d.ts +53 -0
  97. package/dist/cache/store.d.ts.map +1 -0
  98. package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
  99. package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
  100. package/dist/cache/stores/cloudflare-kv.js +29 -0
  101. package/dist/cache/stores/cloudflare-kv.js.map +1 -0
  102. package/dist/cache/stores/memory.d.ts +42 -0
  103. package/dist/cache/stores/memory.d.ts.map +1 -0
  104. package/dist/cache/stores/memory.js +90 -0
  105. package/dist/cache/stores/memory.js.map +1 -0
  106. package/dist/cache/stores/redis.d.ts +69 -0
  107. package/dist/cache/stores/redis.d.ts.map +1 -0
  108. package/dist/cache/stores/redis.js +35 -0
  109. package/dist/cache/stores/redis.js.map +1 -0
  110. package/dist/cache/stores/vercel.d.ts +36 -0
  111. package/dist/cache/stores/vercel.d.ts.map +1 -0
  112. package/dist/cache/stores/vercel.js +33 -0
  113. package/dist/cache/stores/vercel.js.map +1 -0
  114. package/dist/cache/tag-aware-handler.d.ts +51 -0
  115. package/dist/cache/tag-aware-handler.d.ts.map +1 -0
  116. package/dist/cache/timber-cache.d.ts +20 -10
  117. package/dist/cache/timber-cache.d.ts.map +1 -1
  118. package/dist/cdn/cloudflare-purge.d.ts +23 -0
  119. package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
  120. package/dist/cdn/fastly-purge.d.ts +25 -0
  121. package/dist/cdn/fastly-purge.d.ts.map +1 -0
  122. package/dist/cdn/headers.d.ts +97 -0
  123. package/dist/cdn/headers.d.ts.map +1 -0
  124. package/dist/cdn/index.d.ts +5 -0
  125. package/dist/cdn/index.d.ts.map +1 -0
  126. package/dist/cdn/purge-store.d.ts +23 -0
  127. package/dist/cdn/purge-store.d.ts.map +1 -0
  128. package/dist/cdn/workers-cache-purge.d.ts +16 -0
  129. package/dist/cdn/workers-cache-purge.d.ts.map +1 -0
  130. package/dist/cli-schema-sync.d.ts +59 -0
  131. package/dist/cli-schema-sync.d.ts.map +1 -0
  132. package/dist/cli.d.ts +34 -2
  133. package/dist/cli.d.ts.map +1 -1
  134. package/dist/cli.js +107 -33
  135. package/dist/cli.js.map +1 -1
  136. package/dist/client/browser-dev.d.ts +37 -1
  137. package/dist/client/browser-dev.d.ts.map +1 -1
  138. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  139. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  140. package/dist/client/browser-entry/hmr.d.ts +21 -0
  141. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  142. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  143. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  144. package/dist/client/browser-entry/index.d.ts +29 -0
  145. package/dist/client/browser-entry/index.d.ts.map +1 -0
  146. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  147. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  148. package/dist/client/browser-entry/router-init.d.ts +26 -0
  149. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  150. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  151. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  152. package/dist/client/browser-entry/scroll.d.ts +28 -0
  153. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  154. package/dist/client/error-boundary.d.ts +12 -5
  155. package/dist/client/error-boundary.d.ts.map +1 -1
  156. package/dist/client/error-boundary.js +47 -10
  157. package/dist/client/error-boundary.js.map +1 -1
  158. package/dist/client/error-reconstituter.d.ts +61 -0
  159. package/dist/client/error-reconstituter.d.ts.map +1 -0
  160. package/dist/client/form.d.ts +16 -27
  161. package/dist/client/form.d.ts.map +1 -1
  162. package/dist/client/history.d.ts +11 -6
  163. package/dist/client/history.d.ts.map +1 -1
  164. package/dist/client/index.d.ts +10 -24
  165. package/dist/client/index.d.ts.map +1 -1
  166. package/dist/client/index.js +182 -1134
  167. package/dist/client/index.js.map +1 -1
  168. package/dist/client/internal.d.ts +19 -0
  169. package/dist/client/internal.d.ts.map +1 -0
  170. package/dist/client/internal.js +825 -0
  171. package/dist/client/internal.js.map +1 -0
  172. package/dist/client/link.d.ts +69 -60
  173. package/dist/client/link.d.ts.map +1 -1
  174. package/dist/client/navigation-api.d.ts +120 -0
  175. package/dist/client/navigation-api.d.ts.map +1 -0
  176. package/dist/client/navigation-context.d.ts +3 -2
  177. package/dist/client/navigation-context.d.ts.map +1 -1
  178. package/dist/client/navigation-root.d.ts +119 -0
  179. package/dist/client/navigation-root.d.ts.map +1 -0
  180. package/dist/client/nuqs-adapter.d.ts +1 -1
  181. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  182. package/dist/client/router-ref.d.ts +1 -1
  183. package/dist/client/router.d.ts +87 -14
  184. package/dist/client/router.d.ts.map +1 -1
  185. package/dist/client/rsc-fetch.d.ts +47 -14
  186. package/dist/client/rsc-fetch.d.ts.map +1 -1
  187. package/dist/client/segment-cache.d.ts +4 -4
  188. package/dist/client/segment-cache.d.ts.map +1 -1
  189. package/dist/client/segment-outlet.d.ts +49 -0
  190. package/dist/client/segment-outlet.d.ts.map +1 -0
  191. package/dist/client/segment-update-context.d.ts +21 -0
  192. package/dist/client/segment-update-context.d.ts.map +1 -0
  193. package/dist/client/shallow-url.d.ts +10 -0
  194. package/dist/client/shallow-url.d.ts.map +1 -0
  195. package/dist/client/ssr-data.d.ts +13 -4
  196. package/dist/client/ssr-data.d.ts.map +1 -1
  197. package/dist/client/state.d.ts +1 -1
  198. package/dist/client/top-loader.d.ts +5 -5
  199. package/dist/client/top-loader.d.ts.map +1 -1
  200. package/dist/client/use-cookie.d.ts +12 -0
  201. package/dist/client/use-cookie.d.ts.map +1 -1
  202. package/dist/client/use-link-status.d.ts +5 -5
  203. package/dist/client/use-link-status.d.ts.map +1 -1
  204. package/dist/client/use-pathname.d.ts.map +1 -1
  205. package/dist/client/use-pending-navigation.d.ts +23 -0
  206. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  207. package/dist/client/use-query-states.d.ts +1 -1
  208. package/dist/client/use-query-states.d.ts.map +1 -1
  209. package/dist/client/use-router.d.ts +1 -1
  210. package/dist/client/use-router.d.ts.map +1 -1
  211. package/dist/client/use-search-params.d.ts +12 -5
  212. package/dist/client/use-search-params.d.ts.map +1 -1
  213. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +8 -6
  214. package/dist/client/use-segment-params.d.ts.map +1 -0
  215. package/dist/codec.d.ts +69 -0
  216. package/dist/codec.d.ts.map +1 -0
  217. package/dist/codec.js +75 -0
  218. package/dist/codec.js.map +1 -0
  219. package/dist/config-types.d.ts +304 -0
  220. package/dist/config-types.d.ts.map +1 -0
  221. package/dist/config-validation.d.ts +51 -0
  222. package/dist/config-validation.d.ts.map +1 -0
  223. package/dist/content/index.d.ts +1 -10
  224. package/dist/content/index.d.ts.map +1 -1
  225. package/dist/content/index.js +0 -2
  226. package/dist/cookies/define-cookie.d.ts +58 -25
  227. package/dist/cookies/define-cookie.d.ts.map +1 -1
  228. package/dist/cookies/index.d.ts +2 -1
  229. package/dist/cookies/index.d.ts.map +1 -1
  230. package/dist/cookies/index.js +253 -36
  231. package/dist/cookies/index.js.map +1 -1
  232. package/dist/cookies/json-cookie.d.ts +64 -0
  233. package/dist/cookies/json-cookie.d.ts.map +1 -0
  234. package/dist/cookies/validation.d.ts +34 -0
  235. package/dist/cookies/validation.d.ts.map +1 -0
  236. package/dist/dev-tools/404-page.d.ts +50 -0
  237. package/dist/dev-tools/404-page.d.ts.map +1 -0
  238. package/dist/dev-tools/browser-logs.d.ts +40 -0
  239. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  240. package/dist/dev-tools/dev-page-shell.d.ts +78 -0
  241. package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
  242. package/dist/dev-tools/error-page.d.ts +32 -0
  243. package/dist/dev-tools/error-page.d.ts.map +1 -0
  244. package/dist/dev-tools/holding-server.d.ts +54 -0
  245. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  246. package/dist/dev-tools/hydration-overlay.d.ts +11 -0
  247. package/dist/dev-tools/hydration-overlay.d.ts.map +1 -0
  248. package/dist/dev-tools/index.d.ts +31 -0
  249. package/dist/dev-tools/index.d.ts.map +1 -0
  250. package/dist/dev-tools/instrumentation.d.ts +59 -0
  251. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  252. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  253. package/dist/dev-tools/logger.d.ts.map +1 -0
  254. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
  255. package/dist/dev-tools/logs.d.ts.map +1 -0
  256. package/dist/dev-tools/overlay.d.ts +91 -0
  257. package/dist/dev-tools/overlay.d.ts.map +1 -0
  258. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  259. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  260. package/dist/dev-tools/terminal.d.ts +28 -0
  261. package/dist/dev-tools/terminal.d.ts.map +1 -0
  262. package/dist/fonts/ast-walk.d.ts +68 -0
  263. package/dist/fonts/ast-walk.d.ts.map +1 -0
  264. package/dist/fonts/ast.d.ts +110 -6
  265. package/dist/fonts/ast.d.ts.map +1 -1
  266. package/dist/fonts/bundle.d.ts +50 -0
  267. package/dist/fonts/bundle.d.ts.map +1 -0
  268. package/dist/fonts/dev-middleware.d.ts +22 -0
  269. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  270. package/dist/fonts/fallbacks.d.ts +0 -7
  271. package/dist/fonts/fallbacks.d.ts.map +1 -1
  272. package/dist/fonts/google.d.ts +4 -2
  273. package/dist/fonts/google.d.ts.map +1 -1
  274. package/dist/fonts/local.d.ts +4 -4
  275. package/dist/fonts/local.d.ts.map +1 -1
  276. package/dist/fonts/paths.d.ts +43 -0
  277. package/dist/fonts/paths.d.ts.map +1 -0
  278. package/dist/fonts/pipeline.d.ts +158 -0
  279. package/dist/fonts/pipeline.d.ts.map +1 -0
  280. package/dist/fonts/transform.d.ts +82 -0
  281. package/dist/fonts/transform.d.ts.map +1 -0
  282. package/dist/fonts/types.d.ts +47 -1
  283. package/dist/fonts/types.d.ts.map +1 -1
  284. package/dist/fonts/virtual-modules.d.ts +77 -0
  285. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  286. package/dist/index.d.ts +46 -180
  287. package/dist/index.d.ts.map +1 -1
  288. package/dist/index.js +7807 -13691
  289. package/dist/index.js.map +1 -1
  290. package/dist/params/codec-registry.d.ts +26 -0
  291. package/dist/params/codec-registry.d.ts.map +1 -0
  292. package/dist/params/define-schema.d.ts +81 -0
  293. package/dist/params/define-schema.d.ts.map +1 -0
  294. package/dist/params/index.d.ts +5 -0
  295. package/dist/params/index.d.ts.map +1 -0
  296. package/dist/params/index.js +34 -0
  297. package/dist/params/index.js.map +1 -0
  298. package/dist/params/resolve-schema.d.ts +34 -0
  299. package/dist/params/resolve-schema.d.ts.map +1 -0
  300. package/dist/plugin-context.d.ts +190 -0
  301. package/dist/plugin-context.d.ts.map +1 -0
  302. package/dist/plugins/adapter-build.d.ts +20 -1
  303. package/dist/plugins/adapter-build.d.ts.map +1 -1
  304. package/dist/plugins/build-manifest.d.ts +7 -3
  305. package/dist/plugins/build-manifest.d.ts.map +1 -1
  306. package/dist/plugins/build-report.d.ts +43 -7
  307. package/dist/plugins/build-report.d.ts.map +1 -1
  308. package/dist/plugins/cache.d.ts +64 -0
  309. package/dist/plugins/cache.d.ts.map +1 -0
  310. package/dist/plugins/callsite-ast.d.ts +95 -0
  311. package/dist/plugins/callsite-ast.d.ts.map +1 -0
  312. package/dist/plugins/callsite-jsx.d.ts +35 -0
  313. package/dist/plugins/callsite-jsx.d.ts.map +1 -0
  314. package/dist/plugins/chunks.d.ts +11 -4
  315. package/dist/plugins/chunks.d.ts.map +1 -1
  316. package/dist/plugins/client-chunks.d.ts +40 -0
  317. package/dist/plugins/client-chunks.d.ts.map +1 -0
  318. package/dist/plugins/cloudflare-wasm.d.ts +21 -0
  319. package/dist/plugins/cloudflare-wasm.d.ts.map +1 -0
  320. package/dist/plugins/content.d.ts +1 -1
  321. package/dist/plugins/content.d.ts.map +1 -1
  322. package/dist/plugins/dev-server.d.ts +17 -1
  323. package/dist/plugins/dev-server.d.ts.map +1 -1
  324. package/dist/plugins/entries.d.ts +1 -1
  325. package/dist/plugins/entries.d.ts.map +1 -1
  326. package/dist/plugins/fonts.d.ts +16 -73
  327. package/dist/plugins/fonts.d.ts.map +1 -1
  328. package/dist/plugins/mdx.d.ts +1 -1
  329. package/dist/plugins/mdx.d.ts.map +1 -1
  330. package/dist/plugins/prebuilt-capture.d.ts +60 -0
  331. package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
  332. package/dist/plugins/prebuilt.d.ts +82 -0
  333. package/dist/plugins/prebuilt.d.ts.map +1 -0
  334. package/dist/plugins/prerender-sugar.d.ts +42 -0
  335. package/dist/plugins/prerender-sugar.d.ts.map +1 -0
  336. package/dist/plugins/routing.d.ts +1 -1
  337. package/dist/plugins/routing.d.ts.map +1 -1
  338. package/dist/plugins/server-bundle.d.ts.map +1 -1
  339. package/dist/plugins/shims.d.ts +29 -5
  340. package/dist/plugins/shims.d.ts.map +1 -1
  341. package/dist/plugins/static-build.d.ts +5 -26
  342. package/dist/plugins/static-build.d.ts.map +1 -1
  343. package/dist/routing/codegen-shared.d.ts +67 -0
  344. package/dist/routing/codegen-shared.d.ts.map +1 -0
  345. package/dist/routing/codegen-types.d.ts +64 -0
  346. package/dist/routing/codegen-types.d.ts.map +1 -0
  347. package/dist/routing/codegen.d.ts +7 -2
  348. package/dist/routing/codegen.d.ts.map +1 -1
  349. package/dist/routing/convention-lint.d.ts +41 -0
  350. package/dist/routing/convention-lint.d.ts.map +1 -0
  351. package/dist/routing/export-detect.d.ts +56 -0
  352. package/dist/routing/export-detect.d.ts.map +1 -0
  353. package/dist/routing/file-cache.d.ts +8 -0
  354. package/dist/routing/file-cache.d.ts.map +1 -0
  355. package/dist/routing/index.d.ts +7 -1
  356. package/dist/routing/index.d.ts.map +1 -1
  357. package/dist/routing/index.js +4 -2
  358. package/dist/routing/interception.d.ts +0 -5
  359. package/dist/routing/interception.d.ts.map +1 -1
  360. package/dist/routing/link-codegen.d.ts +90 -0
  361. package/dist/routing/link-codegen.d.ts.map +1 -0
  362. package/dist/routing/manifest-codegen.d.ts +32 -0
  363. package/dist/routing/manifest-codegen.d.ts.map +1 -0
  364. package/dist/routing/scanner.d.ts +1 -10
  365. package/dist/routing/scanner.d.ts.map +1 -1
  366. package/dist/routing/schema-validation.d.ts +35 -0
  367. package/dist/routing/schema-validation.d.ts.map +1 -0
  368. package/dist/routing/segment-classify.d.ts +75 -0
  369. package/dist/routing/segment-classify.d.ts.map +1 -0
  370. package/dist/routing/segment-codegen.d.ts +38 -0
  371. package/dist/routing/segment-codegen.d.ts.map +1 -0
  372. package/dist/routing/types.d.ts +77 -25
  373. package/dist/routing/types.d.ts.map +1 -1
  374. package/dist/routing/walkers.d.ts +51 -0
  375. package/dist/routing/walkers.d.ts.map +1 -0
  376. package/dist/rsc-runtime/rsc.d.ts +1 -1
  377. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  378. package/dist/rsc-runtime/ssr.d.ts +12 -0
  379. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  380. package/dist/schema-bridge.d.ts +91 -0
  381. package/dist/schema-bridge.d.ts.map +1 -0
  382. package/dist/search-params/define.d.ts +157 -0
  383. package/dist/search-params/define.d.ts.map +1 -0
  384. package/dist/search-params/index.d.ts +4 -7
  385. package/dist/search-params/index.d.ts.map +1 -1
  386. package/dist/search-params/index.js +37 -440
  387. package/dist/search-params/index.js.map +1 -1
  388. package/dist/search-params/registry.d.ts +2 -2
  389. package/dist/search-params/registry.d.ts.map +1 -1
  390. package/dist/search-params/wrappers.d.ts +53 -0
  391. package/dist/search-params/wrappers.d.ts.map +1 -0
  392. package/dist/segment-params/define.d.ts +89 -0
  393. package/dist/segment-params/define.d.ts.map +1 -0
  394. package/dist/segment-params/index.d.ts +3 -0
  395. package/dist/segment-params/index.d.ts.map +1 -0
  396. package/dist/segment-params/index.js +2 -0
  397. package/dist/server/access-gate.d.ts +8 -3
  398. package/dist/server/access-gate.d.ts.map +1 -1
  399. package/dist/server/action-client.d.ts +41 -6
  400. package/dist/server/action-client.d.ts.map +1 -1
  401. package/dist/server/action-encryption.d.ts +76 -0
  402. package/dist/server/action-encryption.d.ts.map +1 -0
  403. package/dist/server/action-handler.d.ts +35 -1
  404. package/dist/server/action-handler.d.ts.map +1 -1
  405. package/dist/server/actions.d.ts +6 -30
  406. package/dist/server/actions.d.ts.map +1 -1
  407. package/dist/server/als-registry.d.ts +85 -11
  408. package/dist/server/als-registry.d.ts.map +1 -1
  409. package/dist/server/asset-headers.d.ts +8 -18
  410. package/dist/server/asset-headers.d.ts.map +1 -1
  411. package/dist/server/body-limits.d.ts.map +1 -1
  412. package/dist/server/build-manifest.d.ts +6 -29
  413. package/dist/server/build-manifest.d.ts.map +1 -1
  414. package/dist/server/canonicalize.d.ts +10 -0
  415. package/dist/server/canonicalize.d.ts.map +1 -1
  416. package/dist/server/coalesce-tick.d.ts +40 -0
  417. package/dist/server/coalesce-tick.d.ts.map +1 -0
  418. package/dist/server/cookie-context.d.ts +170 -0
  419. package/dist/server/cookie-context.d.ts.map +1 -0
  420. package/dist/server/cookie-parsing.d.ts +65 -0
  421. package/dist/server/cookie-parsing.d.ts.map +1 -0
  422. package/dist/server/csrf.d.ts +3 -2
  423. package/dist/server/csrf.d.ts.map +1 -1
  424. package/dist/server/default-logger.d.ts +22 -0
  425. package/dist/server/default-logger.d.ts.map +1 -0
  426. package/dist/server/deny-boundary.d.ts +115 -0
  427. package/dist/server/deny-boundary.d.ts.map +1 -0
  428. package/dist/server/deny-renderer.d.ts +2 -2
  429. package/dist/server/deny-renderer.d.ts.map +1 -1
  430. package/dist/server/dev-source-map.d.ts +22 -0
  431. package/dist/server/dev-source-map.d.ts.map +1 -0
  432. package/dist/server/early-hints-sender.d.ts.map +1 -1
  433. package/dist/server/early-hints.d.ts +13 -11
  434. package/dist/server/early-hints.d.ts.map +1 -1
  435. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  436. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  437. package/dist/server/fallback-error.d.ts +12 -7
  438. package/dist/server/fallback-error.d.ts.map +1 -1
  439. package/dist/server/flight-injection-state.d.ts +66 -0
  440. package/dist/server/flight-injection-state.d.ts.map +1 -0
  441. package/dist/server/flight-scripts.d.ts +42 -0
  442. package/dist/server/flight-scripts.d.ts.map +1 -0
  443. package/dist/server/form-data.d.ts +41 -0
  444. package/dist/server/form-data.d.ts.map +1 -1
  445. package/dist/server/html-injector-core.d.ts +221 -0
  446. package/dist/server/html-injector-core.d.ts.map +1 -0
  447. package/dist/server/html-injectors.d.ts +82 -41
  448. package/dist/server/html-injectors.d.ts.map +1 -1
  449. package/dist/server/index.d.ts +10 -46
  450. package/dist/server/index.d.ts.map +1 -1
  451. package/dist/server/index.js +170 -2911
  452. package/dist/server/index.js.map +1 -1
  453. package/dist/server/internal.d.ts +49 -0
  454. package/dist/server/internal.d.ts.map +1 -0
  455. package/dist/server/internal.js +3577 -0
  456. package/dist/server/internal.js.map +1 -0
  457. package/dist/server/logger.d.ts +39 -7
  458. package/dist/server/logger.d.ts.map +1 -1
  459. package/dist/server/metadata-routes.d.ts +23 -7
  460. package/dist/server/metadata-routes.d.ts.map +1 -1
  461. package/dist/server/middleware-runner.d.ts +36 -4
  462. package/dist/server/middleware-runner.d.ts.map +1 -1
  463. package/dist/server/node-stream-transforms.d.ts +119 -0
  464. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  465. package/dist/server/param-coercion.d.ts +54 -0
  466. package/dist/server/param-coercion.d.ts.map +1 -0
  467. package/dist/server/pipeline-helpers.d.ts +95 -0
  468. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  469. package/dist/server/pipeline-interception.d.ts +1 -1
  470. package/dist/server/pipeline-interception.d.ts.map +1 -1
  471. package/dist/server/pipeline-metadata.d.ts +6 -0
  472. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  473. package/dist/server/pipeline-outcome.d.ts +49 -0
  474. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  475. package/dist/server/pipeline-phases.d.ts +56 -0
  476. package/dist/server/pipeline-phases.d.ts.map +1 -0
  477. package/dist/server/pipeline.d.ts +122 -19
  478. package/dist/server/pipeline.d.ts.map +1 -1
  479. package/dist/server/port-resolution.d.ts +117 -0
  480. package/dist/server/port-resolution.d.ts.map +1 -0
  481. package/dist/server/prebuilt/cache-key.d.ts +58 -0
  482. package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
  483. package/dist/server/prebuilt/capture-state.d.ts +57 -0
  484. package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
  485. package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
  486. package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
  487. package/dist/server/prebuilt/overlay.d.ts +100 -0
  488. package/dist/server/prebuilt/overlay.d.ts.map +1 -0
  489. package/dist/server/prebuilt/payload-source.d.ts +78 -0
  490. package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
  491. package/dist/server/prebuilt/synthetic-store.d.ts +66 -0
  492. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
  493. package/dist/server/prebuilt-builder.d.ts +120 -0
  494. package/dist/server/prebuilt-builder.d.ts.map +1 -0
  495. package/dist/server/prebuilt-runtime.d.ts +101 -0
  496. package/dist/server/prebuilt-runtime.d.ts.map +1 -0
  497. package/dist/server/primitives.d.ts +83 -31
  498. package/dist/server/primitives.d.ts.map +1 -1
  499. package/dist/server/render-timeout.d.ts +51 -0
  500. package/dist/server/render-timeout.d.ts.map +1 -0
  501. package/dist/server/render-utils.d.ts +25 -0
  502. package/dist/server/render-utils.d.ts.map +1 -0
  503. package/dist/server/request-context.d.ts +62 -107
  504. package/dist/server/request-context.d.ts.map +1 -1
  505. package/dist/server/route-element-builder.d.ts +39 -25
  506. package/dist/server/route-element-builder.d.ts.map +1 -1
  507. package/dist/server/route-handler.d.ts.map +1 -1
  508. package/dist/server/route-matcher.d.ts +25 -36
  509. package/dist/server/route-matcher.d.ts.map +1 -1
  510. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  511. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  512. package/dist/server/rsc-entry/api-handler.d.ts +12 -3
  513. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  514. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  515. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  516. package/dist/server/rsc-entry/helpers.d.ts +51 -28
  517. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  518. package/dist/server/rsc-entry/index.d.ts +30 -8
  519. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  520. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  521. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  522. package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
  523. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
  524. package/dist/server/rsc-entry/rsc-payload.d.ts +5 -6
  525. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  526. package/dist/server/rsc-entry/rsc-stream.d.ts +17 -1
  527. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  528. package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
  529. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  530. package/dist/server/rsc-entry/ssr-renderer.d.ts +34 -4
  531. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  532. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  533. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  534. package/dist/server/safe-load.d.ts +46 -0
  535. package/dist/server/safe-load.d.ts.map +1 -0
  536. package/dist/server/sensitive-fields.d.ts +74 -0
  537. package/dist/server/sensitive-fields.d.ts.map +1 -0
  538. package/dist/server/sitemap-generator.d.ts +129 -0
  539. package/dist/server/sitemap-generator.d.ts.map +1 -0
  540. package/dist/server/sitemap-handler.d.ts +22 -0
  541. package/dist/server/sitemap-handler.d.ts.map +1 -0
  542. package/dist/server/slot-resolver.d.ts +7 -5
  543. package/dist/server/slot-resolver.d.ts.map +1 -1
  544. package/dist/server/ssr-bridge-types.d.ts +121 -0
  545. package/dist/server/ssr-bridge-types.d.ts.map +1 -0
  546. package/dist/server/ssr-entry.d.ts +2 -43
  547. package/dist/server/ssr-entry.d.ts.map +1 -1
  548. package/dist/server/ssr-render.d.ts +64 -21
  549. package/dist/server/ssr-render.d.ts.map +1 -1
  550. package/dist/server/ssr-wrappers.d.ts +50 -0
  551. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  552. package/dist/server/state-tree-diff.d.ts +12 -5
  553. package/dist/server/state-tree-diff.d.ts.map +1 -1
  554. package/dist/server/status-code-resolver.d.ts +22 -11
  555. package/dist/server/status-code-resolver.d.ts.map +1 -1
  556. package/dist/server/stream-utils.d.ts +47 -0
  557. package/dist/server/stream-utils.d.ts.map +1 -0
  558. package/dist/server/tracing.d.ts +44 -9
  559. package/dist/server/tracing.d.ts.map +1 -1
  560. package/dist/server/tree-builder.d.ts +62 -30
  561. package/dist/server/tree-builder.d.ts.map +1 -1
  562. package/dist/server/tree-match.d.ts +49 -0
  563. package/dist/server/tree-match.d.ts.map +1 -0
  564. package/dist/server/types.d.ts +71 -6
  565. package/dist/server/types.d.ts.map +1 -1
  566. package/dist/server/utils/escape-html.d.ts +14 -0
  567. package/dist/server/utils/escape-html.d.ts.map +1 -0
  568. package/dist/server/utils/mdx-file.d.ts +15 -0
  569. package/dist/server/utils/mdx-file.d.ts.map +1 -0
  570. package/dist/server/version-skew.d.ts +61 -0
  571. package/dist/server/version-skew.d.ts.map +1 -0
  572. package/dist/server/workers-cache-bridge.d.ts +26 -0
  573. package/dist/server/workers-cache-bridge.d.ts.map +1 -0
  574. package/dist/shared/href-validation.d.ts +49 -0
  575. package/dist/shared/href-validation.d.ts.map +1 -0
  576. package/dist/shared/merge-search-params.d.ts +22 -0
  577. package/dist/shared/merge-search-params.d.ts.map +1 -0
  578. package/dist/shared/redirect-type.d.ts +17 -0
  579. package/dist/shared/redirect-type.d.ts.map +1 -0
  580. package/dist/shims/font-google.d.ts +1 -1
  581. package/dist/shims/font-google.d.ts.map +1 -1
  582. package/dist/shims/font-google.js +42 -0
  583. package/dist/shims/font-google.js.map +1 -0
  584. package/dist/shims/font-local.d.ts +26 -0
  585. package/dist/shims/font-local.d.ts.map +1 -0
  586. package/dist/shims/font-local.js +20 -0
  587. package/dist/shims/font-local.js.map +1 -0
  588. package/dist/shims/headers.d.ts +53 -1
  589. package/dist/shims/headers.d.ts.map +1 -1
  590. package/dist/shims/image.d.ts +16 -16
  591. package/dist/shims/navigation-client.d.ts +35 -11
  592. package/dist/shims/navigation-client.d.ts.map +1 -1
  593. package/dist/shims/navigation.d.ts +11 -5
  594. package/dist/shims/navigation.d.ts.map +1 -1
  595. package/dist/utils/state-machine.d.ts +80 -0
  596. package/dist/utils/state-machine.d.ts.map +1 -0
  597. package/docs/api/30-api-server.mdx +233 -0
  598. package/docs/api/31-api-client.mdx +161 -0
  599. package/docs/api/32-api-cache.mdx +199 -0
  600. package/docs/api/33-api-search-params.mdx +141 -0
  601. package/docs/api/34-api-config.mdx +189 -0
  602. package/docs/api/35-api-typescript.mdx +170 -0
  603. package/docs/api/36-cli.mdx +143 -0
  604. package/docs/learn/00-introduction.mdx +76 -0
  605. package/docs/learn/01-quick-start.mdx +94 -0
  606. package/docs/learn/02-pages-and-layouts.mdx +147 -0
  607. package/docs/learn/03-fetching-data.mdx +211 -0
  608. package/docs/learn/03b-access-control.mdx +130 -0
  609. package/docs/learn/04-loading-states.mdx +67 -0
  610. package/docs/learn/04b-the-flush-point.mdx +115 -0
  611. package/docs/learn/05-typed-params.mdx +275 -0
  612. package/docs/learn/06-forms-and-actions.mdx +146 -0
  613. package/docs/learn/07-typed-routes.mdx +127 -0
  614. package/docs/learn/08-streaming.mdx +146 -0
  615. package/docs/learn/09-caching.mdx +136 -0
  616. package/docs/learn/10-middleware.mdx +157 -0
  617. package/docs/learn/11-error-handling.mdx +156 -0
  618. package/docs/learn/12-client-navigation.mdx +168 -0
  619. package/docs/learn/13-configuration.mdx +145 -0
  620. package/docs/learn/14-deploying.mdx +264 -0
  621. package/docs/more/01-advanced-routing.mdx +139 -0
  622. package/docs/more/02-advanced-forms.mdx +137 -0
  623. package/docs/more/03-coming-from-nextjs.mdx +186 -0
  624. package/docs/more/04-metadata-and-fonts.mdx +193 -0
  625. package/docs/more/04b-mdx.mdx +209 -0
  626. package/docs/more/05-content-collections.mdx +90 -0
  627. package/docs/more/06-instrumentation.mdx +214 -0
  628. package/docs/more/07-security.mdx +129 -0
  629. package/docs/more/08-developer-experience.mdx +134 -0
  630. package/docs/more/40-why-timber.mdx +50 -0
  631. package/docs/more/41-timber-vs-nextjs.mdx +81 -0
  632. package/docs/more/42-timber-vs-others.mdx +68 -0
  633. package/docs/more/50-ai-agent-instructions.mdx +169 -0
  634. package/llms.txt +55 -0
  635. package/package.json +102 -26
  636. package/src/adapters/build-output-helper.ts +199 -0
  637. package/src/adapters/cloudflare-dev.ts +177 -0
  638. package/src/adapters/cloudflare-kv-cache.ts +179 -0
  639. package/src/adapters/cloudflare.ts +594 -119
  640. package/src/adapters/compress-module.ts +27 -92
  641. package/src/adapters/nitro.ts +131 -96
  642. package/src/adapters/raw-imports.d.ts +5 -0
  643. package/src/adapters/shared.ts +68 -0
  644. package/src/adapters/wrangler.d.ts +7 -0
  645. package/src/cache/cache-api.ts +107 -0
  646. package/src/cache/handler-store.ts +76 -0
  647. package/src/cache/index.ts +88 -18
  648. package/src/cache/invalidation-epoch.ts +93 -0
  649. package/src/cache/redis-handler.ts +122 -15
  650. package/src/cache/singleflight.ts +64 -6
  651. package/src/cache/sizeof.ts +33 -0
  652. package/src/cache/stable-stringify.ts +65 -2
  653. package/src/cache/store.ts +71 -0
  654. package/src/cache/stores/cloudflare-kv.ts +52 -0
  655. package/src/cache/stores/memory.ts +125 -0
  656. package/src/cache/stores/redis.ts +97 -0
  657. package/src/cache/stores/vercel.ts +59 -0
  658. package/src/cache/tag-aware-handler.ts +233 -0
  659. package/src/cache/timber-cache.ts +142 -36
  660. package/src/cdn/cloudflare-purge.ts +50 -0
  661. package/src/cdn/fastly-purge.ts +63 -0
  662. package/src/cdn/headers.ts +153 -0
  663. package/src/cdn/index.ts +17 -0
  664. package/src/cdn/purge-store.ts +34 -0
  665. package/src/cdn/workers-cache-purge.ts +30 -0
  666. package/src/cli-schema-sync.ts +388 -0
  667. package/src/cli.ts +157 -34
  668. package/src/client/browser-dev.ts +156 -1
  669. package/src/client/browser-entry/action-dispatch.ts +124 -0
  670. package/src/client/browser-entry/hmr.ts +70 -0
  671. package/src/client/browser-entry/hydrate.ts +187 -0
  672. package/src/client/browser-entry/index.ts +111 -0
  673. package/src/client/browser-entry/post-hydration.ts +103 -0
  674. package/src/client/browser-entry/router-init.ts +287 -0
  675. package/src/client/browser-entry/rsc-stream.ts +157 -0
  676. package/src/client/browser-entry/scroll.ts +50 -0
  677. package/src/client/error-boundary.tsx +127 -22
  678. package/src/client/error-reconstituter.tsx +79 -0
  679. package/src/client/form.tsx +31 -32
  680. package/src/client/history.ts +11 -7
  681. package/src/client/index.ts +67 -45
  682. package/src/client/internal.ts +58 -0
  683. package/src/client/link.tsx +346 -150
  684. package/src/client/navigation-api.ts +341 -0
  685. package/src/client/navigation-context.ts +15 -7
  686. package/src/client/navigation-root.tsx +355 -0
  687. package/src/client/nuqs-adapter.tsx +16 -3
  688. package/src/client/router-ref.ts +1 -1
  689. package/src/client/router.ts +482 -166
  690. package/src/client/rsc-fetch.ts +214 -33
  691. package/src/client/segment-cache.ts +7 -7
  692. package/src/client/segment-outlet.tsx +77 -0
  693. package/src/client/segment-update-context.ts +42 -0
  694. package/src/client/shallow-url.ts +22 -0
  695. package/src/client/ssr-data.ts +13 -5
  696. package/src/client/state.ts +2 -2
  697. package/src/client/top-loader.tsx +11 -9
  698. package/src/client/use-cookie.ts +49 -14
  699. package/src/client/use-link-status.ts +7 -7
  700. package/src/client/use-pathname.ts +1 -0
  701. package/src/client/use-pending-navigation.ts +40 -0
  702. package/src/client/use-query-states.ts +9 -3
  703. package/src/client/use-router.ts +4 -1
  704. package/src/client/use-search-params.ts +31 -44
  705. package/src/client/{use-params.ts → use-segment-params.ts} +9 -6
  706. package/src/codec.ts +147 -0
  707. package/src/config-types.ts +302 -0
  708. package/src/config-validation.ts +328 -0
  709. package/src/content/index.ts +5 -13
  710. package/src/cookies/define-cookie.ts +217 -53
  711. package/src/cookies/index.ts +12 -1
  712. package/src/cookies/json-cookie.ts +105 -0
  713. package/src/cookies/validation.ts +192 -0
  714. package/src/dev-tools/404-page.ts +286 -0
  715. package/src/dev-tools/browser-logs.ts +55 -0
  716. package/src/dev-tools/dev-page-shell.ts +260 -0
  717. package/src/dev-tools/error-page.ts +331 -0
  718. package/src/dev-tools/holding-server.ts +187 -0
  719. package/src/dev-tools/hydration-overlay.ts +158 -0
  720. package/src/dev-tools/index.ts +83 -0
  721. package/src/dev-tools/instrumentation.ts +213 -0
  722. package/src/{server/dev-logger.ts → dev-tools/logger.ts} +33 -51
  723. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +9 -5
  724. package/src/dev-tools/overlay.ts +469 -0
  725. package/src/dev-tools/stack-classifier.ts +75 -0
  726. package/src/dev-tools/terminal.ts +182 -0
  727. package/src/fonts/ast-walk.ts +235 -0
  728. package/src/fonts/ast.ts +477 -126
  729. package/src/fonts/bundle.ts +138 -0
  730. package/src/fonts/dev-middleware.ts +85 -0
  731. package/src/fonts/fallbacks.ts +0 -23
  732. package/src/fonts/google.ts +63 -8
  733. package/src/fonts/local.ts +9 -8
  734. package/src/fonts/paths.ts +58 -0
  735. package/src/fonts/pipeline.ts +316 -0
  736. package/src/fonts/transform.ts +305 -0
  737. package/src/fonts/types.ts +52 -1
  738. package/src/fonts/virtual-modules.ts +179 -0
  739. package/src/index.ts +431 -352
  740. package/src/params/codec-registry.ts +34 -0
  741. package/src/params/define-schema.ts +115 -0
  742. package/src/params/index.ts +17 -0
  743. package/src/params/resolve-schema.ts +84 -0
  744. package/src/plugin-context.ts +378 -0
  745. package/src/plugins/adapter-build.ts +98 -4
  746. package/src/plugins/build-manifest.ts +168 -23
  747. package/src/plugins/build-report.ts +253 -35
  748. package/src/plugins/cache.ts +186 -0
  749. package/src/plugins/callsite-ast.ts +167 -0
  750. package/src/plugins/callsite-jsx.ts +243 -0
  751. package/src/plugins/chunks.ts +74 -5
  752. package/src/plugins/client-chunks.ts +144 -0
  753. package/src/plugins/cloudflare-wasm.ts +141 -0
  754. package/src/plugins/content.ts +1 -1
  755. package/src/plugins/dev-server.ts +293 -46
  756. package/src/plugins/entries.ts +129 -8
  757. package/src/plugins/fonts.ts +191 -664
  758. package/src/plugins/mdx.ts +47 -10
  759. package/src/plugins/prebuilt-capture.ts +210 -0
  760. package/src/plugins/prebuilt.ts +700 -0
  761. package/src/plugins/prerender-sugar.ts +329 -0
  762. package/src/plugins/routing.ts +237 -241
  763. package/src/plugins/server-bundle.ts +97 -12
  764. package/src/plugins/shims.ts +217 -64
  765. package/src/plugins/static-build.ts +15 -90
  766. package/src/routing/codegen-shared.ts +115 -0
  767. package/src/routing/codegen-types.ts +65 -0
  768. package/src/routing/codegen.ts +360 -178
  769. package/src/routing/convention-lint.ts +394 -0
  770. package/src/routing/export-detect.ts +304 -0
  771. package/src/routing/file-cache.ts +23 -0
  772. package/src/routing/index.ts +10 -1
  773. package/src/routing/interception.ts +3 -22
  774. package/src/routing/link-codegen.ts +310 -0
  775. package/src/routing/manifest-codegen.ts +281 -0
  776. package/src/routing/scanner.ts +248 -188
  777. package/src/routing/schema-validation.ts +149 -0
  778. package/src/routing/segment-classify.ts +188 -0
  779. package/src/routing/segment-codegen.ts +98 -0
  780. package/src/routing/types.ts +78 -25
  781. package/src/routing/walkers.ts +90 -0
  782. package/src/rsc-runtime/rsc.ts +9 -0
  783. package/src/rsc-runtime/ssr.ts +50 -0
  784. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  785. package/src/schema-bridge.ts +252 -0
  786. package/src/search-params/define.ts +570 -0
  787. package/src/search-params/index.ts +14 -20
  788. package/src/search-params/registry.ts +2 -2
  789. package/src/search-params/wrappers.ts +110 -0
  790. package/src/segment-params/define.ts +249 -0
  791. package/src/segment-params/index.ts +9 -0
  792. package/src/server/access-gate.tsx +84 -34
  793. package/src/server/action-client.ts +119 -28
  794. package/src/server/action-encryption.ts +144 -0
  795. package/src/server/action-handler.ts +123 -33
  796. package/src/server/actions.ts +39 -54
  797. package/src/server/als-registry.ts +129 -20
  798. package/src/server/asset-headers.ts +15 -37
  799. package/src/server/body-limits.ts +10 -2
  800. package/src/server/build-manifest.ts +13 -56
  801. package/src/server/canonicalize.ts +6 -3
  802. package/src/server/coalesce-tick.ts +75 -0
  803. package/src/server/compress.ts +34 -7
  804. package/src/server/cookie-context.ts +484 -0
  805. package/src/server/cookie-parsing.ts +163 -0
  806. package/src/server/csrf.ts +39 -6
  807. package/src/server/default-logger.ts +99 -0
  808. package/src/server/deny-boundary.ts +311 -0
  809. package/src/server/deny-renderer.ts +85 -77
  810. package/src/server/dev-source-map.ts +31 -0
  811. package/src/server/early-hints-sender.ts +3 -2
  812. package/src/server/early-hints.ts +37 -27
  813. package/src/server/error-boundary-wrapper.ts +61 -22
  814. package/src/server/fallback-error.ts +79 -102
  815. package/src/server/flight-injection-state.ts +113 -0
  816. package/src/server/flight-scripts.ts +62 -0
  817. package/src/server/form-data.ts +124 -12
  818. package/src/server/html-injector-core.ts +437 -0
  819. package/src/server/html-injectors.ts +267 -254
  820. package/src/server/index.ts +29 -183
  821. package/src/server/internal.ts +181 -0
  822. package/src/server/logger.ts +72 -36
  823. package/src/server/metadata-routes.ts +44 -19
  824. package/src/server/middleware-runner.ts +75 -4
  825. package/src/server/node-stream-transforms.ts +331 -0
  826. package/src/server/param-coercion.ts +206 -0
  827. package/src/server/pipeline-helpers.ts +204 -0
  828. package/src/server/pipeline-interception.ts +32 -18
  829. package/src/server/pipeline-metadata.ts +14 -0
  830. package/src/server/pipeline-outcome.ts +197 -0
  831. package/src/server/pipeline-phases.ts +538 -0
  832. package/src/server/pipeline.ts +226 -382
  833. package/src/server/port-resolution.ts +215 -0
  834. package/src/server/prebuilt/cache-key.ts +224 -0
  835. package/src/server/prebuilt/capture-state.ts +89 -0
  836. package/src/server/prebuilt/manifest-tag-index.ts +46 -0
  837. package/src/server/prebuilt/overlay.ts +256 -0
  838. package/src/server/prebuilt/payload-source.ts +201 -0
  839. package/src/server/prebuilt/synthetic-store.ts +121 -0
  840. package/src/server/prebuilt-builder.ts +696 -0
  841. package/src/server/prebuilt-runtime.ts +708 -0
  842. package/src/server/primitives.ts +155 -63
  843. package/src/server/render-timeout.ts +108 -0
  844. package/src/server/render-utils.ts +31 -0
  845. package/src/server/request-context.ts +168 -337
  846. package/src/server/route-element-builder.ts +523 -233
  847. package/src/server/route-handler.ts +31 -4
  848. package/src/server/route-matcher.ts +144 -277
  849. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  850. package/src/server/rsc-entry/api-handler.ts +69 -32
  851. package/src/server/rsc-entry/error-renderer.ts +306 -89
  852. package/src/server/rsc-entry/helpers.ts +160 -76
  853. package/src/server/rsc-entry/index.ts +393 -329
  854. package/src/server/rsc-entry/render-route.ts +284 -0
  855. package/src/server/rsc-entry/revalidate-renderer.ts +349 -0
  856. package/src/server/rsc-entry/rsc-payload.ts +72 -33
  857. package/src/server/rsc-entry/rsc-stream.ts +85 -13
  858. package/src/server/rsc-entry/ssr-bridge.ts +18 -5
  859. package/src/server/rsc-entry/ssr-renderer.ts +273 -43
  860. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  861. package/src/server/safe-load.ts +60 -0
  862. package/src/server/sensitive-fields.ts +230 -0
  863. package/src/server/sitemap-generator.ts +344 -0
  864. package/src/server/sitemap-handler.ts +157 -0
  865. package/src/server/slot-resolver.ts +258 -257
  866. package/src/server/ssr-bridge-types.ts +124 -0
  867. package/src/server/ssr-entry.ts +206 -78
  868. package/src/server/ssr-render.ts +345 -82
  869. package/src/server/ssr-wrappers.tsx +141 -0
  870. package/src/server/state-tree-diff.ts +30 -23
  871. package/src/server/status-code-resolver.ts +115 -130
  872. package/src/server/stream-utils.ts +286 -0
  873. package/src/server/tracing.ts +126 -14
  874. package/src/server/tree-builder.ts +204 -90
  875. package/src/server/tree-match.ts +220 -0
  876. package/src/server/types.ts +78 -9
  877. package/src/server/utils/escape-html.ts +20 -0
  878. package/src/server/utils/mdx-file.ts +22 -0
  879. package/src/server/version-skew.ts +104 -0
  880. package/src/server/workers-cache-bridge.ts +33 -0
  881. package/src/shared/href-validation.ts +159 -0
  882. package/src/shared/merge-search-params.ts +55 -0
  883. package/src/shared/redirect-type.ts +17 -0
  884. package/src/shims/font-google.ts +1 -1
  885. package/src/shims/font-local.ts +34 -0
  886. package/src/shims/headers.ts +122 -1
  887. package/src/shims/navigation-client.ts +51 -29
  888. package/src/shims/navigation.ts +14 -7
  889. package/src/utils/state-machine.ts +111 -0
  890. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  891. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  892. package/dist/_chunks/debug-B3Gypr3D.js +0 -108
  893. package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
  894. package/dist/_chunks/format-RyoGQL74.js +0 -164
  895. package/dist/_chunks/format-RyoGQL74.js.map +0 -1
  896. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  897. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  898. package/dist/_chunks/metadata-routes-Cjmvi3rQ.js.map +0 -1
  899. package/dist/_chunks/request-context-BQUC8PHn.js +0 -330
  900. package/dist/_chunks/request-context-BQUC8PHn.js.map +0 -1
  901. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  902. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  903. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  904. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  905. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  906. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  907. package/dist/cache/index.js.map +0 -1
  908. package/dist/cache/register-cached-function.d.ts +0 -17
  909. package/dist/cache/register-cached-function.d.ts.map +0 -1
  910. package/dist/client/browser-entry.d.ts +0 -21
  911. package/dist/client/browser-entry.d.ts.map +0 -1
  912. package/dist/client/head.d.ts +0 -16
  913. package/dist/client/head.d.ts.map +0 -1
  914. package/dist/client/link-status-provider.d.ts +0 -11
  915. package/dist/client/link-status-provider.d.ts.map +0 -1
  916. package/dist/client/segment-merger.d.ts +0 -119
  917. package/dist/client/segment-merger.d.ts.map +0 -1
  918. package/dist/client/stale-reload.d.ts +0 -44
  919. package/dist/client/stale-reload.d.ts.map +0 -1
  920. package/dist/client/transition-root.d.ts +0 -74
  921. package/dist/client/transition-root.d.ts.map +0 -1
  922. package/dist/client/use-navigation-pending.d.ts +0 -26
  923. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  924. package/dist/client/use-params.d.ts.map +0 -1
  925. package/dist/plugins/cache-transform.d.ts +0 -36
  926. package/dist/plugins/cache-transform.d.ts.map +0 -1
  927. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  928. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  929. package/dist/plugins/dev-logs.d.ts.map +0 -1
  930. package/dist/plugins/dynamic-transform.d.ts +0 -72
  931. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  932. package/dist/plugins/server-action-exports.d.ts +0 -26
  933. package/dist/plugins/server-action-exports.d.ts.map +0 -1
  934. package/dist/routing/status-file-lint.d.ts +0 -33
  935. package/dist/routing/status-file-lint.d.ts.map +0 -1
  936. package/dist/search-params/analyze.d.ts +0 -54
  937. package/dist/search-params/analyze.d.ts.map +0 -1
  938. package/dist/search-params/builtin-codecs.d.ts +0 -105
  939. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  940. package/dist/search-params/codecs.d.ts +0 -53
  941. package/dist/search-params/codecs.d.ts.map +0 -1
  942. package/dist/search-params/create.d.ts +0 -106
  943. package/dist/search-params/create.d.ts.map +0 -1
  944. package/dist/server/client-module-map.d.ts +0 -47
  945. package/dist/server/client-module-map.d.ts.map +0 -1
  946. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  947. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  948. package/dist/server/dev-logger.d.ts.map +0 -1
  949. package/dist/server/dev-span-processor.d.ts +0 -29
  950. package/dist/server/dev-span-processor.d.ts.map +0 -1
  951. package/dist/server/dev-warnings.d.ts +0 -129
  952. package/dist/server/dev-warnings.d.ts.map +0 -1
  953. package/dist/server/flush.d.ts +0 -74
  954. package/dist/server/flush.d.ts.map +0 -1
  955. package/dist/server/manifest-status-resolver.d.ts +0 -58
  956. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  957. package/dist/server/prerender.d.ts +0 -77
  958. package/dist/server/prerender.d.ts.map +0 -1
  959. package/dist/utils/directive-parser.d.ts +0 -70
  960. package/dist/utils/directive-parser.d.ts.map +0 -1
  961. package/src/cache/register-cached-function.ts +0 -103
  962. package/src/client/browser-entry.ts +0 -678
  963. package/src/client/head.ts +0 -61
  964. package/src/client/link-status-provider.tsx +0 -30
  965. package/src/client/segment-merger.ts +0 -339
  966. package/src/client/stale-reload.ts +0 -87
  967. package/src/client/transition-root.tsx +0 -166
  968. package/src/client/use-navigation-pending.ts +0 -38
  969. package/src/plugins/cache-transform.ts +0 -199
  970. package/src/plugins/dev-error-overlay.ts +0 -230
  971. package/src/plugins/dynamic-transform.ts +0 -161
  972. package/src/plugins/server-action-exports.ts +0 -220
  973. package/src/routing/status-file-lint.ts +0 -112
  974. package/src/search-params/analyze.ts +0 -192
  975. package/src/search-params/builtin-codecs.ts +0 -228
  976. package/src/search-params/codecs.ts +0 -153
  977. package/src/search-params/create.ts +0 -321
  978. package/src/server/client-module-map.ts +0 -58
  979. package/src/server/dev-fetch-instrumentation.ts +0 -96
  980. package/src/server/dev-span-processor.ts +0 -78
  981. package/src/server/dev-warnings.ts +0 -283
  982. package/src/server/flush.ts +0 -182
  983. package/src/server/manifest-status-resolver.ts +0 -215
  984. package/src/server/prerender.ts +0 -139
  985. package/src/utils/directive-parser.ts +0 -529
@@ -18,21 +18,11 @@ import type {
18
18
  ScannerConfig,
19
19
  InterceptionMarker,
20
20
  } from './types.js';
21
- import { DEFAULT_PAGE_EXTENSIONS, INTERCEPTION_MARKERS } from './types.js';
22
- import { classifyMetadataRoute, isDynamicMetadataExtension } from '#/server/metadata-routes.js';
23
-
24
- /**
25
- * Pattern matching encoded path delimiters that must be rejected during route discovery.
26
- * %2F / %2f (forward slash) and %5C / %5c (backslash) can cause route collisions
27
- * when decoded. See design/13-security.md §"Encoded separators rejected".
28
- */
29
- const ENCODED_SEPARATOR_PATTERN = /%(?:2[fF]|5[cC])/;
30
-
31
- /**
32
- * Pattern matching encoded null bytes (%00) that must be rejected.
33
- * See design/13-security.md §"Null bytes rejected".
34
- */
35
- const ENCODED_NULL_PATTERN = /%00/;
21
+ import { classifySegment } from './segment-classify.js';
22
+ import { DEFAULT_PAGE_EXTENSIONS } from './types.js';
23
+ import { classifyMetadataRoute, isDynamicMetadataExtension } from '../server/metadata-routes.js';
24
+ import { swallow } from '../server/logger.js';
25
+ import { ENCODED_SEPARATOR_RE, NULL_BYTE_RE } from '../server/canonicalize.js';
36
26
 
37
27
  /**
38
28
  * File convention names that use pageExtensions (can be .tsx, .ts, .jsx, .js, .mdx, etc.)
@@ -53,7 +43,7 @@ const LEGACY_STATUS_FILES: Record<string, number> = {
53
43
  /**
54
44
  * File convention names that are always .ts/.tsx (never .mdx etc.)
55
45
  */
56
- const FIXED_CONVENTIONS = new Set(['middleware', 'access', 'route', 'prerender', 'search-params']);
46
+ const FIXED_CONVENTIONS = new Set(['middleware', 'access', 'route', 'params']);
57
47
 
58
48
  /**
59
49
  * Status-code file patterns:
@@ -83,6 +73,14 @@ export function scanRoutes(appDir: string, config: ScannerConfig = {}): RouteTre
83
73
  tree.proxy = proxyFile;
84
74
  }
85
75
 
76
+ // Check for global-error.{tsx,ts,jsx,js} at app root.
77
+ // Tier 2 error page — renders standalone (no layouts) when no segment-level
78
+ // error file is found. See design/10-error-handling.md §"Tier 2".
79
+ const globalErrorFile = findPageExtFile(appDir, 'global-error', extSet);
80
+ if (globalErrorFile) {
81
+ tree.globalError = globalErrorFile;
82
+ }
83
+
86
84
  // Scan the root directory's files
87
85
  scanSegmentFiles(appDir, tree.root, extSet);
88
86
 
@@ -92,6 +90,14 @@ export function scanRoutes(appDir: string, config: ScannerConfig = {}): RouteTre
92
90
  // Validate: detect route group collisions (different groups producing pages at the same URL)
93
91
  validateRouteGroupCollisions(tree.root);
94
92
 
93
+ // Validate: detect duplicate param names in nested dynamic segments
94
+ // e.g., /[id]/items/[id] — same param name in ancestor and descendant
95
+ validateDuplicateParamNames(tree.root);
96
+
97
+ // Validate: detect same param name used with different bracket forms
98
+ // e.g., [id] in one route and [...id] in another
99
+ validateUniqueBracketForms(tree.root);
100
+
95
101
  return tree;
96
102
  }
97
103
 
@@ -114,96 +120,10 @@ function createSegmentNode(
114
120
  interceptionMarker,
115
121
  interceptedSegmentName,
116
122
  children: [],
117
- slots: new Map(),
123
+ slots: {},
118
124
  };
119
125
  }
120
126
 
121
- /**
122
- * Classify a directory name into its segment type.
123
- */
124
- export function classifySegment(dirName: string): {
125
- type: SegmentType;
126
- paramName?: string;
127
- interceptionMarker?: InterceptionMarker;
128
- interceptedSegmentName?: string;
129
- } {
130
- // Private folder: _name (excluded from routing)
131
- if (dirName.startsWith('_')) {
132
- return { type: 'private' };
133
- }
134
-
135
- // Parallel route slot: @name
136
- if (dirName.startsWith('@')) {
137
- return { type: 'slot' };
138
- }
139
-
140
- // Intercepting routes: (.)name, (..)name, (...)name, (..)(..)name
141
- // Check before route groups since intercepting markers also start with (
142
- const interception = parseInterceptionMarker(dirName);
143
- if (interception) {
144
- return {
145
- type: 'intercepting',
146
- interceptionMarker: interception.marker,
147
- interceptedSegmentName: interception.segmentName,
148
- };
149
- }
150
-
151
- // Route group: (name)
152
- if (dirName.startsWith('(') && dirName.endsWith(')')) {
153
- return { type: 'group' };
154
- }
155
-
156
- // Optional catch-all: [[...name]]
157
- if (dirName.startsWith('[[...') && dirName.endsWith(']]')) {
158
- const paramName = dirName.slice(5, -2);
159
- return { type: 'optional-catch-all', paramName };
160
- }
161
-
162
- // Catch-all: [...name]
163
- if (dirName.startsWith('[...') && dirName.endsWith(']')) {
164
- const paramName = dirName.slice(4, -1);
165
- return { type: 'catch-all', paramName };
166
- }
167
-
168
- // Dynamic: [name]
169
- if (dirName.startsWith('[') && dirName.endsWith(']')) {
170
- const paramName = dirName.slice(1, -1);
171
- return { type: 'dynamic', paramName };
172
- }
173
-
174
- return { type: 'static' };
175
- }
176
-
177
- /**
178
- * Parse an interception marker from a directory name.
179
- *
180
- * Returns the marker and the remaining segment name, or null if not an
181
- * intercepting route. Markers are checked longest-first to avoid (..)
182
- * matching before (..)(..).
183
- *
184
- * Examples:
185
- * "(.)photo" → { marker: "(.)", segmentName: "photo" }
186
- * "(..)feed" → { marker: "(..)", segmentName: "feed" }
187
- * "(...)photos" → { marker: "(...)", segmentName: "photos" }
188
- * "(..)(..)admin" → { marker: "(..)(..)", segmentName: "admin" }
189
- * "(marketing)" → null (route group, not interception)
190
- */
191
- function parseInterceptionMarker(
192
- dirName: string
193
- ): { marker: InterceptionMarker; segmentName: string } | null {
194
- for (const marker of INTERCEPTION_MARKERS) {
195
- if (dirName.startsWith(marker)) {
196
- const rest = dirName.slice(marker.length);
197
- // Must have a segment name after the marker, and the rest must not
198
- // be empty or end with ) (which would be a route group like "(auth)")
199
- if (rest.length > 0 && !rest.endsWith(')')) {
200
- return { marker, segmentName: rest };
201
- }
202
- }
203
- }
204
- return null;
205
- }
206
-
207
127
  /**
208
128
  * Compute the URL path for a child segment given its parent's URL path.
209
129
  * Route groups, slots, and intercepting routes do NOT add URL depth.
@@ -225,7 +145,8 @@ function scanSegmentFiles(dirPath: string, node: SegmentNode, extSet: Set<string
225
145
  let entries: string[];
226
146
  try {
227
147
  entries = readdirSync(dirPath);
228
- } catch {
148
+ } catch (err) {
149
+ swallow(err, `scanSegmentFiles: unreadable directory ${dirPath}`, { level: 'warn' });
229
150
  return;
230
151
  }
231
152
 
@@ -244,47 +165,26 @@ function scanSegmentFiles(dirPath: string, node: SegmentNode, extSet: Set<string
244
165
 
245
166
  // Page-extension conventions (page, layout, error, default, denied)
246
167
  if (PAGE_EXT_CONVENTIONS.has(name) && extSet.has(ext)) {
247
- const file: RouteFile = { filePath: fullPath, extension: ext };
248
- switch (name) {
249
- case 'page':
250
- node.page = file;
251
- break;
252
- case 'layout':
253
- node.layout = file;
254
- break;
255
- case 'error':
256
- node.error = file;
257
- break;
258
- case 'default':
259
- node.default = file;
260
- break;
261
- case 'denied':
262
- node.denied = file;
263
- break;
168
+ const key = name as 'page' | 'layout' | 'error' | 'default' | 'denied';
169
+ const existing = node[key];
170
+ if (existing) {
171
+ throwDuplicateConvention(name, existing.filePath, fullPath);
264
172
  }
173
+ node[key] = { filePath: fullPath, extension: ext };
265
174
  continue;
266
175
  }
267
176
 
268
- // Fixed conventions (middleware, access, route) — always .ts or .tsx
269
- if (FIXED_CONVENTIONS.has(name) && /\.?[jt]sx?$/.test(ext)) {
270
- const file: RouteFile = { filePath: fullPath, extension: ext };
271
- switch (name) {
272
- case 'middleware':
273
- node.middleware = file;
274
- break;
275
- case 'access':
276
- node.access = file;
277
- break;
278
- case 'route':
279
- node.route = file;
280
- break;
281
- case 'prerender':
282
- node.prerender = file;
283
- break;
284
- case 'search-params':
285
- node.searchParams = file;
286
- break;
177
+ // Fixed conventions (middleware, access, route, params) — only
178
+ // .ts/.tsx/.js/.jsx, never pageExtensions like .mdx. The regex is
179
+ // anchored: mts/cts/mjs/cjs (and stray tail matches like `.foots`)
180
+ // are NOT recognized. See design/07-routing.md §"Page Extensions".
181
+ if (FIXED_CONVENTIONS.has(name) && /^[jt]sx?$/.test(ext)) {
182
+ const key = name as 'middleware' | 'access' | 'route' | 'params';
183
+ const existing = node[key];
184
+ if (existing) {
185
+ throwDuplicateConvention(name, existing.filePath, fullPath);
287
186
  }
187
+ node[key] = { filePath: fullPath, extension: ext };
288
188
  continue;
289
189
  }
290
190
 
@@ -292,50 +192,62 @@ function scanSegmentFiles(dirPath: string, node: SegmentNode, extSet: Set<string
292
192
  // Recognized regardless of pageExtensions — .json is a data format, not a page extension.
293
193
  if (STATUS_CODE_PATTERN.test(name) && ext === 'json') {
294
194
  if (!node.jsonStatusFiles) {
295
- node.jsonStatusFiles = new Map();
195
+ node.jsonStatusFiles = {};
296
196
  }
297
- node.jsonStatusFiles.set(name, { filePath: fullPath, extension: ext });
197
+ node.jsonStatusFiles[name] = { filePath: fullPath, extension: ext };
298
198
  continue;
299
199
  }
300
200
 
301
201
  // Status-code files (401.tsx, 4xx.tsx, 503.tsx, 5xx.tsx)
302
202
  if (STATUS_CODE_PATTERN.test(name) && extSet.has(ext)) {
303
203
  if (!node.statusFiles) {
304
- node.statusFiles = new Map();
204
+ node.statusFiles = {};
205
+ }
206
+ const existing = node.statusFiles[name];
207
+ if (existing) {
208
+ throwDuplicateConvention(name, existing.filePath, fullPath);
305
209
  }
306
- node.statusFiles.set(name, { filePath: fullPath, extension: ext });
210
+ node.statusFiles[name] = { filePath: fullPath, extension: ext };
307
211
  continue;
308
212
  }
309
213
 
310
214
  // Legacy compat files (not-found.tsx, forbidden.tsx, unauthorized.tsx)
311
215
  if (name in LEGACY_STATUS_FILES && extSet.has(ext)) {
312
216
  if (!node.legacyStatusFiles) {
313
- node.legacyStatusFiles = new Map();
217
+ node.legacyStatusFiles = {};
314
218
  }
315
- node.legacyStatusFiles.set(name, { filePath: fullPath, extension: ext });
219
+ const existing = node.legacyStatusFiles[name];
220
+ if (existing) {
221
+ throwDuplicateConvention(name, existing.filePath, fullPath);
222
+ }
223
+ node.legacyStatusFiles[name] = { filePath: fullPath, extension: ext };
316
224
  continue;
317
225
  }
318
226
 
319
227
  // Metadata route files (sitemap.ts, robots.ts, icon.tsx, opengraph-image.tsx, etc.)
320
228
  // Both static (.xml, .txt, .png, .ico, etc.) and dynamic (.ts, .tsx) files are recognized.
321
229
  // When both exist for the same base name, dynamic takes precedence.
230
+ // Two files of the SAME kind (static+static or dynamic+dynamic) are a
231
+ // build error — picking one by readdir order is platform-dependent.
322
232
  // See design/16-metadata.md §"Metadata Routes"
323
233
  const metaInfo = classifyMetadataRoute(entry);
324
234
  if (metaInfo) {
325
235
  if (!node.metadataRoutes) {
326
- node.metadataRoutes = new Map();
236
+ node.metadataRoutes = {};
327
237
  }
328
- const existing = node.metadataRoutes.get(name);
238
+ const existing = node.metadataRoutes[name];
329
239
  if (existing) {
330
- // Dynamic > static precedence: only overwrite if the new file is dynamic
331
- // or the existing file is static (dynamic always wins).
332
240
  const existingIsDynamic = isDynamicMetadataExtension(name, existing.extension);
333
241
  const newIsDynamic = isDynamicMetadataExtension(name, ext);
334
- if (newIsDynamic || !existingIsDynamic) {
335
- node.metadataRoutes.set(name, { filePath: fullPath, extension: ext });
242
+ if (existingIsDynamic === newIsDynamic) {
243
+ throwDuplicateConvention(name, existing.filePath, fullPath);
244
+ }
245
+ // Dynamic > static precedence: overwrite only when the new file is dynamic.
246
+ if (newIsDynamic) {
247
+ node.metadataRoutes[name] = { filePath: fullPath, extension: ext };
336
248
  }
337
249
  } else {
338
- node.metadataRoutes.set(name, { filePath: fullPath, extension: ext });
250
+ node.metadataRoutes[name] = { filePath: fullPath, extension: ext };
339
251
  }
340
252
  }
341
253
  }
@@ -351,6 +263,26 @@ function scanSegmentFiles(dirPath: string, node: SegmentNode, extSet: Set<string
351
263
  }
352
264
  }
353
265
 
266
+ /**
267
+ * Throw a build error for two files claiming the same convention slot in
268
+ * one segment (e.g. page.tsx + page.jsx). Which file readdir returns first
269
+ * is platform-dependent (APFS sorts entries, ext4 does not) — silently
270
+ * picking one would let macOS dev and Linux CI serve different
271
+ * implementations of the same route.
272
+ */
273
+ function throwDuplicateConvention(
274
+ convention: string,
275
+ firstPath: string,
276
+ secondPath: string
277
+ ): never {
278
+ throw new Error(
279
+ `Build error: duplicate '${convention}' files in the same route segment.\n` +
280
+ ` File 1: ${firstPath}\n` +
281
+ ` File 2: ${secondPath}\n` +
282
+ `Each segment may define '${convention}' at most once. Remove one of the files.`
283
+ );
284
+ }
285
+
354
286
  /**
355
287
  * Recursively scan child directories and build the segment tree.
356
288
  */
@@ -358,7 +290,8 @@ function scanChildren(dirPath: string, parentNode: SegmentNode, extSet: Set<stri
358
290
  let entries: string[];
359
291
  try {
360
292
  entries = readdirSync(dirPath);
361
- } catch {
293
+ } catch (err) {
294
+ swallow(err, `scanChildren: unreadable directory ${dirPath}`, { level: 'warn' });
362
295
  return;
363
296
  }
364
297
 
@@ -374,17 +307,17 @@ function scanChildren(dirPath: string, parentNode: SegmentNode, extSet: Set<stri
374
307
  // Reject directories with encoded path delimiters or null bytes.
375
308
  // These can cause route collisions when decoded at the URL boundary.
376
309
  // See design/13-security.md §"Encoded separators rejected" and §"Null bytes rejected".
377
- if (ENCODED_SEPARATOR_PATTERN.test(entry)) {
310
+ if (ENCODED_SEPARATOR_RE.test(entry)) {
378
311
  throw new Error(
379
- `Build error: directory name contains an encoded path delimiter (%%2F or %%5C).\n` +
312
+ `Build error: directory name contains an encoded path delimiter (%2F or %5C).\n` +
380
313
  ` Directory: ${fullPath}\n` +
381
314
  `Encoded separators in directory names cause route collisions when decoded. ` +
382
315
  `Rename the directory to remove the encoded delimiter.`
383
316
  );
384
317
  }
385
- if (ENCODED_NULL_PATTERN.test(entry)) {
318
+ if (NULL_BYTE_RE.test(entry)) {
386
319
  throw new Error(
387
- `Build error: directory name contains an encoded null byte (%%00).\n` +
320
+ `Build error: directory name contains an encoded null byte (%00).\n` +
388
321
  ` Directory: ${fullPath}\n` +
389
322
  `Encoded null bytes in directory names are not allowed. ` +
390
323
  `Rename the directory to remove the null byte encoding.`
@@ -412,10 +345,10 @@ function scanChildren(dirPath: string, parentNode: SegmentNode, extSet: Set<stri
412
345
  // Recurse into subdirectories
413
346
  scanChildren(fullPath, childNode, extSet);
414
347
 
415
- // Attach to parent: slots go into slots map, everything else is a child
348
+ // Attach to parent: slots go into slots record, everything else is a child
416
349
  if (type === 'slot') {
417
350
  const slotName = entry.slice(1); // remove @
418
- parentNode.slots.set(slotName, childNode);
351
+ parentNode.slots[slotName] = childNode;
419
352
  } else {
420
353
  parentNode.children.push(childNode);
421
354
  }
@@ -428,57 +361,162 @@ function scanChildren(dirPath: string, parentNode: SegmentNode, extSet: Set<stri
428
361
  * Two route groups like (auth)/login/page.tsx and (marketing)/login/page.tsx both claim
429
362
  * /login — the scanner must detect and reject this at build time.
430
363
  *
431
- * Parallel slots are excluded from collision detection — they intentionally coexist at
432
- * the same URL path as their parent (that's the whole point of parallel routes).
364
+ * Each parallel slot is validated as its OWN collision space: a slot's pages
365
+ * intentionally share URL paths with the parent tree (that's the point of
366
+ * parallel routes), but two route groups INSIDE one slot claiming the same
367
+ * URL — e.g. @side/(a)/x/page.tsx + @side/(b)/x/page.tsx — still collide.
433
368
  */
434
369
  function validateRouteGroupCollisions(root: SegmentNode): void {
435
370
  // Map from urlPath → { filePath, source } for the first page/route seen at that path
436
- const seen = new Map<string, { filePath: string; segmentPath: string }>();
437
- collectRoutableLeaves(root, seen, '', false);
371
+ collectRoutableLeaves(root, new Map(), '');
438
372
  }
439
373
 
440
374
  /**
441
375
  * Walk the segment tree and collect all routable leaves (page or route files),
442
- * throwing on collision. Slots are tracked in their own collision space since
443
- * they are parallel routes that intentionally share URL paths with their parent.
376
+ * throwing on collision. Each slot recurses with a FRESH collision map —
377
+ * slots are parallel routes that intentionally share URL paths with their
378
+ * parent tree, but collisions within a single slot are real errors.
444
379
  */
445
380
  function collectRoutableLeaves(
446
381
  node: SegmentNode,
447
382
  seen: Map<string, { filePath: string; segmentPath: string }>,
448
- segmentPath: string,
449
- insideSlot: boolean
383
+ segmentPath: string
450
384
  ): void {
385
+ // Intercepting routes are resolved by the slot resolver, not URL matching,
386
+ // and their computed urlPaths intentionally mirror other routes (e.g. two
387
+ // interceptors in one slot both produce /gallery/[id]). Skip them entirely.
388
+ if (node.segmentType === 'intercepting') return;
389
+
451
390
  const currentPath = segmentPath
452
391
  ? `${segmentPath}/${node.segmentName}`
453
392
  : node.segmentName || '(root)';
454
393
 
455
- // Only check collisions for non-slot pages — slots intentionally share URL paths
456
- if (!insideSlot) {
457
- const routableFile = node.page ?? node.route;
458
- if (routableFile) {
459
- const existing = seen.get(node.urlPath);
460
- if (existing) {
461
- throw new Error(
462
- `Build error: route collision — multiple route groups produce a page/route at the same URL path.\n` +
463
- ` URL path: ${node.urlPath}\n` +
464
- ` File 1: ${existing.filePath} (via ${existing.segmentPath})\n` +
465
- ` File 2: ${routableFile.filePath} (via ${currentPath})\n` +
466
- `Each URL path must map to exactly one page or route handler. ` +
467
- `Rename or move one of the conflicting files.`
468
- );
469
- }
470
- seen.set(node.urlPath, { filePath: routableFile.filePath, segmentPath: currentPath });
394
+ const routableFile = node.page ?? node.route;
395
+ if (routableFile) {
396
+ const existing = seen.get(node.urlPath);
397
+ if (existing) {
398
+ throw new Error(
399
+ `Build error: route collision — multiple route groups produce a page/route at the same URL path.\n` +
400
+ ` URL path: ${node.urlPath}\n` +
401
+ ` File 1: ${existing.filePath} (via ${existing.segmentPath})\n` +
402
+ ` File 2: ${routableFile.filePath} (via ${currentPath})\n` +
403
+ `Each URL path must map to exactly one page or route handler. ` +
404
+ `Rename or move one of the conflicting files.`
405
+ );
471
406
  }
407
+ seen.set(node.urlPath, { filePath: routableFile.filePath, segmentPath: currentPath });
472
408
  }
473
409
 
474
410
  // Recurse into children
475
411
  for (const child of node.children) {
476
- collectRoutableLeaves(child, seen, currentPath, insideSlot);
412
+ collectRoutableLeaves(child, seen, currentPath);
477
413
  }
478
414
 
479
- // Recurse into slots — each slot is its own parallel route space
480
- for (const [, slotNode] of node.slots) {
481
- collectRoutableLeaves(slotNode, seen, currentPath, true);
415
+ // Recurse into slots — each slot gets a fresh map (its own collision space)
416
+ for (const slotNode of Object.values(node.slots)) {
417
+ collectRoutableLeaves(slotNode, new Map(), currentPath);
418
+ }
419
+ }
420
+
421
+ /**
422
+ * Validate that no route chain contains duplicate dynamic param names.
423
+ *
424
+ * Example violation:
425
+ * app/[id]/items/[id]/page.tsx — 'id' appears twice in the ancestor chain.
426
+ *
427
+ * Route groups are transparent — params accumulate through them.
428
+ * Slots are independent — duplicate detection does NOT cross slot boundaries.
429
+ *
430
+ * See design/07-routing.md §"Duplicate Param Name Detection"
431
+ */
432
+ function validateDuplicateParamNames(root: SegmentNode): void {
433
+ walkForDuplicateParams(root, new Map());
434
+ }
435
+
436
+ /**
437
+ * Recursively walk the segment tree, tracking seen param names → segment paths.
438
+ * Throws on the first duplicate found.
439
+ */
440
+ function walkForDuplicateParams(node: SegmentNode, seen: Map<string, string>): void {
441
+ // If this node introduces a param name, check for duplicates
442
+ if (node.paramName) {
443
+ const existing = seen.get(node.paramName);
444
+ if (existing) {
445
+ throw new Error(
446
+ `[timber] Duplicate param name '${node.paramName}' in route chain.\n` +
447
+ ` First defined at: ${existing}\n` +
448
+ ` Duplicate at: ${node.urlPath || '/'}\n` +
449
+ ` Rename one of the segments to avoid ambiguity.`
450
+ );
451
+ }
452
+ // Add to seen for descendants (use a new Map to avoid polluting siblings)
453
+ seen = new Map(seen);
454
+ seen.set(node.paramName, node.urlPath || '/');
455
+ }
456
+
457
+ // Recurse into children (they inherit the accumulated params)
458
+ for (const child of node.children) {
459
+ walkForDuplicateParams(child, seen);
460
+ }
461
+
462
+ // Slots are independent parallel routes — start fresh param tracking
463
+ // (a slot's params don't conflict with the main route's params)
464
+ for (const slotNode of Object.values(node.slots)) {
465
+ walkForDuplicateParams(slotNode, new Map(seen));
466
+ }
467
+ }
468
+
469
+ /**
470
+ * Validate that each param name uses a single bracket form across the entire route tree.
471
+ *
472
+ * Different bracket forms produce different types:
473
+ * [id] → string
474
+ * [...id] → string[]
475
+ * [[...id]] → string[] | undefined
476
+ *
477
+ * If the same param name appears with multiple forms, the no-argument
478
+ * getSegmentParams() / useSegmentParams() return type becomes ambiguous.
479
+ *
480
+ * Same name + same form across different routes is fine and expected.
481
+ */
482
+ function validateUniqueBracketForms(root: SegmentNode): void {
483
+ const forms = new Map<string, { segmentType: SegmentType; urlPath: string }>();
484
+ collectBracketForms(root, forms);
485
+ }
486
+
487
+ function collectBracketForms(
488
+ node: SegmentNode,
489
+ forms: Map<string, { segmentType: SegmentType; urlPath: string }>
490
+ ): void {
491
+ if (node.paramName && node.segmentType !== 'static' && node.segmentType !== 'group') {
492
+ const existing = forms.get(node.paramName);
493
+ if (existing && existing.segmentType !== node.segmentType) {
494
+ const bracketExamples: Record<string, string> = {
495
+ 'dynamic': `[${node.paramName}]`,
496
+ 'catch-all': `[...${node.paramName}]`,
497
+ 'optional-catch-all': `[[...${node.paramName}]]`,
498
+ };
499
+ throw new Error(
500
+ `[timber] Param name '${node.paramName}' uses multiple bracket forms.\n` +
501
+ ` ${bracketExamples[existing.segmentType] ?? existing.segmentType} at: ${existing.urlPath}\n` +
502
+ ` ${bracketExamples[node.segmentType] ?? node.segmentType} at: ${node.urlPath || '/'}\n` +
503
+ ` Each param name must use a single bracket form across all routes.\n` +
504
+ ` Rename one of the segments to fix this (e.g., [${node.paramName}] → [${node.paramName}Id]).`
505
+ );
506
+ }
507
+ if (!existing) {
508
+ forms.set(node.paramName, {
509
+ segmentType: node.segmentType,
510
+ urlPath: node.urlPath || '/',
511
+ });
512
+ }
513
+ }
514
+
515
+ for (const child of node.children) {
516
+ collectBracketForms(child, forms);
517
+ }
518
+ for (const slotNode of Object.values(node.slots)) {
519
+ collectBracketForms(slotNode, forms);
482
520
  }
483
521
  }
484
522
 
@@ -498,3 +536,25 @@ function findFixedFile(dirPath: string, name: string): RouteFile | undefined {
498
536
  }
499
537
  return undefined;
500
538
  }
539
+
540
+ /**
541
+ * Find a file using the configured page extensions (tsx, ts, jsx, js, mdx, etc.).
542
+ * Used for app-root conventions like global-error that aren't per-segment.
543
+ */
544
+ function findPageExtFile(
545
+ dirPath: string,
546
+ name: string,
547
+ extSet: Set<string>
548
+ ): RouteFile | undefined {
549
+ for (const ext of extSet) {
550
+ const fullPath = join(dirPath, `${name}.${ext}`);
551
+ try {
552
+ if (statSync(fullPath).isFile()) {
553
+ return { filePath: fullPath, extension: ext };
554
+ }
555
+ } catch {
556
+ // File doesn't exist
557
+ }
558
+ }
559
+ return undefined;
560
+ }