@timber-js/app 0.2.0-alpha.192 → 0.2.0-alpha.195

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 (678) hide show
  1. package/agent-skill.md +2 -0
  2. package/dist/_chunks/{actions-BjbbNRFN.js → actions-CWYtq6ii.js} +3 -3
  3. package/dist/_chunks/actions-CWYtq6ii.js.map +1 -0
  4. package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -1
  5. package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -1
  6. package/dist/_chunks/{build-output-helper-C3DrfzZR.js → build-output-helper-9dqCv1pZ.js} +3 -2
  7. package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +1 -0
  8. package/dist/_chunks/{cache-api-DllJ-Lyw.js → cache-api-CQeYzA5g.js} +6 -8
  9. package/dist/_chunks/cache-api-CQeYzA5g.js.map +1 -0
  10. package/dist/_chunks/chains-h7EO-u3n.js +412 -0
  11. package/dist/_chunks/chains-h7EO-u3n.js.map +1 -0
  12. package/dist/_chunks/{cli-check-DJZDc22E.js → cli-check-BVthpfLS.js} +43 -6
  13. package/dist/_chunks/cli-check-BVthpfLS.js.map +1 -0
  14. package/dist/_chunks/{cli-schema-sync-D4_AZVUb.js → cli-schema-sync-3Wutm8pH.js} +7 -6
  15. package/dist/_chunks/{cli-schema-sync-D4_AZVUb.js.map → cli-schema-sync-3Wutm8pH.js.map} +1 -1
  16. package/dist/_chunks/{cloudflare-CGP6BZKO.js → cloudflare-BKJC3SC_.js} +28 -22
  17. package/dist/_chunks/{cloudflare-CGP6BZKO.js.map → cloudflare-BKJC3SC_.js.map} +1 -1
  18. package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -1
  19. package/dist/_chunks/{convention-lint-CpteIpTm.js → convention-lint-DO10_pVl.js} +93 -7
  20. package/dist/_chunks/convention-lint-DO10_pVl.js.map +1 -0
  21. package/dist/_chunks/dist-DtrJyBbw.js +386 -0
  22. package/dist/_chunks/dist-DtrJyBbw.js.map +1 -0
  23. package/dist/_chunks/{error-boundary-D-ODYX41.js → error-boundary-D-lkwyaD.js} +3 -3
  24. package/dist/_chunks/{error-boundary-D-ODYX41.js.map → error-boundary-D-lkwyaD.js.map} +1 -1
  25. package/dist/_chunks/{file-cache-DmX7OqZP.js → file-cache-Dw6BJPG7.js} +5 -1
  26. package/dist/_chunks/{file-cache-DmX7OqZP.js.map → file-cache-Dw6BJPG7.js.map} +1 -1
  27. package/dist/_chunks/{format-CfwjgPz9.js → format-BKclgVbk.js} +3 -3
  28. package/dist/_chunks/{format-CfwjgPz9.js.map → format-BKclgVbk.js.map} +1 -1
  29. package/dist/_chunks/graph-cache-CP4GEmf9.js +304 -0
  30. package/dist/_chunks/graph-cache-CP4GEmf9.js.map +1 -0
  31. package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -1
  32. package/dist/_chunks/live-graph-Bx4HodF1.js +150 -0
  33. package/dist/_chunks/live-graph-Bx4HodF1.js.map +1 -0
  34. package/dist/_chunks/{logger-CH7IcMmg.js → logger-pumCm3Il.js} +25 -7
  35. package/dist/_chunks/{logger-CH7IcMmg.js.map → logger-pumCm3Il.js.map} +1 -1
  36. package/dist/_chunks/{mdx-file-C005ay-P.js → mdx-file-CXyHGUpS.js} +3 -3
  37. package/dist/_chunks/mdx-file-CXyHGUpS.js.map +1 -0
  38. package/dist/_chunks/{plugin-context-rCinWLiE.js → plugin-context-8idfR3UZ.js} +2 -2
  39. package/dist/_chunks/plugin-context-8idfR3UZ.js.map +1 -0
  40. package/dist/_chunks/poison-rules-DoEhbqaY.js +110 -0
  41. package/dist/_chunks/poison-rules-DoEhbqaY.js.map +1 -0
  42. package/dist/_chunks/poison-scan-BAxfTT5L.js +101 -0
  43. package/dist/_chunks/poison-scan-BAxfTT5L.js.map +1 -0
  44. package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -1
  45. package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
  46. package/dist/_chunks/{router-ref-DuYuV_0Q.js → router-ref-BzqbPwYC.js} +2 -2
  47. package/dist/_chunks/{router-ref-DuYuV_0Q.js.map → router-ref-BzqbPwYC.js.map} +1 -1
  48. package/dist/_chunks/{rsc-media-type-DRqE_lD_.js → rsc-media-type-DDc7duTD.js} +17 -2
  49. package/dist/_chunks/{rsc-media-type-DRqE_lD_.js.map → rsc-media-type-DDc7duTD.js.map} +1 -1
  50. package/dist/_chunks/scan-BoP17W3w.js +140 -0
  51. package/dist/_chunks/scan-BoP17W3w.js.map +1 -0
  52. package/dist/_chunks/{scanner-CAietmj4.js → scanner-BRIOmHE2.js} +43 -4
  53. package/dist/_chunks/scanner-BRIOmHE2.js.map +1 -0
  54. package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -1
  55. package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -1
  56. package/dist/_chunks/{segment-keys-BawYuNFO.js → segment-keys-BhqoHiLc.js} +14 -2
  57. package/dist/_chunks/{segment-keys-BawYuNFO.js.map → segment-keys-BhqoHiLc.js.map} +1 -1
  58. package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -1
  59. package/dist/_chunks/{ssr-data-14MXm7Pj.js → ssr-data-Ya2HJPFp.js} +1 -7
  60. package/dist/_chunks/{ssr-data-14MXm7Pj.js.map → ssr-data-Ya2HJPFp.js.map} +1 -1
  61. package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -1
  62. package/dist/_chunks/{use-segment-params-C4r4BD9T.js → use-segment-params-DzTBpkvj.js} +3 -3
  63. package/dist/_chunks/use-segment-params-DzTBpkvj.js.map +1 -0
  64. package/dist/_chunks/{walkers-BsVLmD1S.js → walkers-BU6z9xRV.js} +9 -6
  65. package/dist/_chunks/{walkers-BsVLmD1S.js.map → walkers-BU6z9xRV.js.map} +1 -1
  66. package/dist/adapters/build-output-helper.d.ts +1 -1
  67. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  68. package/dist/adapters/cloudflare-dev.d.ts.map +1 -1
  69. package/dist/adapters/cloudflare-dev.js +2 -1
  70. package/dist/adapters/cloudflare-dev.js.map +1 -1
  71. package/dist/adapters/cloudflare-kv-cache.d.ts +1 -1
  72. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -1
  73. package/dist/adapters/cloudflare-kv-cache.js +7 -8
  74. package/dist/adapters/cloudflare-kv-cache.js.map +1 -1
  75. package/dist/adapters/cloudflare.d.ts +1 -1
  76. package/dist/adapters/cloudflare.d.ts.map +1 -1
  77. package/dist/adapters/cloudflare.js +1 -1
  78. package/dist/adapters/nitro-presets.d.ts +37 -0
  79. package/dist/adapters/nitro-presets.d.ts.map +1 -0
  80. package/dist/adapters/nitro-preview.d.ts +32 -0
  81. package/dist/adapters/nitro-preview.d.ts.map +1 -0
  82. package/dist/adapters/nitro.d.ts +28 -51
  83. package/dist/adapters/nitro.d.ts.map +1 -1
  84. package/dist/adapters/nitro.js +224 -171
  85. package/dist/adapters/nitro.js.map +1 -1
  86. package/dist/analyze/chains.d.ts +124 -0
  87. package/dist/analyze/chains.d.ts.map +1 -0
  88. package/dist/analyze/classify.d.ts +150 -0
  89. package/dist/analyze/classify.d.ts.map +1 -0
  90. package/dist/analyze/crawl-entry.d.ts +17 -0
  91. package/dist/analyze/crawl-entry.d.ts.map +1 -0
  92. package/dist/analyze/crawl-entry.js +313 -0
  93. package/dist/analyze/crawl-entry.js.map +1 -0
  94. package/dist/analyze/crawl.d.ts +134 -0
  95. package/dist/analyze/crawl.d.ts.map +1 -0
  96. package/dist/analyze/graph-cache.d.ts +104 -0
  97. package/dist/analyze/graph-cache.d.ts.map +1 -0
  98. package/dist/analyze/graph-command.d.ts +43 -0
  99. package/dist/analyze/graph-command.d.ts.map +1 -0
  100. package/dist/analyze/graph-command.js +472 -0
  101. package/dist/analyze/graph-command.js.map +1 -0
  102. package/dist/analyze/live-graph.d.ts +81 -0
  103. package/dist/analyze/live-graph.d.ts.map +1 -0
  104. package/dist/analyze/poison-rules.d.ts +72 -0
  105. package/dist/analyze/poison-rules.d.ts.map +1 -0
  106. package/dist/analyze/poison-scan.d.ts +48 -0
  107. package/dist/analyze/poison-scan.d.ts.map +1 -0
  108. package/dist/analyze/scan.d.ts +73 -0
  109. package/dist/analyze/scan.d.ts.map +1 -0
  110. package/dist/cache/cache-api.d.ts +2 -2
  111. package/dist/cache/cache-api.d.ts.map +1 -1
  112. package/dist/cache/index.d.ts +8 -8
  113. package/dist/cache/index.d.ts.map +1 -1
  114. package/dist/cache/index.js +1 -1
  115. package/dist/cache/redis-handler.d.ts +1 -1
  116. package/dist/cache/redis-handler.d.ts.map +1 -1
  117. package/dist/cache/stores/cloudflare-kv.d.ts +1 -1
  118. package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -1
  119. package/dist/cache/stores/cloudflare-kv.js.map +1 -1
  120. package/dist/cache/stores/memory.d.ts +1 -1
  121. package/dist/cache/stores/memory.d.ts.map +1 -1
  122. package/dist/cache/stores/memory.js.map +1 -1
  123. package/dist/cache/stores/redis.d.ts +1 -1
  124. package/dist/cache/stores/redis.d.ts.map +1 -1
  125. package/dist/cache/stores/redis.js.map +1 -1
  126. package/dist/cache/stores/vercel.d.ts +1 -1
  127. package/dist/cache/stores/vercel.d.ts.map +1 -1
  128. package/dist/cache/stores/vercel.js.map +1 -1
  129. package/dist/cache/tag-aware-handler.d.ts +2 -2
  130. package/dist/cache/tag-aware-handler.d.ts.map +1 -1
  131. package/dist/cache/timber-cache.d.ts +1 -1
  132. package/dist/cache/timber-cache.d.ts.map +1 -1
  133. package/dist/cdn/cloudflare-purge.d.ts +1 -1
  134. package/dist/cdn/cloudflare-purge.d.ts.map +1 -1
  135. package/dist/cdn/cloudflare-purge.js.map +1 -1
  136. package/dist/cdn/fastly-purge.d.ts +1 -1
  137. package/dist/cdn/fastly-purge.d.ts.map +1 -1
  138. package/dist/cdn/fastly-purge.js.map +1 -1
  139. package/dist/cdn/index.d.ts +4 -4
  140. package/dist/cdn/index.d.ts.map +1 -1
  141. package/dist/cdn/workers-cache-purge.d.ts +5 -1
  142. package/dist/cdn/workers-cache-purge.d.ts.map +1 -1
  143. package/dist/cdn/workers-cache-purge.js.map +1 -1
  144. package/dist/cli-check.d.ts +10 -0
  145. package/dist/cli-check.d.ts.map +1 -1
  146. package/dist/cli.d.ts +12 -4
  147. package/dist/cli.d.ts.map +1 -1
  148. package/dist/cli.js +30 -6
  149. package/dist/cli.js.map +1 -1
  150. package/dist/client/browser-entry/hydrate.d.ts +2 -2
  151. package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
  152. package/dist/client/browser-entry/post-hydration.d.ts +2 -2
  153. package/dist/client/browser-entry/router-init.d.ts +2 -2
  154. package/dist/client/browser-entry/rsc-stream.d.ts +1 -1
  155. package/dist/client/error-boundary.js +1 -1
  156. package/dist/client/form.d.ts +2 -2
  157. package/dist/client/form.d.ts.map +1 -1
  158. package/dist/client/history.d.ts +2 -2
  159. package/dist/client/index.d.ts +18 -18
  160. package/dist/client/index.d.ts.map +1 -1
  161. package/dist/client/index.js +3 -3
  162. package/dist/client/index.js.map +1 -1
  163. package/dist/client/internal.d.ts +19 -19
  164. package/dist/client/internal.d.ts.map +1 -1
  165. package/dist/client/internal.js +15 -19
  166. package/dist/client/internal.js.map +1 -1
  167. package/dist/client/link.d.ts +3 -3
  168. package/dist/client/navigation-commit.d.ts +5 -5
  169. package/dist/client/navigation-root.d.ts +1 -1
  170. package/dist/client/navigation-root.d.ts.map +1 -1
  171. package/dist/client/params-context.d.ts +3 -3
  172. package/dist/client/router-pipeline.d.ts +7 -7
  173. package/dist/client/router-ref.d.ts +1 -1
  174. package/dist/client/router-types.d.ts +6 -6
  175. package/dist/client/router-types.d.ts.map +1 -1
  176. package/dist/client/router.d.ts +1 -1
  177. package/dist/client/rsc-fetch.d.ts +4 -4
  178. package/dist/client/rsc-fetch.d.ts.map +1 -1
  179. package/dist/client/segment-cache.d.ts +2 -2
  180. package/dist/client/slot-provider.d.ts +1 -1
  181. package/dist/client/ssr-data.d.ts +2 -2
  182. package/dist/client/state.d.ts +4 -4
  183. package/dist/client/use-query-states.d.ts +1 -1
  184. package/dist/client/use-segment-params.d.ts +3 -3
  185. package/dist/codec.d.ts +2 -2
  186. package/dist/codec.js.map +1 -1
  187. package/dist/config-types.d.ts +12 -9
  188. package/dist/config-types.d.ts.map +1 -1
  189. package/dist/config-validation.d.ts +1 -1
  190. package/dist/cookies/define-cookie.d.ts +3 -3
  191. package/dist/cookies/index.d.ts +3 -3
  192. package/dist/cookies/index.js +4 -5
  193. package/dist/cookies/index.js.map +1 -1
  194. package/dist/cookies/json-cookie.d.ts +1 -1
  195. package/dist/dev-tools/404-page.d.ts +2 -2
  196. package/dist/dev-tools/error-page.d.ts +2 -2
  197. package/dist/dev-tools/index.d.ts +12 -12
  198. package/dist/dev-tools/instrumentation.d.ts +1 -1
  199. package/dist/dev-tools/logs.d.ts +1 -1
  200. package/dist/dev-tools/overlay.d.ts +2 -2
  201. package/dist/dev-tools/terminal.d.ts +1 -1
  202. package/dist/fonts/ast.d.ts +4 -4
  203. package/dist/fonts/bundle.d.ts +3 -3
  204. package/dist/fonts/css.d.ts +1 -1
  205. package/dist/fonts/dev-middleware.d.ts +1 -1
  206. package/dist/fonts/google.d.ts +1 -1
  207. package/dist/fonts/local.d.ts +1 -1
  208. package/dist/fonts/pipeline.d.ts +3 -3
  209. package/dist/fonts/transform.d.ts +2 -2
  210. package/dist/fonts/types.d.ts +1 -1
  211. package/dist/fonts/virtual-modules.d.ts +1 -1
  212. package/dist/index.d.ts +3 -18
  213. package/dist/index.d.ts.map +1 -1
  214. package/dist/index.js +861 -314
  215. package/dist/index.js.map +1 -1
  216. package/dist/params/codec-registry.d.ts +1 -1
  217. package/dist/params/define-schema.d.ts +2 -2
  218. package/dist/params/index.d.ts +4 -4
  219. package/dist/params/index.js.map +1 -1
  220. package/dist/params/resolve-schema.d.ts +1 -1
  221. package/dist/plugin-context.d.ts +9 -9
  222. package/dist/plugin-context.d.ts.map +1 -1
  223. package/dist/plugins/adapter-build.d.ts +2 -2
  224. package/dist/plugins/build-manifest.d.ts +2 -2
  225. package/dist/plugins/build-report.d.ts +5 -5
  226. package/dist/plugins/cache.d.ts +1 -1
  227. package/dist/plugins/callsite-jsx.d.ts +2 -2
  228. package/dist/plugins/chunks.d.ts +1 -1
  229. package/dist/plugins/chunks.d.ts.map +1 -1
  230. package/dist/plugins/cloudflare-wasm.d.ts +1 -1
  231. package/dist/plugins/content.d.ts +1 -1
  232. package/dist/plugins/content.d.ts.map +1 -1
  233. package/dist/plugins/dev-discovery.d.ts +123 -0
  234. package/dist/plugins/dev-discovery.d.ts.map +1 -0
  235. package/dist/plugins/dev-server.d.ts +1 -1
  236. package/dist/plugins/dev-server.d.ts.map +1 -1
  237. package/dist/plugins/entries.d.ts +1 -1
  238. package/dist/plugins/fonts.d.ts +3 -3
  239. package/dist/plugins/fonts.d.ts.map +1 -1
  240. package/dist/plugins/graph-endpoint.d.ts +112 -0
  241. package/dist/plugins/graph-endpoint.d.ts.map +1 -0
  242. package/dist/plugins/mdx.d.ts +1 -1
  243. package/dist/plugins/mdx.d.ts.map +1 -1
  244. package/dist/plugins/prebuilt-capture.d.ts +2 -2
  245. package/dist/plugins/prebuilt-options-analysis.d.ts +1 -1
  246. package/dist/plugins/prebuilt.d.ts +1 -1
  247. package/dist/plugins/prerender-sugar.d.ts +11 -14
  248. package/dist/plugins/prerender-sugar.d.ts.map +1 -1
  249. package/dist/plugins/request-dep/analysis.d.ts +1 -1
  250. package/dist/plugins/request-dep/index.d.ts +5 -5
  251. package/dist/plugins/request-dep/origin.d.ts +1 -1
  252. package/dist/plugins/routing.d.ts +1 -1
  253. package/dist/plugins/routing.d.ts.map +1 -1
  254. package/dist/plugins/server-bundle.d.ts.map +1 -1
  255. package/dist/plugins/shims.d.ts +1 -1
  256. package/dist/plugins/shims.d.ts.map +1 -1
  257. package/dist/plugins/static-build.d.ts +5 -5
  258. package/dist/routing/codegen-shared.d.ts +1 -1
  259. package/dist/routing/codegen-write.d.ts +1 -1
  260. package/dist/routing/codegen.d.ts +1 -1
  261. package/dist/routing/collision-probe.d.ts +1 -1
  262. package/dist/routing/collision-spaces.d.ts +1 -1
  263. package/dist/routing/convention-lint.d.ts +1 -1
  264. package/dist/routing/convention-lint.d.ts.map +1 -1
  265. package/dist/routing/index.d.ts +13 -13
  266. package/dist/routing/index.js +3 -3
  267. package/dist/routing/interception.d.ts +1 -1
  268. package/dist/routing/interception.d.ts.map +1 -1
  269. package/dist/routing/link-codegen.d.ts +1 -1
  270. package/dist/routing/manifest-codegen.d.ts +1 -1
  271. package/dist/routing/scanner.d.ts +14 -1
  272. package/dist/routing/scanner.d.ts.map +1 -1
  273. package/dist/routing/schema-validation.d.ts +1 -1
  274. package/dist/routing/segment-classify.d.ts +1 -1
  275. package/dist/routing/segment-codegen.d.ts +1 -1
  276. package/dist/routing/segment-keys.d.ts +1 -1
  277. package/dist/routing/slot-placement.d.ts +1 -1
  278. package/dist/routing/walkers.d.ts +1 -1
  279. package/dist/rsc-runtime/transforms.d.ts +13 -0
  280. package/dist/rsc-runtime/transforms.d.ts.map +1 -0
  281. package/dist/schema-bridge.d.ts +1 -1
  282. package/dist/search-params/define.d.ts +3 -3
  283. package/dist/search-params/index.d.ts +3 -3
  284. package/dist/search-params/index.js.map +1 -1
  285. package/dist/search-params/wrappers.d.ts +1 -1
  286. package/dist/server/access-gate.d.ts +1 -1
  287. package/dist/server/action-client.d.ts +1 -1
  288. package/dist/server/action-handler.d.ts +5 -5
  289. package/dist/server/actions.d.ts +2 -2
  290. package/dist/server/als-registry.d.ts +8 -8
  291. package/dist/server/asset-headers.d.ts +1 -1
  292. package/dist/server/chain-url-parts.d.ts +3 -3
  293. package/dist/server/children-interception.d.ts +2 -2
  294. package/dist/server/cookie-context.d.ts +1 -1
  295. package/dist/server/cookie-parsing.d.ts +2 -2
  296. package/dist/server/default-logger.d.ts +1 -1
  297. package/dist/server/deny-boundary.d.ts +2 -2
  298. package/dist/server/deny-renderer.d.ts +5 -5
  299. package/dist/server/early-hints.d.ts +1 -1
  300. package/dist/server/error-boundary-wrapper.d.ts +2 -4
  301. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  302. package/dist/server/fallback-error.d.ts +5 -5
  303. package/dist/server/flight-injection-state.d.ts +1 -1
  304. package/dist/server/form-flash.d.ts +1 -1
  305. package/dist/server/html-injector-core.d.ts +2 -2
  306. package/dist/server/html-injectors.d.ts +1 -1
  307. package/dist/server/index.d.ts +18 -18
  308. package/dist/server/index.d.ts.map +1 -1
  309. package/dist/server/index.js +34 -38
  310. package/dist/server/index.js.map +1 -1
  311. package/dist/server/instrumentation.d.ts +1 -1
  312. package/dist/server/internal.d.ts +50 -50
  313. package/dist/server/internal.d.ts.map +1 -1
  314. package/dist/server/internal.js +1024 -1026
  315. package/dist/server/internal.js.map +1 -1
  316. package/dist/server/metadata-collector.d.ts +2 -2
  317. package/dist/server/metadata-platform.d.ts +2 -2
  318. package/dist/server/metadata-render.d.ts +2 -2
  319. package/dist/server/metadata-routes.d.ts +3 -3
  320. package/dist/server/metadata-social.d.ts +2 -2
  321. package/dist/server/metadata.d.ts +2 -2
  322. package/dist/server/middleware-runner.d.ts +1 -1
  323. package/dist/server/node-stream-transforms.d.ts +1 -1
  324. package/dist/server/param-coercion.d.ts +4 -4
  325. package/dist/server/pipeline-helpers.d.ts +3 -3
  326. package/dist/server/pipeline-interception.d.ts +1 -1
  327. package/dist/server/pipeline-metadata.d.ts +1 -1
  328. package/dist/server/pipeline-outcome.d.ts +2 -2
  329. package/dist/server/pipeline-phases.d.ts +3 -3
  330. package/dist/server/pipeline-phases.d.ts.map +1 -1
  331. package/dist/server/pipeline.d.ts +9 -9
  332. package/dist/server/prebuilt/cache-key.d.ts +1 -1
  333. package/dist/server/prebuilt/capture-state.d.ts +1 -1
  334. package/dist/server/prebuilt/key-discipline.d.ts +1 -1
  335. package/dist/server/prebuilt/manifest-tag-index.d.ts +1 -1
  336. package/dist/server/prebuilt/overlay.d.ts +2 -2
  337. package/dist/server/prebuilt/payload-source.d.ts +1 -1
  338. package/dist/server/prebuilt/slots.d.ts +1 -1
  339. package/dist/server/prebuilt/synthetic-store.d.ts +2 -2
  340. package/dist/server/prebuilt-builder.d.ts +2 -2
  341. package/dist/server/primitives.d.ts +2 -2
  342. package/dist/server/publish-params.d.ts +1 -1
  343. package/dist/server/request-context.d.ts +3 -3
  344. package/dist/server/route-element-builder.d.ts +16 -6
  345. package/dist/server/route-element-builder.d.ts.map +1 -1
  346. package/dist/server/route-handler.d.ts +1 -1
  347. package/dist/server/route-matcher.d.ts +4 -4
  348. package/dist/server/rsc-cache-key-guard.d.ts.map +1 -1
  349. package/dist/server/rsc-entry/action-middleware-runner.d.ts +2 -2
  350. package/dist/server/rsc-entry/api-handler.d.ts +1 -1
  351. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  352. package/dist/server/rsc-entry/deny-fallback.d.ts +3 -3
  353. package/dist/server/rsc-entry/error-renderer.d.ts +4 -4
  354. package/dist/server/rsc-entry/helpers.d.ts +6 -6
  355. package/dist/server/rsc-entry/index.d.ts +7 -6
  356. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  357. package/dist/server/rsc-entry/render-route.d.ts +4 -4
  358. package/dist/server/rsc-entry/revalidate-renderer.d.ts +4 -4
  359. package/dist/server/rsc-entry/rsc-payload.d.ts +4 -4
  360. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  361. package/dist/server/rsc-entry/rsc-stream.d.ts +3 -3
  362. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  363. package/dist/server/rsc-entry/ssr-renderer.d.ts +7 -7
  364. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +5 -5
  365. package/dist/server/sitemap-generator.d.ts +2 -2
  366. package/dist/server/sitemap-handler.d.ts +1 -1
  367. package/dist/server/skippable-prefix.d.ts +3 -3
  368. package/dist/server/slot-interception.d.ts +2 -2
  369. package/dist/server/slot-resolver.d.ts +3 -7
  370. package/dist/server/slot-resolver.d.ts.map +1 -1
  371. package/dist/server/ssr-bridge-types.d.ts +2 -2
  372. package/dist/server/ssr-entry.d.ts +1 -1
  373. package/dist/server/static-generator.d.ts +1 -1
  374. package/dist/server/static-not-found.d.ts +1 -1
  375. package/dist/server/status-code-resolver.d.ts +1 -1
  376. package/dist/server/tracing.d.ts +3 -3
  377. package/dist/server/tree-builder.d.ts +3 -3
  378. package/dist/server/tree-match.d.ts +1 -1
  379. package/dist/server/types.d.ts +2 -2
  380. package/dist/server/utils/mdx-file.d.ts +2 -0
  381. package/dist/server/utils/mdx-file.d.ts.map +1 -1
  382. package/dist/server/workers-cache-bridge.d.ts +1 -1
  383. package/dist/shared/als-slots.d.ts +1 -1
  384. package/dist/shared/payload-root.d.ts +2 -2
  385. package/dist/shared/rsc-media-type.d.ts +12 -0
  386. package/dist/shared/rsc-media-type.d.ts.map +1 -1
  387. package/dist/shared/slot-params.d.ts +1 -1
  388. package/dist/shims/font-google.d.ts +1 -1
  389. package/dist/shims/font-google.js.map +1 -1
  390. package/dist/shims/font-local.d.ts +1 -1
  391. package/dist/shims/font-local.js.map +1 -1
  392. package/dist/shims/navigation-client.d.ts +4 -4
  393. package/dist/shims/navigation.d.ts +2 -2
  394. package/docs/api/34-api-config.mdx +7 -4
  395. package/docs/api/36-cli.mdx +23 -3
  396. package/docs/learn/11-error-handling.mdx +11 -0
  397. package/docs/learn/13-configuration.mdx +1 -1
  398. package/docs/more/01-advanced-routing.mdx +1 -0
  399. package/package.json +11 -10
  400. package/src/adapters/build-output-helper.ts +4 -4
  401. package/src/adapters/cloudflare-dev.ts +7 -1
  402. package/src/adapters/cloudflare-kv-cache.ts +11 -8
  403. package/src/adapters/cloudflare.ts +21 -15
  404. package/src/adapters/compress-module.ts +2 -2
  405. package/src/adapters/nitro-presets.ts +139 -0
  406. package/src/adapters/nitro-preview.ts +340 -0
  407. package/src/adapters/nitro.ts +100 -465
  408. package/src/adapters/shared.ts +1 -1
  409. package/src/analyze/chains.ts +411 -0
  410. package/src/analyze/classify.ts +258 -0
  411. package/src/analyze/crawl-entry.ts +68 -0
  412. package/src/analyze/crawl.ts +500 -0
  413. package/src/analyze/graph-cache.ts +332 -0
  414. package/src/analyze/graph-command.ts +762 -0
  415. package/src/analyze/live-graph.ts +232 -0
  416. package/src/analyze/poison-rules.ts +165 -0
  417. package/src/analyze/poison-scan.ts +162 -0
  418. package/src/analyze/scan.ts +149 -0
  419. package/src/cache/cache-api.ts +7 -7
  420. package/src/cache/index.ts +9 -9
  421. package/src/cache/redis-handler.ts +2 -2
  422. package/src/cache/stores/cloudflare-kv.ts +1 -1
  423. package/src/cache/stores/memory.ts +2 -2
  424. package/src/cache/stores/redis.ts +1 -1
  425. package/src/cache/stores/vercel.ts +1 -1
  426. package/src/cache/tag-aware-handler.ts +2 -2
  427. package/src/cache/timber-cache.ts +8 -8
  428. package/src/cdn/cloudflare-purge.ts +1 -1
  429. package/src/cdn/fastly-purge.ts +1 -1
  430. package/src/cdn/index.ts +10 -4
  431. package/src/cdn/workers-cache-purge.ts +6 -2
  432. package/src/cli-check.ts +53 -4
  433. package/src/cli-schema-sync.ts +3 -3
  434. package/src/cli.ts +50 -11
  435. package/src/client/browser-dev.ts +1 -1
  436. package/src/client/browser-entry/action-dispatch.ts +5 -5
  437. package/src/client/browser-entry/hmr.ts +1 -1
  438. package/src/client/browser-entry/hydrate.ts +9 -9
  439. package/src/client/browser-entry/index.ts +10 -10
  440. package/src/client/browser-entry/post-hydration.ts +5 -5
  441. package/src/client/browser-entry/router-init.ts +9 -9
  442. package/src/client/browser-entry/rsc-stream.ts +3 -3
  443. package/src/client/error-boundary.tsx +4 -4
  444. package/src/client/form.tsx +7 -2
  445. package/src/client/history.ts +2 -2
  446. package/src/client/index.ts +21 -18
  447. package/src/client/internal.ts +19 -19
  448. package/src/client/link.tsx +9 -9
  449. package/src/client/navigation-api.ts +1 -1
  450. package/src/client/navigation-commit.ts +5 -5
  451. package/src/client/navigation-context.ts +1 -1
  452. package/src/client/navigation-root.tsx +1 -1
  453. package/src/client/nuqs-adapter.tsx +2 -2
  454. package/src/client/params-context.ts +4 -4
  455. package/src/client/router-effects.ts +3 -3
  456. package/src/client/router-lifecycle.ts +2 -2
  457. package/src/client/router-pipeline.ts +10 -10
  458. package/src/client/router-ref.ts +2 -2
  459. package/src/client/router-skew.ts +2 -2
  460. package/src/client/router-types.ts +6 -6
  461. package/src/client/router.ts +13 -13
  462. package/src/client/rsc-fetch.ts +11 -16
  463. package/src/client/segment-cache.ts +2 -2
  464. package/src/client/segment-outlet.tsx +1 -1
  465. package/src/client/shallow-url.ts +1 -1
  466. package/src/client/slot-outlet.tsx +1 -1
  467. package/src/client/slot-provider.tsx +1 -1
  468. package/src/client/ssr-data.ts +3 -3
  469. package/src/client/stale-client.ts +1 -1
  470. package/src/client/state.ts +4 -4
  471. package/src/client/top-loader.tsx +1 -1
  472. package/src/client/unload-guard.ts +1 -1
  473. package/src/client/use-cookie.ts +2 -2
  474. package/src/client/use-pathname.ts +2 -2
  475. package/src/client/use-pending-navigation.ts +1 -1
  476. package/src/client/use-query-states.ts +3 -3
  477. package/src/client/use-router.ts +2 -2
  478. package/src/client/use-search-params.ts +3 -3
  479. package/src/client/use-segment-params.ts +6 -6
  480. package/src/client/use-selected-layout-segment.ts +2 -2
  481. package/src/codec.ts +2 -2
  482. package/src/config-types.ts +12 -9
  483. package/src/config-validation.ts +1 -1
  484. package/src/cookies/define-cookie.ts +6 -6
  485. package/src/cookies/index.ts +3 -3
  486. package/src/cookies/json-cookie.ts +1 -1
  487. package/src/dev-tools/404-page.ts +4 -4
  488. package/src/dev-tools/dev-page-shell.ts +1 -1
  489. package/src/dev-tools/error-page.ts +4 -4
  490. package/src/dev-tools/index.ts +12 -12
  491. package/src/dev-tools/instrumentation.ts +1 -1
  492. package/src/dev-tools/logs.ts +1 -1
  493. package/src/dev-tools/overlay.ts +3 -3
  494. package/src/dev-tools/terminal.ts +2 -2
  495. package/src/fonts/ast.ts +5 -5
  496. package/src/fonts/bundle.ts +5 -5
  497. package/src/fonts/css.ts +1 -1
  498. package/src/fonts/dev-middleware.ts +2 -2
  499. package/src/fonts/google.ts +2 -2
  500. package/src/fonts/local.ts +4 -4
  501. package/src/fonts/pipeline.ts +8 -8
  502. package/src/fonts/transform.ts +5 -5
  503. package/src/fonts/types.ts +1 -1
  504. package/src/fonts/virtual-modules.ts +1 -1
  505. package/src/index.ts +90 -95
  506. package/src/params/codec-registry.ts +1 -1
  507. package/src/params/define-schema.ts +2 -2
  508. package/src/params/index.ts +4 -4
  509. package/src/params/resolve-schema.ts +2 -2
  510. package/src/plugin-context.ts +10 -10
  511. package/src/plugins/adapter-build.ts +5 -5
  512. package/src/plugins/build-manifest.ts +4 -4
  513. package/src/plugins/build-report.ts +6 -6
  514. package/src/plugins/cache.ts +3 -3
  515. package/src/plugins/callsite-ast.ts +1 -1
  516. package/src/plugins/callsite-jsx.ts +2 -2
  517. package/src/plugins/chunks.ts +1 -1
  518. package/src/plugins/cloudflare-wasm.ts +1 -1
  519. package/src/plugins/content.ts +5 -1
  520. package/src/plugins/dev-discovery.ts +218 -0
  521. package/src/plugins/dev-server.ts +97 -12
  522. package/src/plugins/entries.ts +1 -1
  523. package/src/plugins/fonts.ts +17 -10
  524. package/src/plugins/graph-endpoint.ts +532 -0
  525. package/src/plugins/mdx.ts +4 -3
  526. package/src/plugins/prebuilt-capture.ts +3 -3
  527. package/src/plugins/prebuilt-options-analysis.ts +1 -1
  528. package/src/plugins/prebuilt.ts +7 -7
  529. package/src/plugins/prerender-sugar.ts +11 -19
  530. package/src/plugins/request-dep/analysis.ts +1 -1
  531. package/src/plugins/request-dep/index.ts +8 -8
  532. package/src/plugins/request-dep/origin.ts +1 -1
  533. package/src/plugins/routing.ts +12 -7
  534. package/src/plugins/server-bundle.ts +9 -2
  535. package/src/plugins/shims.ts +16 -31
  536. package/src/plugins/static-build.ts +10 -10
  537. package/src/routing/codegen-shared.ts +1 -1
  538. package/src/routing/codegen-write.ts +3 -3
  539. package/src/routing/codegen.ts +14 -5
  540. package/src/routing/collision-probe.ts +3 -3
  541. package/src/routing/collision-spaces.ts +3 -3
  542. package/src/routing/convention-lint.ts +136 -6
  543. package/src/routing/export-detect.ts +1 -1
  544. package/src/routing/index.ts +13 -13
  545. package/src/routing/interception.ts +41 -4
  546. package/src/routing/link-codegen.ts +3 -3
  547. package/src/routing/manifest-codegen.ts +2 -2
  548. package/src/routing/scanner.ts +33 -9
  549. package/src/routing/schema-validation.ts +4 -4
  550. package/src/routing/segment-classify.ts +2 -2
  551. package/src/routing/segment-codegen.ts +1 -1
  552. package/src/routing/segment-keys.ts +1 -1
  553. package/src/routing/slot-placement.ts +1 -1
  554. package/src/routing/walkers.ts +1 -1
  555. package/src/rsc-runtime/transforms.ts +13 -0
  556. package/src/rsc-runtime/vendor-types.d.ts +12 -0
  557. package/src/schema-bridge.ts +1 -1
  558. package/src/search-params/define.ts +8 -8
  559. package/src/search-params/index.ts +3 -3
  560. package/src/search-params/wrappers.ts +3 -3
  561. package/src/server/access-gate.tsx +6 -6
  562. package/src/server/action-client.ts +5 -5
  563. package/src/server/action-handler.ts +16 -16
  564. package/src/server/actions.ts +5 -5
  565. package/src/server/als-registry.ts +8 -8
  566. package/src/server/asset-headers.ts +2 -2
  567. package/src/server/chain-url-parts.ts +5 -5
  568. package/src/server/children-interception.ts +4 -4
  569. package/src/server/compress.ts +1 -1
  570. package/src/server/cookie-context.ts +4 -4
  571. package/src/server/cookie-parsing.ts +2 -2
  572. package/src/server/default-logger.ts +3 -3
  573. package/src/server/deny-boundary.ts +10 -10
  574. package/src/server/deny-renderer.ts +38 -25
  575. package/src/server/early-hints-sender.ts +2 -2
  576. package/src/server/early-hints.ts +2 -2
  577. package/src/server/error-boundary-wrapper.ts +4 -12
  578. package/src/server/fallback-error.ts +13 -13
  579. package/src/server/flight-injection-state.ts +1 -1
  580. package/src/server/form-flash.ts +2 -2
  581. package/src/server/html-injector-core.ts +4 -4
  582. package/src/server/html-injectors.ts +5 -5
  583. package/src/server/index.ts +18 -18
  584. package/src/server/instrumentation.ts +1 -1
  585. package/src/server/internal.ts +50 -50
  586. package/src/server/logger.ts +4 -4
  587. package/src/server/metadata-collector.ts +7 -7
  588. package/src/server/metadata-platform.ts +2 -2
  589. package/src/server/metadata-render.ts +4 -4
  590. package/src/server/metadata-routes.ts +3 -3
  591. package/src/server/metadata-social.ts +2 -2
  592. package/src/server/metadata.ts +2 -2
  593. package/src/server/middleware-runner.ts +1 -1
  594. package/src/server/node-stream-transforms.ts +4 -4
  595. package/src/server/param-coercion.ts +8 -8
  596. package/src/server/pipeline-helpers.ts +7 -7
  597. package/src/server/pipeline-interception.ts +2 -2
  598. package/src/server/pipeline-metadata.ts +1 -1
  599. package/src/server/pipeline-outcome.ts +8 -8
  600. package/src/server/pipeline-phases.ts +24 -28
  601. package/src/server/pipeline.ts +22 -22
  602. package/src/server/prebuilt/cache-key.ts +1 -1
  603. package/src/server/prebuilt/capture-state.ts +1 -1
  604. package/src/server/prebuilt/key-discipline.ts +1 -1
  605. package/src/server/prebuilt/manifest-tag-index.ts +1 -1
  606. package/src/server/prebuilt/overlay.ts +6 -6
  607. package/src/server/prebuilt/payload-source.ts +2 -2
  608. package/src/server/prebuilt/slots.ts +5 -5
  609. package/src/server/prebuilt/synthetic-store.ts +2 -2
  610. package/src/server/prebuilt-builder.ts +16 -16
  611. package/src/server/prebuilt-runtime.ts +12 -12
  612. package/src/server/primitives.ts +7 -7
  613. package/src/server/publish-params.ts +3 -3
  614. package/src/server/request-context.ts +7 -7
  615. package/src/server/route-element-builder.ts +108 -50
  616. package/src/server/route-handler.ts +4 -4
  617. package/src/server/route-matcher.ts +5 -5
  618. package/src/server/rsc-cache-key-guard.ts +3 -5
  619. package/src/server/rsc-entry/action-middleware-runner.ts +7 -7
  620. package/src/server/rsc-entry/api-handler.ts +18 -9
  621. package/src/server/rsc-entry/deny-fallback.ts +10 -10
  622. package/src/server/rsc-entry/error-renderer.ts +27 -27
  623. package/src/server/rsc-entry/helpers.ts +10 -10
  624. package/src/server/rsc-entry/index.ts +51 -47
  625. package/src/server/rsc-entry/render-route.ts +20 -20
  626. package/src/server/rsc-entry/revalidate-renderer.ts +12 -12
  627. package/src/server/rsc-entry/rsc-payload.ts +19 -15
  628. package/src/server/rsc-entry/rsc-stream.ts +8 -8
  629. package/src/server/rsc-entry/ssr-bridge.ts +3 -3
  630. package/src/server/rsc-entry/ssr-renderer.ts +23 -23
  631. package/src/server/rsc-entry/wrap-action-dispatch.ts +9 -9
  632. package/src/server/rsc-prop-warnings.ts +1 -1
  633. package/src/server/sensitive-fields.ts +1 -1
  634. package/src/server/server-timing.ts +1 -1
  635. package/src/server/sitemap-generator.ts +3 -3
  636. package/src/server/sitemap-handler.ts +3 -3
  637. package/src/server/skippable-prefix.ts +7 -7
  638. package/src/server/slot-interception.ts +5 -5
  639. package/src/server/slot-resolver.ts +20 -28
  640. package/src/server/ssr-bridge-types.ts +2 -2
  641. package/src/server/ssr-entry.ts +18 -18
  642. package/src/server/ssr-render.ts +4 -4
  643. package/src/server/ssr-wrappers.tsx +1 -1
  644. package/src/server/state-tree-diff.ts +1 -1
  645. package/src/server/static-generator.ts +6 -6
  646. package/src/server/static-not-found.ts +3 -3
  647. package/src/server/status-code-resolver.ts +1 -1
  648. package/src/server/tracing.ts +5 -5
  649. package/src/server/tree-builder.ts +4 -4
  650. package/src/server/tree-match.ts +1 -1
  651. package/src/server/types.ts +2 -2
  652. package/src/server/utils/mdx-file.ts +2 -2
  653. package/src/server/waituntil-bridge.ts +1 -1
  654. package/src/server/workers-cache-bridge.ts +2 -2
  655. package/src/shared/als-slots.ts +1 -1
  656. package/src/shared/payload-root.ts +2 -2
  657. package/src/shared/rsc-media-type.ts +16 -0
  658. package/src/shared/slot-params.ts +1 -1
  659. package/src/shims/font-google.ts +1 -1
  660. package/src/shims/font-local.ts +1 -1
  661. package/src/shims/navigation-client.ts +5 -5
  662. package/src/shims/navigation.ts +2 -2
  663. package/dist/_chunks/actions-BjbbNRFN.js.map +0 -1
  664. package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +0 -1
  665. package/dist/_chunks/cache-api-DllJ-Lyw.js.map +0 -1
  666. package/dist/_chunks/cli-check-DJZDc22E.js.map +0 -1
  667. package/dist/_chunks/convention-lint-CpteIpTm.js.map +0 -1
  668. package/dist/_chunks/dist-BA3u1z3W.js +0 -423
  669. package/dist/_chunks/dist-BA3u1z3W.js.map +0 -1
  670. package/dist/_chunks/mdx-file-C005ay-P.js.map +0 -1
  671. package/dist/_chunks/plugin-context-rCinWLiE.js.map +0 -1
  672. package/dist/_chunks/scanner-CAietmj4.js.map +0 -1
  673. package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +0 -1
  674. package/dist/content/index.d.ts +0 -2
  675. package/dist/content/index.d.ts.map +0 -1
  676. package/dist/content/index.js +0 -0
  677. package/src/content/index.ts +0 -5
  678. package/src/shims/server-only-noop.js +0 -6
