@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.
- package/agent-skill.md +2 -0
- package/dist/_chunks/{actions-BjbbNRFN.js → actions-CWYtq6ii.js} +3 -3
- package/dist/_chunks/actions-CWYtq6ii.js.map +1 -0
- package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -1
- package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -1
- package/dist/_chunks/{build-output-helper-C3DrfzZR.js → build-output-helper-9dqCv1pZ.js} +3 -2
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +1 -0
- package/dist/_chunks/{cache-api-DllJ-Lyw.js → cache-api-CQeYzA5g.js} +6 -8
- package/dist/_chunks/cache-api-CQeYzA5g.js.map +1 -0
- package/dist/_chunks/chains-h7EO-u3n.js +412 -0
- package/dist/_chunks/chains-h7EO-u3n.js.map +1 -0
- package/dist/_chunks/{cli-check-DJZDc22E.js → cli-check-BVthpfLS.js} +43 -6
- package/dist/_chunks/cli-check-BVthpfLS.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync-D4_AZVUb.js → cli-schema-sync-3Wutm8pH.js} +7 -6
- package/dist/_chunks/{cli-schema-sync-D4_AZVUb.js.map → cli-schema-sync-3Wutm8pH.js.map} +1 -1
- package/dist/_chunks/{cloudflare-CGP6BZKO.js → cloudflare-BKJC3SC_.js} +28 -22
- package/dist/_chunks/{cloudflare-CGP6BZKO.js.map → cloudflare-BKJC3SC_.js.map} +1 -1
- package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -1
- package/dist/_chunks/{convention-lint-CpteIpTm.js → convention-lint-DO10_pVl.js} +93 -7
- package/dist/_chunks/convention-lint-DO10_pVl.js.map +1 -0
- package/dist/_chunks/dist-DtrJyBbw.js +386 -0
- package/dist/_chunks/dist-DtrJyBbw.js.map +1 -0
- package/dist/_chunks/{error-boundary-D-ODYX41.js → error-boundary-D-lkwyaD.js} +3 -3
- package/dist/_chunks/{error-boundary-D-ODYX41.js.map → error-boundary-D-lkwyaD.js.map} +1 -1
- package/dist/_chunks/{file-cache-DmX7OqZP.js → file-cache-Dw6BJPG7.js} +5 -1
- package/dist/_chunks/{file-cache-DmX7OqZP.js.map → file-cache-Dw6BJPG7.js.map} +1 -1
- package/dist/_chunks/{format-CfwjgPz9.js → format-BKclgVbk.js} +3 -3
- package/dist/_chunks/{format-CfwjgPz9.js.map → format-BKclgVbk.js.map} +1 -1
- package/dist/_chunks/graph-cache-CP4GEmf9.js +304 -0
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +1 -0
- package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -1
- package/dist/_chunks/live-graph-Bx4HodF1.js +150 -0
- package/dist/_chunks/live-graph-Bx4HodF1.js.map +1 -0
- package/dist/_chunks/{logger-CH7IcMmg.js → logger-pumCm3Il.js} +25 -7
- package/dist/_chunks/{logger-CH7IcMmg.js.map → logger-pumCm3Il.js.map} +1 -1
- package/dist/_chunks/{mdx-file-C005ay-P.js → mdx-file-CXyHGUpS.js} +3 -3
- package/dist/_chunks/mdx-file-CXyHGUpS.js.map +1 -0
- package/dist/_chunks/{plugin-context-rCinWLiE.js → plugin-context-8idfR3UZ.js} +2 -2
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +1 -0
- package/dist/_chunks/poison-rules-DoEhbqaY.js +110 -0
- package/dist/_chunks/poison-rules-DoEhbqaY.js.map +1 -0
- package/dist/_chunks/poison-scan-BAxfTT5L.js +101 -0
- package/dist/_chunks/poison-scan-BAxfTT5L.js.map +1 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -1
- package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/_chunks/{router-ref-DuYuV_0Q.js → router-ref-BzqbPwYC.js} +2 -2
- package/dist/_chunks/{router-ref-DuYuV_0Q.js.map → router-ref-BzqbPwYC.js.map} +1 -1
- package/dist/_chunks/{rsc-media-type-DRqE_lD_.js → rsc-media-type-DDc7duTD.js} +17 -2
- package/dist/_chunks/{rsc-media-type-DRqE_lD_.js.map → rsc-media-type-DDc7duTD.js.map} +1 -1
- package/dist/_chunks/scan-BoP17W3w.js +140 -0
- package/dist/_chunks/scan-BoP17W3w.js.map +1 -0
- package/dist/_chunks/{scanner-CAietmj4.js → scanner-BRIOmHE2.js} +43 -4
- package/dist/_chunks/scanner-BRIOmHE2.js.map +1 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -1
- package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -1
- package/dist/_chunks/{segment-keys-BawYuNFO.js → segment-keys-BhqoHiLc.js} +14 -2
- package/dist/_chunks/{segment-keys-BawYuNFO.js.map → segment-keys-BhqoHiLc.js.map} +1 -1
- package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -1
- package/dist/_chunks/{ssr-data-14MXm7Pj.js → ssr-data-Ya2HJPFp.js} +1 -7
- package/dist/_chunks/{ssr-data-14MXm7Pj.js.map → ssr-data-Ya2HJPFp.js.map} +1 -1
- package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -1
- package/dist/_chunks/{use-segment-params-C4r4BD9T.js → use-segment-params-DzTBpkvj.js} +3 -3
- package/dist/_chunks/use-segment-params-DzTBpkvj.js.map +1 -0
- package/dist/_chunks/{walkers-BsVLmD1S.js → walkers-BU6z9xRV.js} +9 -6
- package/dist/_chunks/{walkers-BsVLmD1S.js.map → walkers-BU6z9xRV.js.map} +1 -1
- package/dist/adapters/build-output-helper.d.ts +1 -1
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -1
- package/dist/adapters/cloudflare-dev.js +2 -1
- package/dist/adapters/cloudflare-dev.js.map +1 -1
- package/dist/adapters/cloudflare-kv-cache.d.ts +1 -1
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +7 -8
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -1
- package/dist/adapters/cloudflare.d.ts +1 -1
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/nitro-presets.d.ts +37 -0
- package/dist/adapters/nitro-presets.d.ts.map +1 -0
- package/dist/adapters/nitro-preview.d.ts +32 -0
- package/dist/adapters/nitro-preview.d.ts.map +1 -0
- package/dist/adapters/nitro.d.ts +28 -51
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +224 -171
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/analyze/chains.d.ts +124 -0
- package/dist/analyze/chains.d.ts.map +1 -0
- package/dist/analyze/classify.d.ts +150 -0
- package/dist/analyze/classify.d.ts.map +1 -0
- package/dist/analyze/crawl-entry.d.ts +17 -0
- package/dist/analyze/crawl-entry.d.ts.map +1 -0
- package/dist/analyze/crawl-entry.js +313 -0
- package/dist/analyze/crawl-entry.js.map +1 -0
- package/dist/analyze/crawl.d.ts +134 -0
- package/dist/analyze/crawl.d.ts.map +1 -0
- package/dist/analyze/graph-cache.d.ts +104 -0
- package/dist/analyze/graph-cache.d.ts.map +1 -0
- package/dist/analyze/graph-command.d.ts +43 -0
- package/dist/analyze/graph-command.d.ts.map +1 -0
- package/dist/analyze/graph-command.js +472 -0
- package/dist/analyze/graph-command.js.map +1 -0
- package/dist/analyze/live-graph.d.ts +81 -0
- package/dist/analyze/live-graph.d.ts.map +1 -0
- package/dist/analyze/poison-rules.d.ts +72 -0
- package/dist/analyze/poison-rules.d.ts.map +1 -0
- package/dist/analyze/poison-scan.d.ts +48 -0
- package/dist/analyze/poison-scan.d.ts.map +1 -0
- package/dist/analyze/scan.d.ts +73 -0
- package/dist/analyze/scan.d.ts.map +1 -0
- package/dist/cache/cache-api.d.ts +2 -2
- package/dist/cache/cache-api.d.ts.map +1 -1
- package/dist/cache/index.d.ts +8 -8
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/cache/redis-handler.d.ts +1 -1
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/stores/cloudflare-kv.d.ts +1 -1
- package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -1
- package/dist/cache/stores/cloudflare-kv.js.map +1 -1
- package/dist/cache/stores/memory.d.ts +1 -1
- package/dist/cache/stores/memory.d.ts.map +1 -1
- package/dist/cache/stores/memory.js.map +1 -1
- package/dist/cache/stores/redis.d.ts +1 -1
- package/dist/cache/stores/redis.d.ts.map +1 -1
- package/dist/cache/stores/redis.js.map +1 -1
- package/dist/cache/stores/vercel.d.ts +1 -1
- package/dist/cache/stores/vercel.d.ts.map +1 -1
- package/dist/cache/stores/vercel.js.map +1 -1
- package/dist/cache/tag-aware-handler.d.ts +2 -2
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cache/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.d.ts +1 -1
- package/dist/cdn/cloudflare-purge.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.js.map +1 -1
- package/dist/cdn/fastly-purge.d.ts +1 -1
- package/dist/cdn/fastly-purge.d.ts.map +1 -1
- package/dist/cdn/fastly-purge.js.map +1 -1
- package/dist/cdn/index.d.ts +4 -4
- package/dist/cdn/index.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.d.ts +5 -1
- package/dist/cdn/workers-cache-purge.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.js.map +1 -1
- package/dist/cli-check.d.ts +10 -0
- package/dist/cli-check.d.ts.map +1 -1
- package/dist/cli.d.ts +12 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +30 -6
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +2 -2
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/post-hydration.d.ts +2 -2
- package/dist/client/browser-entry/router-init.d.ts +2 -2
- package/dist/client/browser-entry/rsc-stream.d.ts +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/form.d.ts +2 -2
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +2 -2
- package/dist/client/index.d.ts +18 -18
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +19 -19
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +15 -19
- package/dist/client/internal.js.map +1 -1
- package/dist/client/link.d.ts +3 -3
- package/dist/client/navigation-commit.d.ts +5 -5
- package/dist/client/navigation-root.d.ts +1 -1
- package/dist/client/navigation-root.d.ts.map +1 -1
- package/dist/client/params-context.d.ts +3 -3
- package/dist/client/router-pipeline.d.ts +7 -7
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router-types.d.ts +6 -6
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router.d.ts +1 -1
- package/dist/client/rsc-fetch.d.ts +4 -4
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +2 -2
- package/dist/client/slot-provider.d.ts +1 -1
- package/dist/client/ssr-data.d.ts +2 -2
- package/dist/client/state.d.ts +4 -4
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-segment-params.d.ts +3 -3
- package/dist/codec.d.ts +2 -2
- package/dist/codec.js.map +1 -1
- package/dist/config-types.d.ts +12 -9
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts +1 -1
- package/dist/cookies/define-cookie.d.ts +3 -3
- package/dist/cookies/index.d.ts +3 -3
- package/dist/cookies/index.js +4 -5
- package/dist/cookies/index.js.map +1 -1
- package/dist/cookies/json-cookie.d.ts +1 -1
- package/dist/dev-tools/404-page.d.ts +2 -2
- package/dist/dev-tools/error-page.d.ts +2 -2
- package/dist/dev-tools/index.d.ts +12 -12
- package/dist/dev-tools/instrumentation.d.ts +1 -1
- package/dist/dev-tools/logs.d.ts +1 -1
- package/dist/dev-tools/overlay.d.ts +2 -2
- package/dist/dev-tools/terminal.d.ts +1 -1
- package/dist/fonts/ast.d.ts +4 -4
- package/dist/fonts/bundle.d.ts +3 -3
- package/dist/fonts/css.d.ts +1 -1
- package/dist/fonts/dev-middleware.d.ts +1 -1
- package/dist/fonts/google.d.ts +1 -1
- package/dist/fonts/local.d.ts +1 -1
- package/dist/fonts/pipeline.d.ts +3 -3
- package/dist/fonts/transform.d.ts +2 -2
- package/dist/fonts/types.d.ts +1 -1
- package/dist/fonts/virtual-modules.d.ts +1 -1
- package/dist/index.d.ts +3 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +861 -314
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +1 -1
- package/dist/params/define-schema.d.ts +2 -2
- package/dist/params/index.d.ts +4 -4
- package/dist/params/index.js.map +1 -1
- package/dist/params/resolve-schema.d.ts +1 -1
- package/dist/plugin-context.d.ts +9 -9
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/adapter-build.d.ts +2 -2
- package/dist/plugins/build-manifest.d.ts +2 -2
- package/dist/plugins/build-report.d.ts +5 -5
- package/dist/plugins/cache.d.ts +1 -1
- package/dist/plugins/callsite-jsx.d.ts +2 -2
- package/dist/plugins/chunks.d.ts +1 -1
- package/dist/plugins/chunks.d.ts.map +1 -1
- package/dist/plugins/cloudflare-wasm.d.ts +1 -1
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-discovery.d.ts +123 -0
- package/dist/plugins/dev-discovery.d.ts.map +1 -0
- package/dist/plugins/dev-server.d.ts +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/fonts.d.ts +3 -3
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/graph-endpoint.d.ts +112 -0
- package/dist/plugins/graph-endpoint.d.ts.map +1 -0
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/prebuilt-capture.d.ts +2 -2
- package/dist/plugins/prebuilt-options-analysis.d.ts +1 -1
- package/dist/plugins/prebuilt.d.ts +1 -1
- package/dist/plugins/prerender-sugar.d.ts +11 -14
- package/dist/plugins/prerender-sugar.d.ts.map +1 -1
- package/dist/plugins/request-dep/analysis.d.ts +1 -1
- package/dist/plugins/request-dep/index.d.ts +5 -5
- package/dist/plugins/request-dep/origin.d.ts +1 -1
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +1 -1
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +5 -5
- package/dist/routing/codegen-shared.d.ts +1 -1
- package/dist/routing/codegen-write.d.ts +1 -1
- package/dist/routing/codegen.d.ts +1 -1
- package/dist/routing/collision-probe.d.ts +1 -1
- package/dist/routing/collision-spaces.d.ts +1 -1
- package/dist/routing/convention-lint.d.ts +1 -1
- package/dist/routing/convention-lint.d.ts.map +1 -1
- package/dist/routing/index.d.ts +13 -13
- package/dist/routing/index.js +3 -3
- package/dist/routing/interception.d.ts +1 -1
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +1 -1
- package/dist/routing/manifest-codegen.d.ts +1 -1
- package/dist/routing/scanner.d.ts +14 -1
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/schema-validation.d.ts +1 -1
- package/dist/routing/segment-classify.d.ts +1 -1
- package/dist/routing/segment-codegen.d.ts +1 -1
- package/dist/routing/segment-keys.d.ts +1 -1
- package/dist/routing/slot-placement.d.ts +1 -1
- package/dist/routing/walkers.d.ts +1 -1
- package/dist/rsc-runtime/transforms.d.ts +13 -0
- package/dist/rsc-runtime/transforms.d.ts.map +1 -0
- package/dist/schema-bridge.d.ts +1 -1
- package/dist/search-params/define.d.ts +3 -3
- package/dist/search-params/index.d.ts +3 -3
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/wrappers.d.ts +1 -1
- package/dist/server/access-gate.d.ts +1 -1
- package/dist/server/action-client.d.ts +1 -1
- package/dist/server/action-handler.d.ts +5 -5
- package/dist/server/actions.d.ts +2 -2
- package/dist/server/als-registry.d.ts +8 -8
- package/dist/server/asset-headers.d.ts +1 -1
- package/dist/server/chain-url-parts.d.ts +3 -3
- package/dist/server/children-interception.d.ts +2 -2
- package/dist/server/cookie-context.d.ts +1 -1
- package/dist/server/cookie-parsing.d.ts +2 -2
- package/dist/server/default-logger.d.ts +1 -1
- package/dist/server/deny-boundary.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts +5 -5
- package/dist/server/early-hints.d.ts +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +2 -4
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +5 -5
- package/dist/server/flight-injection-state.d.ts +1 -1
- package/dist/server/form-flash.d.ts +1 -1
- package/dist/server/html-injector-core.d.ts +2 -2
- package/dist/server/html-injectors.d.ts +1 -1
- package/dist/server/index.d.ts +18 -18
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +34 -38
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +1 -1
- package/dist/server/internal.d.ts +50 -50
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +1024 -1026
- package/dist/server/internal.js.map +1 -1
- package/dist/server/metadata-collector.d.ts +2 -2
- package/dist/server/metadata-platform.d.ts +2 -2
- package/dist/server/metadata-render.d.ts +2 -2
- package/dist/server/metadata-routes.d.ts +3 -3
- package/dist/server/metadata-social.d.ts +2 -2
- package/dist/server/metadata.d.ts +2 -2
- package/dist/server/middleware-runner.d.ts +1 -1
- package/dist/server/node-stream-transforms.d.ts +1 -1
- package/dist/server/param-coercion.d.ts +4 -4
- package/dist/server/pipeline-helpers.d.ts +3 -3
- package/dist/server/pipeline-interception.d.ts +1 -1
- package/dist/server/pipeline-metadata.d.ts +1 -1
- package/dist/server/pipeline-outcome.d.ts +2 -2
- package/dist/server/pipeline-phases.d.ts +3 -3
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +9 -9
- package/dist/server/prebuilt/cache-key.d.ts +1 -1
- package/dist/server/prebuilt/capture-state.d.ts +1 -1
- package/dist/server/prebuilt/key-discipline.d.ts +1 -1
- package/dist/server/prebuilt/manifest-tag-index.d.ts +1 -1
- package/dist/server/prebuilt/overlay.d.ts +2 -2
- package/dist/server/prebuilt/payload-source.d.ts +1 -1
- package/dist/server/prebuilt/slots.d.ts +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts +2 -2
- package/dist/server/prebuilt-builder.d.ts +2 -2
- package/dist/server/primitives.d.ts +2 -2
- package/dist/server/publish-params.d.ts +1 -1
- package/dist/server/request-context.d.ts +3 -3
- package/dist/server/route-element-builder.d.ts +16 -6
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts +1 -1
- package/dist/server/route-matcher.d.ts +4 -4
- package/dist/server/rsc-cache-key-guard.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +2 -2
- package/dist/server/rsc-entry/api-handler.d.ts +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +3 -3
- package/dist/server/rsc-entry/error-renderer.d.ts +4 -4
- package/dist/server/rsc-entry/helpers.d.ts +6 -6
- package/dist/server/rsc-entry/index.d.ts +7 -6
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +4 -4
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +4 -4
- package/dist/server/rsc-entry/rsc-payload.d.ts +4 -4
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +3 -3
- package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +7 -7
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +5 -5
- package/dist/server/sitemap-generator.d.ts +2 -2
- package/dist/server/sitemap-handler.d.ts +1 -1
- package/dist/server/skippable-prefix.d.ts +3 -3
- package/dist/server/slot-interception.d.ts +2 -2
- package/dist/server/slot-resolver.d.ts +3 -7
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +2 -2
- package/dist/server/ssr-entry.d.ts +1 -1
- package/dist/server/static-generator.d.ts +1 -1
- package/dist/server/static-not-found.d.ts +1 -1
- package/dist/server/status-code-resolver.d.ts +1 -1
- package/dist/server/tracing.d.ts +3 -3
- package/dist/server/tree-builder.d.ts +3 -3
- package/dist/server/tree-match.d.ts +1 -1
- package/dist/server/types.d.ts +2 -2
- package/dist/server/utils/mdx-file.d.ts +2 -0
- package/dist/server/utils/mdx-file.d.ts.map +1 -1
- package/dist/server/workers-cache-bridge.d.ts +1 -1
- package/dist/shared/als-slots.d.ts +1 -1
- package/dist/shared/payload-root.d.ts +2 -2
- package/dist/shared/rsc-media-type.d.ts +12 -0
- package/dist/shared/rsc-media-type.d.ts.map +1 -1
- package/dist/shared/slot-params.d.ts +1 -1
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.js.map +1 -1
- package/dist/shims/font-local.d.ts +1 -1
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/navigation-client.d.ts +4 -4
- package/dist/shims/navigation.d.ts +2 -2
- package/docs/api/34-api-config.mdx +7 -4
- package/docs/api/36-cli.mdx +23 -3
- package/docs/learn/11-error-handling.mdx +11 -0
- package/docs/learn/13-configuration.mdx +1 -1
- package/docs/more/01-advanced-routing.mdx +1 -0
- package/package.json +11 -10
- package/src/adapters/build-output-helper.ts +4 -4
- package/src/adapters/cloudflare-dev.ts +7 -1
- package/src/adapters/cloudflare-kv-cache.ts +11 -8
- package/src/adapters/cloudflare.ts +21 -15
- package/src/adapters/compress-module.ts +2 -2
- package/src/adapters/nitro-presets.ts +139 -0
- package/src/adapters/nitro-preview.ts +340 -0
- package/src/adapters/nitro.ts +100 -465
- package/src/adapters/shared.ts +1 -1
- package/src/analyze/chains.ts +411 -0
- package/src/analyze/classify.ts +258 -0
- package/src/analyze/crawl-entry.ts +68 -0
- package/src/analyze/crawl.ts +500 -0
- package/src/analyze/graph-cache.ts +332 -0
- package/src/analyze/graph-command.ts +762 -0
- package/src/analyze/live-graph.ts +232 -0
- package/src/analyze/poison-rules.ts +165 -0
- package/src/analyze/poison-scan.ts +162 -0
- package/src/analyze/scan.ts +149 -0
- package/src/cache/cache-api.ts +7 -7
- package/src/cache/index.ts +9 -9
- package/src/cache/redis-handler.ts +2 -2
- package/src/cache/stores/cloudflare-kv.ts +1 -1
- package/src/cache/stores/memory.ts +2 -2
- package/src/cache/stores/redis.ts +1 -1
- package/src/cache/stores/vercel.ts +1 -1
- package/src/cache/tag-aware-handler.ts +2 -2
- package/src/cache/timber-cache.ts +8 -8
- package/src/cdn/cloudflare-purge.ts +1 -1
- package/src/cdn/fastly-purge.ts +1 -1
- package/src/cdn/index.ts +10 -4
- package/src/cdn/workers-cache-purge.ts +6 -2
- package/src/cli-check.ts +53 -4
- package/src/cli-schema-sync.ts +3 -3
- package/src/cli.ts +50 -11
- package/src/client/browser-dev.ts +1 -1
- package/src/client/browser-entry/action-dispatch.ts +5 -5
- package/src/client/browser-entry/hmr.ts +1 -1
- package/src/client/browser-entry/hydrate.ts +9 -9
- package/src/client/browser-entry/index.ts +10 -10
- package/src/client/browser-entry/post-hydration.ts +5 -5
- package/src/client/browser-entry/router-init.ts +9 -9
- package/src/client/browser-entry/rsc-stream.ts +3 -3
- package/src/client/error-boundary.tsx +4 -4
- package/src/client/form.tsx +7 -2
- package/src/client/history.ts +2 -2
- package/src/client/index.ts +21 -18
- package/src/client/internal.ts +19 -19
- package/src/client/link.tsx +9 -9
- package/src/client/navigation-api.ts +1 -1
- package/src/client/navigation-commit.ts +5 -5
- package/src/client/navigation-context.ts +1 -1
- package/src/client/navigation-root.tsx +1 -1
- package/src/client/nuqs-adapter.tsx +2 -2
- package/src/client/params-context.ts +4 -4
- package/src/client/router-effects.ts +3 -3
- package/src/client/router-lifecycle.ts +2 -2
- package/src/client/router-pipeline.ts +10 -10
- package/src/client/router-ref.ts +2 -2
- package/src/client/router-skew.ts +2 -2
- package/src/client/router-types.ts +6 -6
- package/src/client/router.ts +13 -13
- package/src/client/rsc-fetch.ts +11 -16
- package/src/client/segment-cache.ts +2 -2
- package/src/client/segment-outlet.tsx +1 -1
- package/src/client/shallow-url.ts +1 -1
- package/src/client/slot-outlet.tsx +1 -1
- package/src/client/slot-provider.tsx +1 -1
- package/src/client/ssr-data.ts +3 -3
- package/src/client/stale-client.ts +1 -1
- package/src/client/state.ts +4 -4
- package/src/client/top-loader.tsx +1 -1
- package/src/client/unload-guard.ts +1 -1
- package/src/client/use-cookie.ts +2 -2
- package/src/client/use-pathname.ts +2 -2
- package/src/client/use-pending-navigation.ts +1 -1
- package/src/client/use-query-states.ts +3 -3
- package/src/client/use-router.ts +2 -2
- package/src/client/use-search-params.ts +3 -3
- package/src/client/use-segment-params.ts +6 -6
- package/src/client/use-selected-layout-segment.ts +2 -2
- package/src/codec.ts +2 -2
- package/src/config-types.ts +12 -9
- package/src/config-validation.ts +1 -1
- package/src/cookies/define-cookie.ts +6 -6
- package/src/cookies/index.ts +3 -3
- package/src/cookies/json-cookie.ts +1 -1
- package/src/dev-tools/404-page.ts +4 -4
- package/src/dev-tools/dev-page-shell.ts +1 -1
- package/src/dev-tools/error-page.ts +4 -4
- package/src/dev-tools/index.ts +12 -12
- package/src/dev-tools/instrumentation.ts +1 -1
- package/src/dev-tools/logs.ts +1 -1
- package/src/dev-tools/overlay.ts +3 -3
- package/src/dev-tools/terminal.ts +2 -2
- package/src/fonts/ast.ts +5 -5
- package/src/fonts/bundle.ts +5 -5
- package/src/fonts/css.ts +1 -1
- package/src/fonts/dev-middleware.ts +2 -2
- package/src/fonts/google.ts +2 -2
- package/src/fonts/local.ts +4 -4
- package/src/fonts/pipeline.ts +8 -8
- package/src/fonts/transform.ts +5 -5
- package/src/fonts/types.ts +1 -1
- package/src/fonts/virtual-modules.ts +1 -1
- package/src/index.ts +90 -95
- package/src/params/codec-registry.ts +1 -1
- package/src/params/define-schema.ts +2 -2
- package/src/params/index.ts +4 -4
- package/src/params/resolve-schema.ts +2 -2
- package/src/plugin-context.ts +10 -10
- package/src/plugins/adapter-build.ts +5 -5
- package/src/plugins/build-manifest.ts +4 -4
- package/src/plugins/build-report.ts +6 -6
- package/src/plugins/cache.ts +3 -3
- package/src/plugins/callsite-ast.ts +1 -1
- package/src/plugins/callsite-jsx.ts +2 -2
- package/src/plugins/chunks.ts +1 -1
- package/src/plugins/cloudflare-wasm.ts +1 -1
- package/src/plugins/content.ts +5 -1
- package/src/plugins/dev-discovery.ts +218 -0
- package/src/plugins/dev-server.ts +97 -12
- package/src/plugins/entries.ts +1 -1
- package/src/plugins/fonts.ts +17 -10
- package/src/plugins/graph-endpoint.ts +532 -0
- package/src/plugins/mdx.ts +4 -3
- package/src/plugins/prebuilt-capture.ts +3 -3
- package/src/plugins/prebuilt-options-analysis.ts +1 -1
- package/src/plugins/prebuilt.ts +7 -7
- package/src/plugins/prerender-sugar.ts +11 -19
- package/src/plugins/request-dep/analysis.ts +1 -1
- package/src/plugins/request-dep/index.ts +8 -8
- package/src/plugins/request-dep/origin.ts +1 -1
- package/src/plugins/routing.ts +12 -7
- package/src/plugins/server-bundle.ts +9 -2
- package/src/plugins/shims.ts +16 -31
- package/src/plugins/static-build.ts +10 -10
- package/src/routing/codegen-shared.ts +1 -1
- package/src/routing/codegen-write.ts +3 -3
- package/src/routing/codegen.ts +14 -5
- package/src/routing/collision-probe.ts +3 -3
- package/src/routing/collision-spaces.ts +3 -3
- package/src/routing/convention-lint.ts +136 -6
- package/src/routing/export-detect.ts +1 -1
- package/src/routing/index.ts +13 -13
- package/src/routing/interception.ts +41 -4
- package/src/routing/link-codegen.ts +3 -3
- package/src/routing/manifest-codegen.ts +2 -2
- package/src/routing/scanner.ts +33 -9
- package/src/routing/schema-validation.ts +4 -4
- package/src/routing/segment-classify.ts +2 -2
- package/src/routing/segment-codegen.ts +1 -1
- package/src/routing/segment-keys.ts +1 -1
- package/src/routing/slot-placement.ts +1 -1
- package/src/routing/walkers.ts +1 -1
- package/src/rsc-runtime/transforms.ts +13 -0
- package/src/rsc-runtime/vendor-types.d.ts +12 -0
- package/src/schema-bridge.ts +1 -1
- package/src/search-params/define.ts +8 -8
- package/src/search-params/index.ts +3 -3
- package/src/search-params/wrappers.ts +3 -3
- package/src/server/access-gate.tsx +6 -6
- package/src/server/action-client.ts +5 -5
- package/src/server/action-handler.ts +16 -16
- package/src/server/actions.ts +5 -5
- package/src/server/als-registry.ts +8 -8
- package/src/server/asset-headers.ts +2 -2
- package/src/server/chain-url-parts.ts +5 -5
- package/src/server/children-interception.ts +4 -4
- package/src/server/compress.ts +1 -1
- package/src/server/cookie-context.ts +4 -4
- package/src/server/cookie-parsing.ts +2 -2
- package/src/server/default-logger.ts +3 -3
- package/src/server/deny-boundary.ts +10 -10
- package/src/server/deny-renderer.ts +38 -25
- package/src/server/early-hints-sender.ts +2 -2
- package/src/server/early-hints.ts +2 -2
- package/src/server/error-boundary-wrapper.ts +4 -12
- package/src/server/fallback-error.ts +13 -13
- package/src/server/flight-injection-state.ts +1 -1
- package/src/server/form-flash.ts +2 -2
- package/src/server/html-injector-core.ts +4 -4
- package/src/server/html-injectors.ts +5 -5
- package/src/server/index.ts +18 -18
- package/src/server/instrumentation.ts +1 -1
- package/src/server/internal.ts +50 -50
- package/src/server/logger.ts +4 -4
- package/src/server/metadata-collector.ts +7 -7
- package/src/server/metadata-platform.ts +2 -2
- package/src/server/metadata-render.ts +4 -4
- package/src/server/metadata-routes.ts +3 -3
- package/src/server/metadata-social.ts +2 -2
- package/src/server/metadata.ts +2 -2
- package/src/server/middleware-runner.ts +1 -1
- package/src/server/node-stream-transforms.ts +4 -4
- package/src/server/param-coercion.ts +8 -8
- package/src/server/pipeline-helpers.ts +7 -7
- package/src/server/pipeline-interception.ts +2 -2
- package/src/server/pipeline-metadata.ts +1 -1
- package/src/server/pipeline-outcome.ts +8 -8
- package/src/server/pipeline-phases.ts +24 -28
- package/src/server/pipeline.ts +22 -22
- package/src/server/prebuilt/cache-key.ts +1 -1
- package/src/server/prebuilt/capture-state.ts +1 -1
- package/src/server/prebuilt/key-discipline.ts +1 -1
- package/src/server/prebuilt/manifest-tag-index.ts +1 -1
- package/src/server/prebuilt/overlay.ts +6 -6
- package/src/server/prebuilt/payload-source.ts +2 -2
- package/src/server/prebuilt/slots.ts +5 -5
- package/src/server/prebuilt/synthetic-store.ts +2 -2
- package/src/server/prebuilt-builder.ts +16 -16
- package/src/server/prebuilt-runtime.ts +12 -12
- package/src/server/primitives.ts +7 -7
- package/src/server/publish-params.ts +3 -3
- package/src/server/request-context.ts +7 -7
- package/src/server/route-element-builder.ts +108 -50
- package/src/server/route-handler.ts +4 -4
- package/src/server/route-matcher.ts +5 -5
- package/src/server/rsc-cache-key-guard.ts +3 -5
- package/src/server/rsc-entry/action-middleware-runner.ts +7 -7
- package/src/server/rsc-entry/api-handler.ts +18 -9
- package/src/server/rsc-entry/deny-fallback.ts +10 -10
- package/src/server/rsc-entry/error-renderer.ts +27 -27
- package/src/server/rsc-entry/helpers.ts +10 -10
- package/src/server/rsc-entry/index.ts +51 -47
- package/src/server/rsc-entry/render-route.ts +20 -20
- package/src/server/rsc-entry/revalidate-renderer.ts +12 -12
- package/src/server/rsc-entry/rsc-payload.ts +19 -15
- package/src/server/rsc-entry/rsc-stream.ts +8 -8
- package/src/server/rsc-entry/ssr-bridge.ts +3 -3
- package/src/server/rsc-entry/ssr-renderer.ts +23 -23
- package/src/server/rsc-entry/wrap-action-dispatch.ts +9 -9
- package/src/server/rsc-prop-warnings.ts +1 -1
- package/src/server/sensitive-fields.ts +1 -1
- package/src/server/server-timing.ts +1 -1
- package/src/server/sitemap-generator.ts +3 -3
- package/src/server/sitemap-handler.ts +3 -3
- package/src/server/skippable-prefix.ts +7 -7
- package/src/server/slot-interception.ts +5 -5
- package/src/server/slot-resolver.ts +20 -28
- package/src/server/ssr-bridge-types.ts +2 -2
- package/src/server/ssr-entry.ts +18 -18
- package/src/server/ssr-render.ts +4 -4
- package/src/server/ssr-wrappers.tsx +1 -1
- package/src/server/state-tree-diff.ts +1 -1
- package/src/server/static-generator.ts +6 -6
- package/src/server/static-not-found.ts +3 -3
- package/src/server/status-code-resolver.ts +1 -1
- package/src/server/tracing.ts +5 -5
- package/src/server/tree-builder.ts +4 -4
- package/src/server/tree-match.ts +1 -1
- package/src/server/types.ts +2 -2
- package/src/server/utils/mdx-file.ts +2 -2
- package/src/server/waituntil-bridge.ts +1 -1
- package/src/server/workers-cache-bridge.ts +2 -2
- package/src/shared/als-slots.ts +1 -1
- package/src/shared/payload-root.ts +2 -2
- package/src/shared/rsc-media-type.ts +16 -0
- package/src/shared/slot-params.ts +1 -1
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +1 -1
- package/src/shims/navigation-client.ts +5 -5
- package/src/shims/navigation.ts +2 -2
- package/dist/_chunks/actions-BjbbNRFN.js.map +0 -1
- package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +0 -1
- package/dist/_chunks/cache-api-DllJ-Lyw.js.map +0 -1
- package/dist/_chunks/cli-check-DJZDc22E.js.map +0 -1
- package/dist/_chunks/convention-lint-CpteIpTm.js.map +0 -1
- package/dist/_chunks/dist-BA3u1z3W.js +0 -423
- package/dist/_chunks/dist-BA3u1z3W.js.map +0 -1
- package/dist/_chunks/mdx-file-C005ay-P.js.map +0 -1
- package/dist/_chunks/plugin-context-rCinWLiE.js.map +0 -1
- package/dist/_chunks/scanner-CAietmj4.js.map +0 -1
- package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +0 -1
- package/dist/content/index.d.ts +0 -2
- package/dist/content/index.d.ts.map +0 -1
- package/dist/content/index.js +0 -0
- package/src/content/index.ts +0 -5
- package/src/shims/server-only-noop.js +0 -6
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import type { Plugin } from 'vite';
|
|
27
|
-
import type { PluginContext } from '../../plugin-context.
|
|
28
|
-
import type { ProgramNode } from '../callsite-ast.
|
|
29
|
-
import { analyzeModule, usedSources, contributesNothing, type ModuleFacts } from './analysis.
|
|
30
|
-
import { createOriginResolver, FRAMEWORK_SOURCES } from './origin.
|
|
31
|
-
|
|
32
|
-
export type { ModuleFacts } from './analysis.
|
|
33
|
-
export { analyzeModule, usedSources } from './analysis.
|
|
34
|
-
export { createOriginResolver } from './origin.
|
|
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.
|
|
19
|
+
import type { CalleeRef, ImportEdge, ModuleFacts } from './analysis.ts';
|
|
20
20
|
|
|
21
21
|
// ─── What counts as a request accessor ───────────────────────────────────
|
|
22
22
|
|
package/src/plugins/routing.ts
CHANGED
|
@@ -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.
|
|
14
|
-
import { buildDirToRouteMap, type SegmentInfo } from '../routing/segment-codegen.
|
|
15
|
-
import { writeRouteCodegen, flushCodegenWrites } from '../routing/codegen-write.
|
|
16
|
-
import { validateSchemaAgainstRoutes } from '../routing/schema-validation.
|
|
17
|
-
import { generateManifestModule, generateSchemaModule } from '../routing/manifest-codegen.
|
|
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.
|
|
23
|
-
import type { PluginContext } from '../plugin-context.
|
|
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: [
|
|
90
|
+
noExternal: [...POISON_MARKER_SPECIFIERS],
|
|
84
91
|
},
|
|
85
92
|
},
|
|
86
93
|
ssr: {
|
|
87
94
|
resolve: {
|
|
88
|
-
noExternal: [
|
|
95
|
+
noExternal: [...POISON_MARKER_SPECIFIERS, 'nuqs'],
|
|
89
96
|
},
|
|
90
97
|
},
|
|
91
98
|
},
|
package/src/plugins/shims.ts
CHANGED
|
@@ -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.
|
|
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
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* -
|
|
37
|
-
*
|
|
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 = '
|
|
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
|
-
|
|
195
|
-
|
|
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
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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.
|
|
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.
|
|
24
|
-
import { mergeRscAssetsManifest } from './adapter-build.
|
|
25
|
-
import { isRelativeBase, normalizeBasePath, withBasePath } from '../shared/base-path.
|
|
26
|
-
import type { RscManifest, RscManifestEntry } from '../shared/rsc-manifest.
|
|
27
|
-
import { htmlEscapeJsonString } from '../server/flight-scripts.
|
|
28
|
-
import { rscPayloadPath } from '../shared/rsc-payload-path.
|
|
29
|
-
import { REDIRECTS_FILE, RESERVED_OUTPUT_PATHS } from '../shared/static-platform-files.
|
|
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.
|
|
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.
|
|
48
|
+
export type { RscManifestEntry, RscManifest } from '../shared/rsc-manifest.ts';
|
|
49
49
|
|
|
50
50
|
export interface StaticValidationError {
|
|
51
51
|
type: 'dynamic-api';
|
|
@@ -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.
|
|
21
|
-
import { writeSegmentTypes } from './segment-codegen.
|
|
22
|
-
import type { RouteTree } from './types.
|
|
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
|
package/src/routing/codegen.ts
CHANGED
|
@@ -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.
|
|
14
|
-
import type { ParamEntry, RouteEntry } from './codegen-types.
|
|
15
|
-
import { buildSchemaParamType } from './codegen-shared.
|
|
16
|
-
import { effectiveUrlSegment, type UrlSegmentIdentity } from './segment-classify.
|
|
17
|
-
import { formatLinkCatchAllOverloads, formatTypedLinkOverloads } from './link-codegen.
|
|
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.
|
|
45
|
-
import { effectiveUrlSegment } from './segment-classify.
|
|
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.
|
|
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.
|
|
15
|
-
import { computeInterceptedUrlBase } from './interception.
|
|
16
|
-
import { findOrderDependentCollision, type ProbeLeaf } from './collision-probe.
|
|
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.
|
|
22
|
-
import { swallow } from '../server/logger.
|
|
23
|
-
import { isMdxFilePath } from '../server/utils/mdx-file.
|
|
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.
|
|
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:
|
|
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
|
/**
|
package/src/routing/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { scanRoutes } from './scanner.
|
|
2
|
-
export { generateRouteMap } from './codegen.
|
|
3
|
-
export type { CodegenOptions } from './codegen.
|
|
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.
|
|
12
|
-
export { DEFAULT_PAGE_EXTENSIONS, INTERCEPTION_MARKERS } from './types.
|
|
13
|
-
export { collectInterceptionRewrites } from './interception.
|
|
14
|
-
export type { InterceptionRewrite } from './interception.
|
|
15
|
-
export { classifyUrlSegment, classifySegment } from './segment-classify.
|
|
16
|
-
export type { UrlSegment, SegmentClassification } from './segment-classify.
|
|
17
|
-
export { collectLeafRoutes } from './walkers.
|
|
18
|
-
export type { LeafRoute, CollectLeafRoutesOptions } from './walkers.
|
|
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.
|
|
23
|
-
export type { SchemaWarning } from './schema-validation.
|
|
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.
|
|
21
|
-
import { computeSegmentTreePaths, treePathDepth } from './segment-keys.
|
|
22
|
-
import { classifyUrlSegment, effectiveUrlSegment } from './segment-classify.
|
|
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.
|
|
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.
|
|
27
|
-
import { buildSchemaParamType } from './codegen-shared.
|
|
28
|
-
import { classifyUrlSegment } from './segment-classify.
|
|
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.
|
|
14
|
-
import type { RouteTree, SegmentNode, RouteFile } from './types.
|
|
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.
|