@@ -23,7 +23,7 @@ import type {
23
23
  IdentifierNode,
24
24
  CallExpressionNode,
25
25
  MemberExpressionNode,
26
- } from '../callsite-ast.js';
26
+ } from '../callsite-ast.ts';
27
27
 
28
28
  /**
29
29
  * One module-graph edge introduced by an `import` or `export … from`.
@@ -24,14 +24,14 @@
24
24
  */
25
25
 
26
26
  import type { Plugin } from 'vite';
27
- import type { PluginContext } from '../../plugin-context.js';
28
- import type { ProgramNode } from '../callsite-ast.js';
29
- import { analyzeModule, usedSources, contributesNothing, type ModuleFacts } from './analysis.js';
30
- import { createOriginResolver, FRAMEWORK_SOURCES } from './origin.js';
31
-
32
- export type { ModuleFacts } from './analysis.js';
33
- export { analyzeModule, usedSources } from './analysis.js';
34
- export { createOriginResolver } from './origin.js';
27
+ import type { PluginContext } from '../../plugin-context.ts';
28
+ import type { ProgramNode } from '../callsite-ast.ts';
29
+ import { analyzeModule, usedSources, contributesNothing, type ModuleFacts } from './analysis.ts';
30
+ import { createOriginResolver, FRAMEWORK_SOURCES } from './origin.ts';
31
+
32
+ export type { ModuleFacts } from './analysis.ts';
33
+ export { analyzeModule, usedSources } from './analysis.ts';
34
+ export { createOriginResolver } from './origin.ts';
35
35
 
36
36
  // ─── Framework module detection ─────────────────────────────────────────
37
37
 
@@ -16,7 +16,7 @@
16
16
  * See design/19-client-navigation.md §"Why the slot comparison ignores the query".
17
17
  */
18
18
 
19
- import type { CalleeRef, ImportEdge, ModuleFacts } from './analysis.js';
19
+ import type { CalleeRef, ImportEdge, ModuleFacts } from './analysis.ts';
20
20
 
21
21
  // ─── What counts as a request accessor ───────────────────────────────────
22
22
 
@@ -10,17 +10,17 @@
10
10
 
11
11
  import type { Plugin, ViteDevServer } from 'vite';
12
12
  import { join } from 'node:path';
13
- import { scanRoutes } from '../routing/scanner.js';
14
- import { buildDirToRouteMap, type SegmentInfo } from '../routing/segment-codegen.js';
15
- import { writeRouteCodegen, flushCodegenWrites } from '../routing/codegen-write.js';
16
- import { validateSchemaAgainstRoutes } from '../routing/schema-validation.js';
17
- import { generateManifestModule, generateSchemaModule } from '../routing/manifest-codegen.js';
13
+ import { scanRoutes } from '../routing/scanner.ts';
14
+ import { buildDirToRouteMap, type SegmentInfo } from '../routing/segment-codegen.ts';
15
+ import { writeRouteCodegen, flushCodegenWrites } from '../routing/codegen-write.ts';
16
+ import { validateSchemaAgainstRoutes } from '../routing/schema-validation.ts';
17
+ import { generateManifestModule, generateSchemaModule } from '../routing/manifest-codegen.ts';
18
18
  import {
19
19
  lintConventions,
20
20
  checkAppDirExists,
21
21
  formatConventionWarnings,
22
- } from '../routing/convention-lint.js';
23
- import type { PluginContext } from '../plugin-context.js';
22
+ } from '../routing/convention-lint.ts';
23
+ import type { PluginContext } from '../plugin-context.ts';
24
24
 
25
25
  const VIRTUAL_MODULE_ID = 'virtual:timber-route-manifest';
26
26
  const RESOLVED_VIRTUAL_ID = `\0${VIRTUAL_MODULE_ID}`;
@@ -62,6 +62,11 @@ const ROUTE_FILE_PATTERNS =
62
62
  */
63
63
  function writeCodegen(ctx: PluginContext): void {
64
64
  if (!ctx.routeTree) return;
65
+ // The analyze crawl child only needs the route tree for
66
+ // classification — codegen writes are fire-and-forget and can be
67
+ // truncated by the child's process.exit, leaving partial .d.ts
68
+ // files on disk.
69
+ if (process.env.TIMBER_ANALYZE === '1') return;
65
70
  void writeRouteCodegen(ctx.routeTree, ctx.appDir, ctx.root).catch((err) => {
66
71
  console.warn('[timber] Failed to write codegen output:', err);
67
72
  });
@@ -13,6 +13,13 @@
13
13
 
14
14
  import { builtinModules } from 'node:module';
15
15
  import type { Plugin } from 'vite';
16
+ import { EXPLICIT_MARKERS } from '../analyze/poison-rules.ts';
17
+
18
+ // The poison-pill marker packages (server-only, client-only) must never be
19
+ // externalized — they have to reach the timber-shims resolveId hook so it
20
+ // can substitute the poison virtual modules. Derived from poison-rules.ts
21
+ // so the list cannot drift from what shims.ts intercepts.
22
+ const POISON_MARKER_SPECIFIERS = EXPLICIT_MARKERS.map((m) => m.specifier);
16
23
 
17
24
  // Every Node built-in as both bare (`stream`) and prefixed (`node:stream`).
18
25
  // Available at runtime on all targets (Node natively, Workers via nodejs_compat).
@@ -80,12 +87,12 @@ export function timberServerBundle(): Plugin[] {
80
87
  environments: {
81
88
  rsc: {
82
89
  resolve: {
83
- noExternal: ['server-only', 'client-only'],
90
+ noExternal: [...POISON_MARKER_SPECIFIERS],
84
91
  },
85
92
  },
86
93
  ssr: {
87
94
  resolve: {
88
- noExternal: ['server-only', 'client-only', 'nuqs'],
95
+ noExternal: [...POISON_MARKER_SPECIFIERS, 'nuqs'],
89
96
  },
90
97
  },
91
98
  },
@@ -17,7 +17,8 @@
17
17
  import type { Plugin } from 'vite';
18
18
  import { resolve, dirname } from 'node:path';
19
19
  import { fileURLToPath } from 'node:url';
20
- import type { PluginContext } from '../plugin-context.js';
20
+ import type { PluginContext } from '../plugin-context.ts';
21
+ import { EXPLICIT_MARKERS, markerFor, poisonPillSource } from '../analyze/poison-rules.ts';
21
22
 
22
23
  const __dirname = dirname(fileURLToPath(import.meta.url));
23
24
  // Detect whether we're running from source (src/plugins/) or dist (dist/).
@@ -30,14 +31,13 @@ const PKG_ROOT = __dirname.endsWith('plugins')
30
31
  const SHIMS_DIR = resolve(PKG_ROOT, 'src', 'shims');
31
32
 
32
33
  /**
33
- * Virtual module IDs for server-only and client-only poison pills.
34
- *
35
- * These packages cause build errors when imported in the wrong environment:
36
- * - `server-only` errors when imported in a client component
37
- * - `client-only` errors when imported in a server component
34
+ * The server-only marker's virtual ID, needed directly by the
35
+ * `#server-only-guard` resolution branch below. All poison-pill rules
36
+ * (specifiers, virtual IDs, error messages, environment policy) live in
37
+ * analyze/poison-rules.ts — the single source of truth shared with the
38
+ * `timber graph` reporter (design/47 §3).
38
39
  */
39
- const SERVER_ONLY_VIRTUAL = '\0timber:server-only';
40
- const CLIENT_ONLY_VIRTUAL = '\0timber:client-only';
40
+ const SERVER_ONLY_VIRTUAL = markerFor('server-only').virtualId;
41
41
 
42
42
  /**
43
43
  * Map from @timber-js/app/<subpath> to relative src/ file paths.
@@ -191,8 +191,9 @@ export function timberShims(_ctx: PluginContext): Plugin {
191
191
  */
192
192
  resolveId(id: string) {
193
193
  // Poison pill packages — resolve to virtual modules handled by load()
194
- if (id === 'server-only') return SERVER_ONLY_VIRTUAL;
195
- if (id === 'client-only') return CLIENT_ONLY_VIRTUAL;
194
+ for (const marker of EXPLICIT_MARKERS) {
195
+ if (id === marker.specifier) return marker.virtualId;
196
+ }
196
197
 
197
198
  const cleanId = stripJsExtension(id);
198
199
 
@@ -351,28 +352,12 @@ export function timberShims(_ctx: PluginContext): Plugin {
351
352
  */
352
353
  load(id: string) {
353
354
  const env = envName(this);
354
- const isClient = env === 'client';
355
-
356
- if (id === SERVER_ONLY_VIRTUAL) {
357
- if (isClient) {
358
- return `throw new Error(
359
- "This module cannot be imported from a Client Component module. " +
360
- "It should only be used from a Server Component."
361
- );`;
362
- }
363
- // No-op in server environments (rsc, ssr)
364
- return 'export {};';
365
- }
366
355
 
367
- if (id === CLIENT_ONLY_VIRTUAL) {
368
- if (!isClient) {
369
- return `throw new Error(
370
- "This module cannot be imported from a Server Component module. " +
371
- "It should only be used from a Client Component."
372
- );`;
373
- }
374
- // No-op in client environment
375
- return 'export {};';
356
+ // Poison pill bodies — a top-level throw in the wrong environment,
357
+ // a no-op in the right one. Behavior (which environments throw, and
358
+ // the exact message) is defined entirely by poison-rules.ts.
359
+ for (const marker of EXPLICIT_MARKERS) {
360
+ if (id === marker.virtualId) return poisonPillSource(marker, env);
376
361
  }
377
362
 
378
363
  // Error module for @timber-js/app/server in client environment.
@@ -14,25 +14,25 @@ import { mkdir, readdir, readFile, writeFile, rename, rm, stat } from 'node:fs/p
14
14
  import { createHash, randomUUID } from 'node:crypto';
15
15
  import { dirname, extname, isAbsolute, join, resolve, relative } from 'node:path';
16
16
  import { pathToFileURL } from 'node:url';
17
- import type { PluginContext } from '../plugin-context.js';
17
+ import type { PluginContext } from '../plugin-context.ts';
18
18
  import type {
19
19
  StaticGenerationOptions,
20
20
  StaticGenerationSummary,
21
21
  StaticPageEntry,
22
22
  StaticRedirectEntry,
23
- } from '../server/static-generator.js';
24
- import { mergeRscAssetsManifest } from './adapter-build.js';
25
- import { isRelativeBase, normalizeBasePath, withBasePath } from '../shared/base-path.js';
26
- import type { RscManifest, RscManifestEntry } from '../shared/rsc-manifest.js';
27
- import { htmlEscapeJsonString } from '../server/flight-scripts.js';
28
- import { rscPayloadPath } from '../shared/rsc-payload-path.js';
29
- import { REDIRECTS_FILE, RESERVED_OUTPUT_PATHS } from '../shared/static-platform-files.js';
23
+ } from '../server/static-generator.ts';
24
+ import { mergeRscAssetsManifest } from './adapter-build.ts';
25
+ import { isRelativeBase, normalizeBasePath, withBasePath } from '../shared/base-path.ts';
26
+ import type { RscManifest, RscManifestEntry } from '../shared/rsc-manifest.ts';
27
+ import { htmlEscapeJsonString } from '../server/flight-scripts.ts';
28
+ import { rscPayloadPath } from '../shared/rsc-payload-path.ts';
29
+ import { REDIRECTS_FILE, RESERVED_OUTPUT_PATHS } from '../shared/static-platform-files.ts';
30
30
  import {
31
31
  detectFsIdentity,
32
32
  fsKey,
33
33
  EXACT_FS_IDENTITY,
34
34
  type FsIdentity,
35
- } from '../adapters/fs-identity.js';
35
+ } from '../adapters/fs-identity.ts';
36
36
 
37
37
  // ---------------------------------------------------------------------------
38
38
  // Types
@@ -45,7 +45,7 @@ import {
45
45
  */
46
46
  // Declared in shared/rsc-manifest.ts so the client that reads this manifest and
47
47
  // the build that writes it cannot drift. Re-exported for existing importers.
48
- export type { RscManifestEntry, RscManifest } from '../shared/rsc-manifest.js';
48
+ export type { RscManifestEntry, RscManifest } from '../shared/rsc-manifest.ts';
49
49
 
50
50
  export interface StaticValidationError {
51
51
  type: 'dynamic-api';
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { relative, posix } from 'node:path';
10
- import type { ParamEntry } from './codegen-types.js';
10
+ import type { ParamEntry } from './codegen-types.ts';
11
11
 
12
12
  /**
13
13
  * Compute a relative import specifier for a codec/page file, stripping
@@ -17,9 +17,9 @@
17
17
 
18
18
  import { writeFile, mkdir } from 'node:fs/promises';
19
19
  import { join } from 'node:path';
20
- import { generateRouteMap } from './codegen.js';
21
- import { writeSegmentTypes } from './segment-codegen.js';
22
- import type { RouteTree } from './types.js';
20
+ import { generateRouteMap } from './codegen.ts';
21
+ import { writeSegmentTypes } from './segment-codegen.ts';
22
+ import type { RouteTree } from './types.ts';
23
23
 
24
24
  /**
25
25
  * Path (relative to the project root) of the generated route map declaration
@@ -10,11 +10,11 @@
10
10
 
11
11
  import { existsSync } from 'node:fs';
12
12
  import { join, relative } from 'node:path';
13
- import type { RouteTree, SegmentNode } from './types.js';
14
- import type { ParamEntry, RouteEntry } from './codegen-types.js';
15
- import { buildSchemaParamType } from './codegen-shared.js';
16
- import { effectiveUrlSegment, type UrlSegmentIdentity } from './segment-classify.js';
17
- import { formatLinkCatchAllOverloads, formatTypedLinkOverloads } from './link-codegen.js';
13
+ import type { RouteTree, SegmentNode } from './types.ts';
14
+ import type { ParamEntry, RouteEntry } from './codegen-types.ts';
15
+ import { buildSchemaParamType } from './codegen-shared.ts';
16
+ import { effectiveUrlSegment, type UrlSegmentIdentity } from './segment-classify.ts';
17
+ import { formatLinkCatchAllOverloads, formatTypedLinkOverloads } from './link-codegen.ts';
18
18
 
19
19
  /** Options for route map generation. */
20
20
  export interface CodegenOptions {
@@ -325,6 +325,15 @@ function formatDeclarationFile(
325
325
  lines.push('}');
326
326
  lines.push('');
327
327
  }
328
+ // Guard: detect when the schema or params imports silently degraded to
329
+ // `any` because TypeScript could not resolve the import specifier.
330
+ // In a .d.ts an unresolved import does NOT error — every downstream
331
+ // type silently becomes `any`, which satisfies every assertion. Only
332
+ // an explicit IsAny check catches it.
333
+ lines.push('type _IsAny<T> = 0 extends 1 & T ? true : false;');
334
+ lines.push('type _AssertSchemaNotAny<_T extends false = _IsAny<typeof schema>> = true;');
335
+ lines.push('type _AssertCodecTypeNotAny<_T extends false = _IsAny<SegmentParamCodec>> = true;');
336
+ lines.push('');
328
337
  // Type-level validation: each schema value must be a Codec or Standard Schema.
329
338
  // Running `pnpm run typecheck` will surface errors for invalid values.
330
339
  lines.push('type _AssertSchemaValues = {');
@@ -41,13 +41,13 @@
41
41
  * See design/07-routing.md §"Comparing Routes by the URLs They Match".
42
42
  */
43
43
 
44
- import type { SegmentNode } from './types.js';
45
- import { effectiveUrlSegment } from './segment-classify.js';
44
+ import type { SegmentNode } from './types.ts';
45
+ import { effectiveUrlSegment } from './segment-classify.ts';
46
46
  // The validators ask the real matcher which page answers a URL rather than
47
47
  // modelling its precedence rules a second time. `tree-match.ts` is a pure
48
48
  // walker over `SegmentNode` with no request-time state, and
49
49
  // `server/chain-url-parts.ts` already imports the other direction.
50
- import { matchUrlParts } from '../server/tree-match.js';
50
+ import { matchUrlParts } from '../server/tree-match.ts';
51
51
 
52
52
  /** One page-or-route-bearing node in a collision space. */
53
53
  export interface ProbeLeaf {
@@ -11,9 +11,9 @@
11
11
  * See design/07-routing.md §"Route Collisions".
12
12
  */
13
13
 
14
- import type { SegmentNode } from './types.js';
15
- import { computeInterceptedUrlBase } from './interception.js';
16
- import { findOrderDependentCollision, type ProbeLeaf } from './collision-probe.js';
14
+ import type { SegmentNode } from './types.ts';
15
+ import { computeInterceptedUrlBase } from './interception.ts';
16
+ import { findOrderDependentCollision, type ProbeLeaf } from './collision-probe.ts';
17
17
 
18
18
  /**
19
19
  * Validate that no two pages/routes in one collision space answer the same URL.
@@ -17,17 +17,17 @@
17
17
  * Design doc: 07-routing.md, 10-error-handling.md
18
18
  */
19
19
 
20
- import { existsSync } from 'node:fs';
21
- import type { RouteFile, RouteTree, SegmentNode } from './types.js';
22
- import { swallow } from '../server/logger.js';
23
- import { isMdxFilePath } from '../server/utils/mdx-file.js';
20
+ import { existsSync, readFileSync } from 'node:fs';
21
+ import type { RouteFile, RouteTree, SegmentNode } from './types.ts';
22
+ import { swallow } from '../server/logger.ts';
23
+ import { isMdxFilePath } from '../server/utils/mdx-file.ts';
24
24
  import {
25
25
  fileDefaultExportIsLocalValue,
26
26
  fileHasAnyExport,
27
27
  fileHasDefaultExport,
28
28
  fileHasDirective,
29
29
  fileHasStarExport,
30
- } from './export-detect.js';
30
+ } from './export-detect.ts';
31
31
 
32
32
  // ─── Types ──────────────────────────────────────────────────────────────────
33
33
 
@@ -69,15 +69,56 @@ export function lintConventions(tree: RouteTree, appDir: string): ConventionWarn
69
69
  // Check 5: page.tsx / layout.tsx without default export
70
70
  checkDefaultExports(tree.root, warnings);
71
71
 
72
- // Check 6: error.tsx / 404.tsx / 4xx.tsx / … without 'use client' directive
72
+ // Check 6: Client layouts cannot suppress server children before Flight
73
+ // serializes them. They remain valid UI boundaries, but not authorization
74
+ // or data-hiding boundaries.
75
+ checkClientLayouts(tree.root, warnings);
76
+
77
+ // Check 7: error.tsx / 404.tsx / 4xx.tsx / … without 'use client' directive
73
78
  checkClientBoundaryFiles(tree.root, warnings);
74
79
  if (tree.globalError) {
75
80
  checkFileUseClientDirective(tree.globalError, 'global-error', warnings);
76
81
  }
77
82
 
83
+ // Check 8: Wildcard MDX status files (4xx.mdx, 5xx.mdx, error.mdx) that
84
+ // reference `props` — props resolve on deny and throw paths but are empty
85
+ // on the boundary path. See design/10-error-handling.md §"MDX Props by Path".
86
+ checkWildcardMdxProps(tree.root, warnings);
87
+
78
88
  return warnings;
79
89
  }
80
90
 
91
+ function checkClientLayouts(node: SegmentNode, warnings: ConventionWarning[]): void {
92
+ if (node.layout && isScriptExtension(node.layout.extension)) {
93
+ try {
94
+ const isClient = fileHasDirective(node.layout.filePath, 'use client');
95
+ const isProvablyServer = fileDefaultExportIsLocalValue(node.layout.filePath);
96
+ if (isClient || !isProvablyServer) {
97
+ const certainty = isClient
98
+ ? `This layout is a client component.`
99
+ : `Timber cannot prove this layout is a server component because its default export comes from another module or an opaque expression.`;
100
+ warnings.push({
101
+ id: `CLIENT_LAYOUT_NOT_AUTH_BOUNDARY:${node.layout.filePath}`,
102
+ summary: isClient
103
+ ? `Client layout cannot securely suppress server children: ${node.layout.filePath}`
104
+ : `Layout may resolve to a client component and cannot be trusted as an auth boundary: ${node.layout.filePath}`,
105
+ details:
106
+ ` File: ${node.layout.filePath}\n\n` +
107
+ ` ${certainty}\n` +
108
+ ` React Flight resolves server content passed to a client layout before the layout runs in the browser.\n` +
109
+ ` Conditionally omitting children here does not prevent descendant server components from executing or being serialized.\n\n` +
110
+ ` To fix: Put authorization in access.ts or a provably server layout with a locally defined default component, and keep client components inside that boundary.\n`,
111
+ level: 'warn',
112
+ });
113
+ }
114
+ } catch (err) {
115
+ swallow(err, `convention-lint: unreadable layout file ${node.layout.filePath}`);
116
+ }
117
+ }
118
+ for (const child of node.children) checkClientLayouts(child, warnings);
119
+ for (const slot of Object.values(node.slots)) checkClientLayouts(slot, warnings);
120
+ }
121
+
81
122
  // ─── Check: Empty App ───────────────────────────────────────────────────────
82
123
 
83
124
  /**
@@ -408,6 +449,95 @@ function checkFileUseClientDirective(
408
449
  });
409
450
  }
410
451
 
452
+ // ─── Check: Wildcard MDX Props ──────────────────────────────────────────────
453
+
454
+ /**
455
+ * Wildcard status file keys in `statusFiles` whose props differ by path.
456
+ * `error` is not here — the scanner stores it in `node.error`, not
457
+ * `node.statusFiles`, and the check handles it separately below.
458
+ */
459
+ const WILDCARD_MDX_STATUS_KEYS = new Set(['4xx', '5xx']);
460
+
461
+ /**
462
+ * Warn when a wildcard MDX status file (`4xx.mdx`, `5xx.mdx`, `error.mdx`)
463
+ * appears to reference `props` in its source.
464
+ *
465
+ * These files are pre-rendered into `fallbackElement` on the error-boundary
466
+ * path, before the error happens, so they receive empty or partial props.
467
+ * On the deny and error-renderer paths they receive the real props. An author
468
+ * writing `{props.status}` gets the number on some paths and `undefined` on
469
+ * others — same source, different output.
470
+ *
471
+ * A text scan for `props` is acceptable here because the check is `level:
472
+ * 'warn'` — a false positive costs a printed line, not a refused build. A
473
+ * sound check would need the MDX compiler, which is optional, async, and
474
+ * scoped to the RSC environment. See TIM-1333.
475
+ *
476
+ * Exact-code MDX files (e.g. `503.mdx`) are unaffected — all four paths
477
+ * agree on their status.
478
+ */
479
+ function checkWildcardMdxProps(node: SegmentNode, warnings: ConventionWarning[]): void {
480
+ if (node.statusFiles) {
481
+ for (const [key, file] of Object.entries(node.statusFiles)) {
482
+ if (WILDCARD_MDX_STATUS_KEYS.has(key) && isMdxFilePath(file.filePath)) {
483
+ checkMdxFileForProps(file.filePath, key, warnings);
484
+ }
485
+ }
486
+ }
487
+ if (node.error && isMdxFilePath(node.error.filePath)) {
488
+ checkMdxFileForProps(node.error.filePath, 'error', warnings);
489
+ }
490
+
491
+ for (const child of node.children) {
492
+ checkWildcardMdxProps(child, warnings);
493
+ }
494
+ for (const slot of Object.values(node.slots)) {
495
+ checkWildcardMdxProps(slot, warnings);
496
+ }
497
+ }
498
+
499
+ /**
500
+ * Check if an MDX file's source appears to reference `props`.
501
+ *
502
+ * MDX passes a `props` object to the default export function. A reference to
503
+ * `props.status` or `props.dangerouslyPassData` in a wildcard file works on
504
+ * the deny/throw paths but renders `undefined` on the boundary path.
505
+ */
506
+ function checkMdxFileForProps(
507
+ filePath: string,
508
+ convention: string,
509
+ warnings: ConventionWarning[]
510
+ ): void {
511
+ let source: string;
512
+ try {
513
+ source = readFileSync(filePath, 'utf-8');
514
+ } catch {
515
+ return;
516
+ }
517
+
518
+ // MDX exposes props via the default export: export default function(props) { ... }
519
+ // and via JSX expressions: {props.status}. A text scan is intentionally
520
+ // broad — false positives are cheap at warn level.
521
+ if (!/\bprops\b/.test(source)) return;
522
+
523
+ const label = `${convention}.${filePath.endsWith('.md') ? 'md' : 'mdx'}`;
524
+ warnings.push({
525
+ id: `MDX_WILDCARD_PROPS:${filePath}`,
526
+ summary: `${label} references props, which are empty on the error boundary path: ${filePath}`,
527
+ details:
528
+ ` File: ${filePath}\n\n` +
529
+ ` Wildcard MDX status files (${convention}.mdx) are pre-rendered into\n` +
530
+ ' fallbackElement before the error occurs. On that path, props are\n' +
531
+ ` empty${convention === 'error' ? '' : ' (no status, no dangerouslyPassData)'}. On the deny() and error-renderer\n` +
532
+ ' paths, props.status resolves correctly.\n\n' +
533
+ ' If this file uses only static content and "props" appears in prose,\n' +
534
+ ' this warning is a false positive — ignore it.\n\n' +
535
+ ' To fix: Use only static content in wildcard MDX status files, or\n' +
536
+ ' use an exact-code file (e.g. 404.mdx) where all paths agree.\n',
537
+ level: 'warn',
538
+ });
539
+ }
540
+
411
541
  // ─── Check: App Directory Exists ────────────────────────────────────────────
412
542
 
413
543
  /**
@@ -8,7 +8,7 @@
8
8
 
9
9
  import { existsSync } from 'node:fs';
10
10
  import { parseAst } from 'vite';
11
- import { readFileCached } from './file-cache.js';
11
+ import { readFileCached } from './file-cache.ts';
12
12
 
13
13
  interface AstNode {
14
14
  type: string;
@@ -1,6 +1,6 @@
1
- export { scanRoutes } from './scanner.js';
2
- export { generateRouteMap } from './codegen.js';
3
- export type { CodegenOptions } from './codegen.js';
1
+ export { scanRoutes } from './scanner.ts';
2
+ export { generateRouteMap } from './codegen.ts';
3
+ export type { CodegenOptions } from './codegen.ts';
4
4
  export type {
5
5
  RouteTree,
6
6
  SegmentNode,
@@ -8,16 +8,16 @@ export type {
8
8
  RouteFile,
9
9
  ScannerConfig,
10
10
  InterceptionMarker,
11
- } from './types.js';
12
- export { DEFAULT_PAGE_EXTENSIONS, INTERCEPTION_MARKERS } from './types.js';
13
- export { collectInterceptionRewrites } from './interception.js';
14
- export type { InterceptionRewrite } from './interception.js';
15
- export { classifyUrlSegment, classifySegment } from './segment-classify.js';
16
- export type { UrlSegment, SegmentClassification } from './segment-classify.js';
17
- export { collectLeafRoutes } from './walkers.js';
18
- export type { LeafRoute, CollectLeafRoutesOptions } from './walkers.js';
11
+ } from './types.ts';
12
+ export { DEFAULT_PAGE_EXTENSIONS, INTERCEPTION_MARKERS } from './types.ts';
13
+ export { collectInterceptionRewrites } from './interception.ts';
14
+ export type { InterceptionRewrite } from './interception.ts';
15
+ export { classifyUrlSegment, classifySegment } from './segment-classify.ts';
16
+ export type { UrlSegment, SegmentClassification } from './segment-classify.ts';
17
+ export { collectLeafRoutes } from './walkers.ts';
18
+ export type { LeafRoute, CollectLeafRoutesOptions } from './walkers.ts';
19
19
  export {
20
20
  validateSchemaAgainstRoutes,
21
21
  collectDynamicSegmentsFromTree,
22
- } from './schema-validation.js';
23
- export type { SchemaWarning } from './schema-validation.js';
22
+ } from './schema-validation.ts';
23
+ export type { SchemaWarning } from './schema-validation.ts';
@@ -17,13 +17,13 @@
17
17
  * See design/07-routing.md §"Intercepting Routes"
18
18
  */
19
19
 
20
- import type { SegmentNode, InterceptionMarker, RouteFile } from './types.js';
21
- import { computeSegmentTreePaths, treePathDepth } from './segment-keys.js';
22
- import { classifyUrlSegment, effectiveUrlSegment } from './segment-classify.js';
20
+ import type { SegmentNode, InterceptionMarker, RouteFile } from './types.ts';
21
+ import { computeSegmentTreePaths, treePathDepth } from './segment-keys.ts';
22
+ import { classifyUrlSegment, effectiveUrlSegment } from './segment-classify.ts';
23
23
  // Every collision space — the main tree, each slot, each intercepting subtree
24
24
  // — decides order-dependence with the same oracle, so the spaces cannot drift
25
25
  // on what counts as two pages answering one URL. See TIM-1308.
26
- import { findOrderDependentCollision, type ProbeLeaf } from './collision-probe.js';
26
+ import { findOrderDependentCollision, type ProbeLeaf } from './collision-probe.ts';
27
27
 
28
28
  /** Fields shared by both interception shapes. */
29
29
  interface InterceptionRewriteBase {
@@ -505,6 +505,42 @@ function assertInterceptedCatchAllsAreTerminal(node: SegmentNode, nodePath: stri
505
505
  }
506
506
  }
507
507
 
508
+ /**
509
+ * Reject a `route.ts` anywhere inside an intercepting subtree.
510
+ *
511
+ * An interception is a soft-navigation variant of a page — it swaps which
512
+ * page component renders. A route handler returns a `Response` and cannot
513
+ * be an interception target: `walkInterceptedLeaves` visits `node.page`
514
+ * only, so no rewrite is emitted for it, but `isTerminal` in
515
+ * `tree-match.ts` counts both `page` and `route`, so `matchUrlParts` can
516
+ * resolve to the route handler. `slot-interception.ts` then drops the
517
+ * match (`if (!leaf.page) continue`), silently disabling the page's
518
+ * interception. Fail-safe (the canonical route renders) but silent.
519
+ *
520
+ * The walk mirrors `assertInterceptedCatchAllsAreTerminal`: it descends
521
+ * `children` (not `slots`), matching `collectLeavesWithRewrites` exactly.
522
+ */
523
+ function assertNoRouteHandlersInSubtree(node: SegmentNode, nodePath: string): void {
524
+ if (node.route) {
525
+ throw new Error(
526
+ `Build error: route handler inside an intercepting route.\n` +
527
+ ` File: ${node.route.filePath}\n` +
528
+ ` Directory: app/${nodePath}\n` +
529
+ `An intercepting subtree renders a page component on soft navigation — a ` +
530
+ `route handler returns a Response and cannot be an interception target. ` +
531
+ `The route handler would silently shadow the interception: the resolver ` +
532
+ `would match it and then discard it because it has no page, so the modal ` +
533
+ `would stop opening with no diagnostic.\n` +
534
+ `Remove the route.ts, or move it outside the intercepting subtree.\n` +
535
+ `See design/07-routing.md §"Intercepting Routes".`
536
+ );
537
+ }
538
+
539
+ for (const child of node.children) {
540
+ assertNoRouteHandlersInSubtree(child, `${nodePath}/${child.segmentName}`);
541
+ }
542
+ }
543
+
508
544
  /**
509
545
  * Reject two pages that answer one URL among the interceptors an owner
510
546
  * resolves in a single walk.
@@ -723,6 +759,7 @@ function walkForPlacement(node: SegmentNode, path: string, ctx: PlacementContext
723
759
  // interception. The same input rewrite generation bases from.
724
760
  assertInterceptedBaseIsCountable(child, node.urlPath, childPath);
725
761
  assertInterceptedCatchAllsAreTerminal(child, childPath);
762
+ assertNoRouteHandlersInSubtree(child, childPath);
726
763
  }
727
764
 
728
765
  walkForPlacement(child, childPath, {
@@ -23,9 +23,9 @@
23
23
  * overload TS reports against on failure.
24
24
  */
25
25
 
26
- import type { ParamEntry, RouteEntry } from './codegen-types.js';
27
- import { buildSchemaParamType } from './codegen-shared.js';
28
- import { classifyUrlSegment } from './segment-classify.js';
26
+ import type { ParamEntry, RouteEntry } from './codegen-types.ts';
27
+ import { buildSchemaParamType } from './codegen-shared.ts';
28
+ import { classifyUrlSegment } from './segment-classify.ts';
29
29
 
30
30
  /**
31
31
  * The `searchParams` prop type, emitted identically on every Link variant
@@ -10,8 +10,8 @@
10
10
 
11
11
  import { existsSync } from 'node:fs';
12
12
  import { join } from 'node:path';
13
- import { collectInterceptionRewrites } from './interception.js';
14
- import type { RouteTree, SegmentNode, RouteFile } from './types.js';
13
+ import { collectInterceptionRewrites } from './interception.ts';
14
+ import type { RouteTree, SegmentNode, RouteFile } from './types.ts';
15
15
 
16
16
  // ── Single-file conventions ─────────────────────────────────────────────
17
17
  // Each entry maps to a node property that holds a single RouteFile.