@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
package/dist/index.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { r as
|
|
1
|
+
import { l as registerDevDiscovery } from "./_chunks/graph-cache-CP4GEmf9.js";
|
|
2
|
+
import { n as isScannableSourceFile, t as buildSourceExtensions } from "./_chunks/scan-BoP17W3w.js";
|
|
3
|
+
import { t as RSC_CONTENT_TYPE } from "./_chunks/rsc-media-type-DDc7duTD.js";
|
|
4
|
+
import { a as canonicalize, d as isMetadataRouteServePath, u as isDynamicMetadataExtension } from "./_chunks/segment-keys-BhqoHiLc.js";
|
|
5
|
+
import { i as matchUrlParts, n as scanRoutes, r as collectInterceptionRewrites } from "./_chunks/scanner-BRIOmHE2.js";
|
|
6
|
+
import { t as MDX_EXTENSIONS } from "./_chunks/mdx-file-CXyHGUpS.js";
|
|
7
|
+
import { h as swallow } from "./_chunks/logger-pumCm3Il.js";
|
|
8
|
+
import { c as writeRouteCodegen, i as getPrerenderExport, l as buildDirToRouteMap, n as formatConventionWarnings, r as lintConventions, s as flushCodegenWrites, t as checkAppDirExists } from "./_chunks/convention-lint-DO10_pVl.js";
|
|
9
|
+
import { c as resolveClientJavascript, i as mergeFileConfig, l as createNoopTimer, o as resolveAppDir, r as loadTimberConfigFile, s as resolveBuildDir, t as createPluginContext } from "./_chunks/plugin-context-8idfR3UZ.js";
|
|
10
|
+
import { r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "./_chunks/walkers-BU6z9xRV.js";
|
|
11
|
+
import { i as poisonPillSource, r as markerFor, t as EXPLICIT_MARKERS } from "./_chunks/poison-rules-DoEhbqaY.js";
|
|
9
12
|
import { i as withBasePath, n as normalizeBasePath, t as isRelativeBase } from "./_chunks/base-path-DaQrzbez.js";
|
|
10
13
|
import { t as rscPayloadPath } from "./_chunks/rsc-payload-path-B_LBodc2.js";
|
|
11
14
|
import { a as REDIRECTS_FILE, n as detectFsIdentity, o as RESERVED_OUTPUT_PATHS, r as fsKey, t as EXACT_FS_IDENTITY } from "./_chunks/fs-identity-D7vb6GdI.js";
|
|
12
15
|
import { t as EMPTY_BUILD_MANIFEST } from "./_chunks/build-manifest-DWppEdLB.js";
|
|
13
16
|
import { t as fnv1aHash } from "./_chunks/fast-hash-C-tVYrLb.js";
|
|
14
|
-
import { t as formatSize } from "./_chunks/format-
|
|
15
|
-
import { createLogger, parseAst } from "vite";
|
|
17
|
+
import { t as formatSize } from "./_chunks/format-BKclgVbk.js";
|
|
18
|
+
import { createLogger, normalizePath, parseAst } from "vite";
|
|
16
19
|
import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve, win32 } from "node:path";
|
|
17
20
|
import { builtinModules, createRequire } from "node:module";
|
|
18
|
-
import react
|
|
19
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
21
|
+
import react from "@vitejs/plugin-react";
|
|
22
|
+
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
20
23
|
import nodeHTTP from "node:http";
|
|
21
24
|
import { Readable, pipeline } from "node:stream";
|
|
22
25
|
import { pipeline as pipeline$1 } from "node:stream/promises";
|
|
@@ -24,9 +27,10 @@ import "node:https";
|
|
|
24
27
|
import "node:http2";
|
|
25
28
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
26
29
|
import { styleText } from "node:util";
|
|
27
|
-
import { constants, createGzip, gzipSync } from "node:zlib";
|
|
28
30
|
import { createHash, randomUUID } from "node:crypto";
|
|
29
|
-
import { copyFile, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
31
|
+
import { copyFile, mkdir, readFile, readdir, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
32
|
+
import { isIP } from "node:net";
|
|
33
|
+
import { constants, createGzip, gzipSync } from "node:zlib";
|
|
30
34
|
//#region src/plugins/content.ts
|
|
31
35
|
var CONFIG_FILE_NAMES$1 = [
|
|
32
36
|
"content-collections.ts",
|
|
@@ -106,13 +110,14 @@ function timberContent(ctx) {
|
|
|
106
110
|
return null;
|
|
107
111
|
},
|
|
108
112
|
async configureServer(server) {
|
|
113
|
+
if (process.env.TIMBER_ANALYZE === "1") return;
|
|
109
114
|
if (!innerPlugin) return;
|
|
110
115
|
if (typeof innerPlugin.configureServer === "function") await innerPlugin.configureServer.call(this, server);
|
|
111
116
|
}
|
|
112
117
|
};
|
|
113
118
|
}
|
|
114
119
|
//#endregion
|
|
115
|
-
//#region ../../node_modules/.pnpm/srvx@0.12.
|
|
120
|
+
//#region ../../node_modules/.pnpm/srvx@0.12.7/node_modules/srvx/dist/adapters/node.mjs
|
|
116
121
|
function sendNodeResponse(nodeRes, webRes) {
|
|
117
122
|
try {
|
|
118
123
|
return _sendNodeResponse(nodeRes, webRes, false) || Promise.resolve();
|
|
@@ -143,8 +148,14 @@ function _sendNodeResponse(nodeRes, webRes, detached) {
|
|
|
143
148
|
return webRes.body ? streamBody(webRes.body, nodeRes) : endNodeResponse(nodeRes, detached);
|
|
144
149
|
}
|
|
145
150
|
function writeHead(nodeRes, status, statusText, rawHeaders) {
|
|
146
|
-
if (!nodeRes.headersSent)
|
|
147
|
-
|
|
151
|
+
if (!nodeRes.headersSent) {
|
|
152
|
+
if (nodeRes.req?.httpVersion === "2.0") nodeRes.writeHead(status, rawHeaders);
|
|
153
|
+
else nodeRes.writeHead(status, safeStatusText(statusText), rawHeaders);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
var INVALID_REASON_PHRASE_RE = /[^\t\u0020-\u007E\u0080-\u00FF]/g;
|
|
157
|
+
function safeStatusText(statusText) {
|
|
158
|
+
return typeof statusText === "string" && statusText ? statusText.replace(INVALID_REASON_PHRASE_RE, "") : statusText;
|
|
148
159
|
}
|
|
149
160
|
function endNodeResponse(nodeRes, detached) {
|
|
150
161
|
if (detached) {
|
|
@@ -158,6 +169,12 @@ function pipeBody(stream, nodeRes, status, statusText, headers) {
|
|
|
158
169
|
stream.destroy?.();
|
|
159
170
|
return;
|
|
160
171
|
}
|
|
172
|
+
if (nodeRes.req?.method === "HEAD") {
|
|
173
|
+
if (typeof stream.destroy === "function") stream.destroy();
|
|
174
|
+
else stream.abort?.();
|
|
175
|
+
writeHead(nodeRes, status, statusText, headers);
|
|
176
|
+
return endNodeResponse(nodeRes);
|
|
177
|
+
}
|
|
161
178
|
if (typeof stream.on !== "function" || typeof stream.destroy !== "function") {
|
|
162
179
|
writeHead(nodeRes, status, statusText, headers);
|
|
163
180
|
stream.pipe(nodeRes);
|
|
@@ -168,14 +185,19 @@ function pipeBody(stream, nodeRes, status, statusText, headers) {
|
|
|
168
185
|
return endNodeResponse(nodeRes);
|
|
169
186
|
}
|
|
170
187
|
return new Promise((resolve) => {
|
|
171
|
-
function
|
|
188
|
+
function cleanup() {
|
|
189
|
+
stream.off("error", onEarlyError);
|
|
172
190
|
stream.off("readable", onReadable);
|
|
191
|
+
nodeRes.off("close", onResClose);
|
|
192
|
+
}
|
|
193
|
+
function onEarlyError() {
|
|
194
|
+
cleanup();
|
|
173
195
|
stream.destroy();
|
|
174
196
|
writeHead(nodeRes, 500, "Internal Server Error", []);
|
|
175
197
|
endNodeResponse(nodeRes).then(resolve);
|
|
176
198
|
}
|
|
177
199
|
function onReadable() {
|
|
178
|
-
|
|
200
|
+
cleanup();
|
|
179
201
|
if (nodeRes.destroyed) {
|
|
180
202
|
stream.destroy();
|
|
181
203
|
return resolve();
|
|
@@ -183,8 +205,14 @@ function pipeBody(stream, nodeRes, status, statusText, headers) {
|
|
|
183
205
|
writeHead(nodeRes, status, statusText, headers);
|
|
184
206
|
pipeline$1(stream, nodeRes).catch(() => {}).then(() => resolve());
|
|
185
207
|
}
|
|
208
|
+
function onResClose() {
|
|
209
|
+
cleanup();
|
|
210
|
+
stream.destroy();
|
|
211
|
+
resolve();
|
|
212
|
+
}
|
|
186
213
|
stream.once("error", onEarlyError);
|
|
187
214
|
stream.once("readable", onReadable);
|
|
215
|
+
nodeRes.once("close", onResClose);
|
|
188
216
|
});
|
|
189
217
|
}
|
|
190
218
|
function streamBody(stream, nodeRes) {
|
|
@@ -397,7 +425,8 @@ var _traceMapping = null;
|
|
|
397
425
|
*/
|
|
398
426
|
function getTraceMapping() {
|
|
399
427
|
if (_traceMapping) return _traceMapping;
|
|
400
|
-
|
|
428
|
+
const vitePath = createRequire(import.meta.url).resolve("vite");
|
|
429
|
+
_traceMapping = createRequire(vitePath)("@jridgewell/trace-mapping");
|
|
401
430
|
return _traceMapping;
|
|
402
431
|
}
|
|
403
432
|
/** Labels for terminal output. */
|
|
@@ -1143,13 +1172,31 @@ var ERROR_CSS = `
|
|
|
1143
1172
|
*
|
|
1144
1173
|
* Design doc: 18-build-system.md
|
|
1145
1174
|
*/
|
|
1146
|
-
var
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1175
|
+
var knownKeys = new Set(Object.keys({
|
|
1176
|
+
output: true,
|
|
1177
|
+
debug: true,
|
|
1178
|
+
clientJavascript: true,
|
|
1179
|
+
adapter: true,
|
|
1180
|
+
allowedOrigins: true,
|
|
1181
|
+
csrf: true,
|
|
1182
|
+
limits: true,
|
|
1183
|
+
forms: true,
|
|
1184
|
+
pageExtensions: true,
|
|
1185
|
+
slowRequestMs: true,
|
|
1186
|
+
renderTimeoutMs: true,
|
|
1187
|
+
devBrowserLogs: true,
|
|
1188
|
+
dev: true,
|
|
1189
|
+
serverTiming: true,
|
|
1190
|
+
appDir: true,
|
|
1191
|
+
mdx: true,
|
|
1192
|
+
actionEncryption: true,
|
|
1193
|
+
reactCompiler: true,
|
|
1194
|
+
sitemap: true,
|
|
1195
|
+
buildDir: true,
|
|
1196
|
+
clientSegmentCache: true,
|
|
1197
|
+
topLoader: true,
|
|
1198
|
+
budget: true
|
|
1199
|
+
}));
|
|
1153
1200
|
/**
|
|
1154
1201
|
* Validate a TimberUserConfig object.
|
|
1155
1202
|
*
|
|
@@ -1164,29 +1211,31 @@ function validateConfig(config) {
|
|
|
1164
1211
|
value: config.output,
|
|
1165
1212
|
suggestion: "Use output: \"server\" (default) or output: \"static\" for static site generation."
|
|
1166
1213
|
});
|
|
1167
|
-
if (config.pageExtensions !== void 0)
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1214
|
+
if (config.pageExtensions !== void 0) {
|
|
1215
|
+
if (!Array.isArray(config.pageExtensions)) errors.push({
|
|
1216
|
+
field: "pageExtensions",
|
|
1217
|
+
message: "pageExtensions must be an array of strings.",
|
|
1218
|
+
value: config.pageExtensions,
|
|
1219
|
+
suggestion: "Example: pageExtensions: [\"tsx\", \"ts\", \"jsx\", \"js\", \"mdx\"]"
|
|
1220
|
+
});
|
|
1221
|
+
else for (const ext of config.pageExtensions) {
|
|
1222
|
+
if (typeof ext !== "string") {
|
|
1223
|
+
errors.push({
|
|
1224
|
+
field: "pageExtensions",
|
|
1225
|
+
message: `pageExtensions contains a non-string value: ${JSON.stringify(ext)}`,
|
|
1226
|
+
value: ext
|
|
1227
|
+
});
|
|
1228
|
+
break;
|
|
1229
|
+
}
|
|
1230
|
+
if (ext.startsWith(".")) {
|
|
1231
|
+
errors.push({
|
|
1232
|
+
field: "pageExtensions",
|
|
1233
|
+
message: `pageExtensions should not include the leading dot: "${ext}"`,
|
|
1234
|
+
value: ext,
|
|
1235
|
+
suggestion: `Use "${ext.slice(1)}" instead of "${ext}".`
|
|
1236
|
+
});
|
|
1237
|
+
break;
|
|
1238
|
+
}
|
|
1190
1239
|
}
|
|
1191
1240
|
}
|
|
1192
1241
|
if (config.slowRequestMs !== void 0) {
|
|
@@ -1255,6 +1304,10 @@ function validateConfig(config) {
|
|
|
1255
1304
|
});
|
|
1256
1305
|
return errors;
|
|
1257
1306
|
}
|
|
1307
|
+
var RED = "\x1B[31m";
|
|
1308
|
+
var BOLD = "\x1B[1m";
|
|
1309
|
+
var DIM = "\x1B[2m";
|
|
1310
|
+
var RESET = "\x1B[0m";
|
|
1258
1311
|
/**
|
|
1259
1312
|
* Format config errors for terminal output.
|
|
1260
1313
|
*/
|
|
@@ -1269,6 +1322,16 @@ function formatConfigErrors(errors) {
|
|
|
1269
1322
|
}
|
|
1270
1323
|
return lines.join("\n");
|
|
1271
1324
|
}
|
|
1325
|
+
var VIRTUAL_MODULE_NAMES = {
|
|
1326
|
+
"virtual:timber-rsc-entry": "RSC entry (server component handler)",
|
|
1327
|
+
"virtual:timber-ssr-entry": "SSR entry (HTML renderer)",
|
|
1328
|
+
"virtual:timber-browser-entry": "Browser entry (client hydration)",
|
|
1329
|
+
"virtual:timber-config": "Runtime config (timber.config.ts)",
|
|
1330
|
+
"virtual:timber-route-manifest": "Route manifest (app/ file tree)",
|
|
1331
|
+
"virtual:timber-instrumentation": "Instrumentation (instrumentation.ts)",
|
|
1332
|
+
"virtual:timber-cache-handler": "Cache handler (timber.cache.ts)",
|
|
1333
|
+
"virtual:timber-build-manifest": "Build manifest (asset mapping)"
|
|
1334
|
+
};
|
|
1272
1335
|
/**
|
|
1273
1336
|
* Add timber-specific context to an error message that references virtual modules.
|
|
1274
1337
|
*
|
|
@@ -1280,6 +1343,15 @@ function addVirtualModuleContext(errorMessage) {
|
|
|
1280
1343
|
return errorMessage;
|
|
1281
1344
|
}
|
|
1282
1345
|
/**
|
|
1346
|
+
* Required (non-optional) peer dependencies that must be installed.
|
|
1347
|
+
*/
|
|
1348
|
+
var REQUIRED_PEERS = [
|
|
1349
|
+
"react",
|
|
1350
|
+
"react-dom",
|
|
1351
|
+
"@vitejs/plugin-react",
|
|
1352
|
+
"@vitejs/plugin-rsc"
|
|
1353
|
+
];
|
|
1354
|
+
/**
|
|
1283
1355
|
* Check that required peer dependencies are installed.
|
|
1284
1356
|
*
|
|
1285
1357
|
* Uses require.resolve with a try/catch — no fs scanning.
|
|
@@ -1318,57 +1390,325 @@ function formatMissingPeers(results) {
|
|
|
1318
1390
|
lines.push(` ${BOLD}pnpm add ${names.join(" ")}${RESET}`);
|
|
1319
1391
|
return lines.join("\n");
|
|
1320
1392
|
}
|
|
1321
|
-
|
|
1322
|
-
var
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1393
|
+
/** HMR custom event name for graph-affecting file changes. */
|
|
1394
|
+
var GRAPH_UPDATE_EVENT = "timber:graph-update";
|
|
1395
|
+
/**
|
|
1396
|
+
* Host-header allowlist check, ported branch-for-branch from Vite's
|
|
1397
|
+
* host-validation middleware (`isHostAllowedWithoutCache`) so this
|
|
1398
|
+
* endpoint's reachability matches the rest of the dev server:
|
|
1399
|
+
*
|
|
1400
|
+
* - `allowedHosts: true` allows everything
|
|
1401
|
+
* - a MISSING Host header is allowed (Vite parity — HTTP/1.0 probes)
|
|
1402
|
+
* - any IP-literal host is allowed (`vite --host` LAN access sends
|
|
1403
|
+
* `Host: 192.168.x.x:port`; rejecting it would 403 this endpoint
|
|
1404
|
+
* while every other dev route works)
|
|
1405
|
+
* - `localhost` and `*.localhost` are always allowed
|
|
1406
|
+
* - allowedHosts entries: exact match, or `.suffix` subdomain entries
|
|
1407
|
+
*/
|
|
1408
|
+
function isAllowedGraphHost(hostHeader, allowedHosts) {
|
|
1409
|
+
if (allowedHosts === true) return true;
|
|
1410
|
+
if (hostHeader === void 0) return true;
|
|
1411
|
+
let host = hostHeader;
|
|
1412
|
+
const bracket = host.match(/^\[([^\]]+)\](?::\d+)?$/);
|
|
1413
|
+
if (bracket) return isIP(bracket[1]) === 6;
|
|
1414
|
+
const colon = host.lastIndexOf(":");
|
|
1415
|
+
if (colon !== -1) host = host.slice(0, colon);
|
|
1416
|
+
host = host.toLowerCase();
|
|
1417
|
+
if (isIP(host) !== 0) return true;
|
|
1418
|
+
if (host === "localhost" || host.endsWith(".localhost")) return true;
|
|
1419
|
+
for (const entry of allowedHosts ?? []) {
|
|
1420
|
+
const allowed = entry.toLowerCase();
|
|
1421
|
+
if (allowed.startsWith(".")) {
|
|
1422
|
+
if (host === allowed.slice(1) || host.endsWith(allowed)) return true;
|
|
1423
|
+
} else if (host === allowed) return true;
|
|
1424
|
+
}
|
|
1425
|
+
return false;
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Non-http(s) origins admitted without a host check: Vite's own
|
|
1429
|
+
* `file:` / `*-extension:` set (its host-validation regex), plus
|
|
1430
|
+
* `vscode-webview:` — VS Code webviews fetch with that Origin, and the
|
|
1431
|
+
* extension is this endpoint's primary consumer. Vite itself never
|
|
1432
|
+
* origin-checks plain HTTP GETs (only WebSocket upgrades), so this
|
|
1433
|
+
* layer is strictly additional; the additions keep it from rejecting
|
|
1434
|
+
* consumers Vite would serve.
|
|
1435
|
+
*
|
|
1436
|
+
* NOT admitted: `Origin: null`. Browsers serialize file:// pages'
|
|
1437
|
+
* opaque origin as the literal string `null` — but so do sandboxed
|
|
1438
|
+
* iframes and data: documents, exactly the untrusted embedders the
|
|
1439
|
+
* check exists to stop, and the header offers nothing to tell them
|
|
1440
|
+
* apart. file:// pages therefore cannot use this endpoint from a
|
|
1441
|
+
* browser; the `file:` scheme entry covers non-browser clients that
|
|
1442
|
+
* send a real scheme-form Origin (Vite admits the same set).
|
|
1443
|
+
*/
|
|
1444
|
+
var TRUSTED_ORIGIN_SCHEMES = /^(?:file|vscode-webview|.+-extension):/i;
|
|
1445
|
+
/** Origin check: absent is fine (CLI probe); present must pass the host allowlist. */
|
|
1446
|
+
function isAllowedGraphOrigin(originHeader, allowedHosts) {
|
|
1447
|
+
if (originHeader === void 0) return true;
|
|
1448
|
+
if (TRUSTED_ORIGIN_SCHEMES.test(originHeader)) return true;
|
|
1449
|
+
let originUrl;
|
|
1450
|
+
try {
|
|
1451
|
+
originUrl = new URL(originHeader);
|
|
1452
|
+
} catch {
|
|
1453
|
+
return false;
|
|
1454
|
+
}
|
|
1455
|
+
if (originUrl.host === "") return false;
|
|
1456
|
+
const bareHost = originUrl.hostname.replace(/^\[|\]$/g, "");
|
|
1457
|
+
if (isIP(bareHost) !== 0) {
|
|
1458
|
+
if (bareHost === "127.0.0.1" || bareHost === "::1") return true;
|
|
1459
|
+
if (allowedHosts === true) return true;
|
|
1460
|
+
return (allowedHosts ?? []).some((entry) => entry.toLowerCase() === bareHost);
|
|
1461
|
+
}
|
|
1462
|
+
return isAllowedGraphHost(originUrl.host, allowedHosts);
|
|
1463
|
+
}
|
|
1464
|
+
function sendJson(res, status, body) {
|
|
1465
|
+
res.statusCode = status;
|
|
1466
|
+
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
1467
|
+
res.end(JSON.stringify(body));
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Echo an ADMITTED origin back as CORS headers. A webview fetch from
|
|
1471
|
+
* `vscode-webview://…` passes the origin check but the browser rejects
|
|
1472
|
+
* the response body without `Access-Control-Allow-Origin` — the exact
|
|
1473
|
+
* transport design/47 specifies for the extension. Only the validated
|
|
1474
|
+
* origin is echoed (never `*`), with `Vary: Origin` for any cache in
|
|
1475
|
+
* between; unadmitted origins were already 403'd and get nothing.
|
|
1476
|
+
*/
|
|
1477
|
+
function reflectCors(res, origin) {
|
|
1478
|
+
if (!origin) return;
|
|
1479
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
1480
|
+
res.setHeader("Vary", "Origin");
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Create the Connect middleware handling GET /__timber/graph.
|
|
1484
|
+
*
|
|
1485
|
+
* Query surface: `?file=<path>` (absolute or project-root-relative) or
|
|
1486
|
+
* `?all=1`. Anything else is a 400 — fail loudly, like the CLI.
|
|
1487
|
+
*/
|
|
1488
|
+
function createGraphEndpointMiddleware(server, ctx) {
|
|
1489
|
+
const sourceExtensions = buildSourceExtensions(ctx.config.pageExtensions);
|
|
1490
|
+
return async (req, res, next) => {
|
|
1491
|
+
const rawUrl = req.url;
|
|
1492
|
+
if (!rawUrl || !rawUrl.startsWith("/__timber/")) {
|
|
1493
|
+
next();
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
const url = new URL(rawUrl, "http://placeholder.invalid");
|
|
1497
|
+
if (url.pathname !== "/__timber/graph") {
|
|
1498
|
+
sendJson(res, 404, { error: `unknown /__timber/ endpoint: ${url.pathname}` });
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
if (req.method !== "GET") {
|
|
1502
|
+
res.setHeader("Allow", "GET");
|
|
1503
|
+
sendJson(res, 405, { error: "GET only" });
|
|
1504
|
+
return;
|
|
1505
|
+
}
|
|
1506
|
+
const origin = req.headers.origin;
|
|
1507
|
+
const allowedHosts = server.config.server.allowedHosts;
|
|
1508
|
+
if (!server.config.server.https && !isAllowedGraphHost(req.headers.host, allowedHosts)) {
|
|
1509
|
+
sendJson(res, 403, { error: "host not allowed" });
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
if (!isAllowedGraphOrigin(origin, allowedHosts)) {
|
|
1513
|
+
sendJson(res, 403, { error: "origin not allowed" });
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
reflectCors(res, origin);
|
|
1517
|
+
try {
|
|
1518
|
+
const { classifyLiveFile, classifyLiveProject } = await import("./_chunks/live-graph-Bx4HodF1.js");
|
|
1519
|
+
const preserveSymlinks = server.config.resolve.preserveSymlinks;
|
|
1520
|
+
const root = normalizePath(preserveSymlinks ? ctx.root : await realpath(ctx.root));
|
|
1521
|
+
const appDir = normalizePath(preserveSymlinks ? ctx.appDir : await realpath(ctx.appDir).catch(() => join(root, relative(ctx.root, ctx.appDir))));
|
|
1522
|
+
const liveCtx = {
|
|
1523
|
+
rsc: server.environments.rsc.moduleGraph,
|
|
1524
|
+
ssr: server.environments.ssr.moduleGraph,
|
|
1525
|
+
client: server.environments.client.moduleGraph,
|
|
1526
|
+
root,
|
|
1527
|
+
appDir,
|
|
1528
|
+
pageExtensions: ctx.config.pageExtensions
|
|
1529
|
+
};
|
|
1530
|
+
const allParam = url.searchParams.get("all");
|
|
1531
|
+
if (allParam !== null && allParam !== "1") {
|
|
1532
|
+
sendJson(res, 400, { error: `unsupported all value: ${allParam} (use ?all=1)` });
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
if (allParam === "1") {
|
|
1536
|
+
sendJson(res, 200, {
|
|
1537
|
+
version: 1,
|
|
1538
|
+
source: "dev-server",
|
|
1539
|
+
cached: false,
|
|
1540
|
+
...await classifyLiveProject(liveCtx)
|
|
1541
|
+
});
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
const fileParam = url.searchParams.get("file");
|
|
1545
|
+
if (!fileParam) {
|
|
1546
|
+
sendJson(res, 400, { error: "missing ?file=<path> (or ?all=1)" });
|
|
1547
|
+
return;
|
|
1548
|
+
}
|
|
1549
|
+
const absolute = normalizePath(isAbsolute(fileParam) ? resolve(fileParam) : resolve(root, fileParam));
|
|
1550
|
+
let target;
|
|
1551
|
+
try {
|
|
1552
|
+
const physical = normalizePath(await realpath(absolute));
|
|
1553
|
+
const rootPhysical = preserveSymlinks ? normalizePath(await realpath(root)) : root;
|
|
1554
|
+
if (physical !== rootPhysical && !physical.startsWith(rootPhysical + "/") && !physical.startsWith(rootPhysical + "\\")) {
|
|
1555
|
+
sendJson(res, 404, { error: `not a project file under ${root}` });
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
if (preserveSymlinks) {
|
|
1559
|
+
if (physical !== rootPhysical + absolute.slice(root.length)) {
|
|
1560
|
+
sendJson(res, 404, { error: `not a project source file: ${absolute}` });
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
target = normalizePath(preserveSymlinks ? absolute : physical);
|
|
1565
|
+
} catch {
|
|
1566
|
+
sendJson(res, 404, { error: `file not found: ${absolute}` });
|
|
1567
|
+
return;
|
|
1568
|
+
}
|
|
1569
|
+
if (target !== root && !target.startsWith(root + "/") && !target.startsWith(root + "\\")) {
|
|
1570
|
+
sendJson(res, 404, { error: `not a project file under ${root}` });
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
if (!(await stat(target).catch(() => null))?.isFile() || !isScannableSourceFile(normalizePath(target), normalizePath(root), sourceExtensions)) {
|
|
1574
|
+
sendJson(res, 404, { error: `not a project source file: ${target}` });
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
const errors = [];
|
|
1578
|
+
const module = await classifyLiveFile(target, liveCtx, void 0, errors);
|
|
1579
|
+
sendJson(res, 200, {
|
|
1580
|
+
version: 1,
|
|
1581
|
+
source: "dev-server",
|
|
1582
|
+
cached: false,
|
|
1583
|
+
target: {
|
|
1584
|
+
input: fileParam,
|
|
1585
|
+
resolved: target
|
|
1586
|
+
},
|
|
1587
|
+
kind: module.kind,
|
|
1588
|
+
pending: module.pending,
|
|
1589
|
+
subtreeUnknown: module.subtreeUnknown,
|
|
1590
|
+
envs: module.envs,
|
|
1591
|
+
boundary: module.boundary,
|
|
1592
|
+
chains: module.chains,
|
|
1593
|
+
poisonings: module.poisonings,
|
|
1594
|
+
errors
|
|
1595
|
+
});
|
|
1596
|
+
} catch (error) {
|
|
1597
|
+
sendJson(res, 500, { error: error instanceof Error ? error.message : String(error) });
|
|
1598
|
+
}
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Build the push channel: `timber:graph-update` custom HMR events per
|
|
1603
|
+
* project-source change. Consumers (the VS Code extension) re-query
|
|
1604
|
+
* and debounce on their side; the channel just emits. Non-source noise
|
|
1605
|
+
* (build output, dotdirs) is filtered by the same extension set the
|
|
1606
|
+
* scanners use.
|
|
1607
|
+
*
|
|
1608
|
+
* Two phases per edit, because one is not enough (codex review, PR
|
|
1609
|
+
* #1057): the `invalidated` event fires from the plugin's `hotUpdate`
|
|
1610
|
+
* hook — after Vite clears the module's transform result, but its
|
|
1611
|
+
* importer EDGES are only rebuilt when the module is next transformed.
|
|
1612
|
+
* The `transformed` event fires for exactly the files with a pending
|
|
1613
|
+
* invalidation, and only once the node's `transformResult` is set
|
|
1614
|
+
* again — the plugin transform hook itself runs BEFORE Vite's trailing
|
|
1615
|
+
* `vite:import-analysis` (which rebuilds the edges), so the hook only
|
|
1616
|
+
* marks the file "settling" and a short bounded timer confirms
|
|
1617
|
+
* completion via `isTransformed` before emitting. (A module nothing
|
|
1618
|
+
* re-requests never re-transforms — its `transformed` event waits for
|
|
1619
|
+
* the next render, which is also when the graph has new information.)
|
|
1620
|
+
*/
|
|
1621
|
+
function makeGraphUpdateChannel(ctx, send, isTransformed, canonicalize = (file) => file) {
|
|
1622
|
+
/** Files invalidated but not yet re-transformed, per environment. */
|
|
1623
|
+
const pending = /* @__PURE__ */ new Set();
|
|
1624
|
+
const key = (file, environment) => `${environment}\0${file}`;
|
|
1625
|
+
const root = normalizePath(canonicalize(ctx.root));
|
|
1626
|
+
const extensions = buildSourceExtensions(ctx.config.pageExtensions);
|
|
1627
|
+
const emitTransformed = (file, environment, structural) => {
|
|
1628
|
+
send({
|
|
1629
|
+
type: "custom",
|
|
1630
|
+
event: GRAPH_UPDATE_EVENT,
|
|
1631
|
+
data: structural ? {
|
|
1632
|
+
file,
|
|
1633
|
+
event: "update",
|
|
1634
|
+
environment,
|
|
1635
|
+
phase: "transformed",
|
|
1636
|
+
structural: true
|
|
1637
|
+
} : {
|
|
1638
|
+
file,
|
|
1639
|
+
event: "update",
|
|
1640
|
+
environment,
|
|
1641
|
+
phase: "transformed"
|
|
1642
|
+
}
|
|
1643
|
+
});
|
|
1361
1644
|
};
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1645
|
+
/**
|
|
1646
|
+
* Confirm the transform request finished (transformResult set again)
|
|
1647
|
+
* before emitting phase `transformed`. If confirmation never arrives
|
|
1648
|
+
* within the bounded schedule below, the pending key is RE-ARMED
|
|
1649
|
+
* rather than emitted — a `transformed` event over a still-stale
|
|
1650
|
+
* graph would be a false all-clear with no corrective event.
|
|
1651
|
+
*/
|
|
1652
|
+
/**
|
|
1653
|
+
* Delays between confirmation re-checks: dense while a normal
|
|
1654
|
+
* transform request finishes, then exponential backoff for slow
|
|
1655
|
+
* import-analysis passes (large graphs, cold dep optimizer) — a
|
|
1656
|
+
* completed slow transform is CACHED, so no later transform hook may
|
|
1657
|
+
* ever fire for it and the tail checks are the only chance to emit.
|
|
1658
|
+
* Total window ≈ 16 s, then give up (bounded — the async-safety
|
|
1659
|
+
* rules ban open-ended polling) and re-arm the pending key.
|
|
1660
|
+
*/
|
|
1661
|
+
const CONFIRM_DELAYS_MS = [
|
|
1662
|
+
...Array.from({ length: 25 }, () => 20),
|
|
1663
|
+
500,
|
|
1664
|
+
1e3,
|
|
1665
|
+
2e3,
|
|
1666
|
+
4e3,
|
|
1667
|
+
8e3
|
|
1367
1668
|
];
|
|
1368
|
-
|
|
1669
|
+
const confirmAndEmit = (file, environment, attempt = 0, structural = false) => {
|
|
1670
|
+
if (!isTransformed || isTransformed(file, environment)) {
|
|
1671
|
+
emitTransformed(file, environment, structural);
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
if (attempt >= CONFIRM_DELAYS_MS.length) {
|
|
1675
|
+
if (!structural) pending.add(key(file, environment));
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
setTimeout(() => confirmAndEmit(file, environment, attempt + 1, structural), CONFIRM_DELAYS_MS[attempt]);
|
|
1679
|
+
};
|
|
1680
|
+
return {
|
|
1681
|
+
onHotUpdate(update) {
|
|
1682
|
+
const file = normalizePath(canonicalize(update.file));
|
|
1683
|
+
if (!isScannableSourceFile(file, root, extensions)) return;
|
|
1684
|
+
if (update.type === "delete") pending.delete(key(file, update.environment));
|
|
1685
|
+
else pending.add(key(file, update.environment));
|
|
1686
|
+
send({
|
|
1687
|
+
type: "custom",
|
|
1688
|
+
event: GRAPH_UPDATE_EVENT,
|
|
1689
|
+
data: {
|
|
1690
|
+
file,
|
|
1691
|
+
event: update.type,
|
|
1692
|
+
environment: update.environment,
|
|
1693
|
+
phase: "invalidated"
|
|
1694
|
+
}
|
|
1695
|
+
});
|
|
1696
|
+
},
|
|
1697
|
+
onTransform(id, environment) {
|
|
1698
|
+
const file = normalizePath(id.split("?")[0]);
|
|
1699
|
+
if (file.includes("virtual:timber-route-manifest")) {
|
|
1700
|
+
confirmAndEmit(file, environment, 25, true);
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
const pendingKey = key(file, environment);
|
|
1704
|
+
if (!pending.has(pendingKey)) return;
|
|
1705
|
+
pending.delete(pendingKey);
|
|
1706
|
+
confirmAndEmit(file, environment);
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1369
1710
|
//#endregion
|
|
1370
1711
|
//#region src/server/compress.ts
|
|
1371
|
-
init_config_validation();
|
|
1372
1712
|
/**
|
|
1373
1713
|
* MIME types that benefit from compression.
|
|
1374
1714
|
* text/* is handled via prefix matching; these are the specific
|
|
@@ -1481,7 +1821,8 @@ function compressResponse(request, response) {
|
|
|
1481
1821
|
*/
|
|
1482
1822
|
function compressWithGzip(body) {
|
|
1483
1823
|
const gzip = createGzip({ flush: constants.Z_SYNC_FLUSH });
|
|
1484
|
-
|
|
1824
|
+
const nodeInput = Readable.fromWeb(body);
|
|
1825
|
+
pipeline(nodeInput, gzip, () => {});
|
|
1485
1826
|
return Readable.toWeb(gzip);
|
|
1486
1827
|
}
|
|
1487
1828
|
//#endregion
|
|
@@ -1516,10 +1857,35 @@ var ASSET_EXTENSIONS = /\.(?:js|ts|tsx|jsx|css|map|json|svg|png|jpg|jpeg|gif|web
|
|
|
1516
1857
|
* Hook: configureServer (returns post-hook to register after Vite's middleware)
|
|
1517
1858
|
*/
|
|
1518
1859
|
function timberDevServer(ctx) {
|
|
1860
|
+
let graphChannel = null;
|
|
1519
1861
|
return {
|
|
1520
1862
|
name: "timber-dev-server",
|
|
1521
1863
|
apply: "serve",
|
|
1522
1864
|
/**
|
|
1865
|
+
* Push channel for the graph endpoint, phase 1: `invalidated`, one
|
|
1866
|
+
* per (file, environment). Emitted from hotUpdate — which runs
|
|
1867
|
+
* AFTER Vite invalidates the environment module graphs — never
|
|
1868
|
+
* from a raw watcher listener, which would race consumers into
|
|
1869
|
+
* querying pre-invalidation memberships (design/47 §"Dev-server
|
|
1870
|
+
* endpoint").
|
|
1871
|
+
*/
|
|
1872
|
+
hotUpdate({ file, type }) {
|
|
1873
|
+
graphChannel?.onHotUpdate({
|
|
1874
|
+
file,
|
|
1875
|
+
type,
|
|
1876
|
+
environment: this.environment.name
|
|
1877
|
+
});
|
|
1878
|
+
},
|
|
1879
|
+
/**
|
|
1880
|
+
* Push channel phase 2: `transformed`, when a pending-invalidated
|
|
1881
|
+
* module's import edges are actually rebuilt. A Set lookup for
|
|
1882
|
+
* everything without a pending invalidation — free on the hot
|
|
1883
|
+
* path. Returning nothing leaves the code untouched.
|
|
1884
|
+
*/
|
|
1885
|
+
transform(_code, id) {
|
|
1886
|
+
graphChannel?.onTransform(id, this.environment.name);
|
|
1887
|
+
},
|
|
1888
|
+
/**
|
|
1523
1889
|
* Register the dev server middleware and config file watcher.
|
|
1524
1890
|
*
|
|
1525
1891
|
* Registers as a pre-hook (no return value) so our middleware runs
|
|
@@ -1532,7 +1898,30 @@ function timberDevServer(ctx) {
|
|
|
1532
1898
|
const configPaths = CONFIG_FILE_NAMES.map((name) => join(ctx.root, name));
|
|
1533
1899
|
server.watcher.add(configPaths);
|
|
1534
1900
|
listenForClientErrors(server, ctx.root);
|
|
1901
|
+
server.middlewares.use(createGraphEndpointMiddleware(server, ctx));
|
|
1902
|
+
graphChannel = makeGraphUpdateChannel(ctx, (payload) => server.hot.send(payload), (file, environment) => {
|
|
1903
|
+
const graph = server.environments[environment]?.moduleGraph;
|
|
1904
|
+
if (!graph) return false;
|
|
1905
|
+
const nodes = graph.getModulesByFile(file);
|
|
1906
|
+
if (nodes) {
|
|
1907
|
+
for (const node of nodes) if (node.transformResult != null) return true;
|
|
1908
|
+
return false;
|
|
1909
|
+
}
|
|
1910
|
+
return graph.getModuleById(file)?.transformResult != null;
|
|
1911
|
+
}, (file) => {
|
|
1912
|
+
if (server.config?.resolve?.preserveSymlinks || file.includes("virtual:")) return file;
|
|
1913
|
+
try {
|
|
1914
|
+
return realpathSync(file);
|
|
1915
|
+
} catch {
|
|
1916
|
+
try {
|
|
1917
|
+
return join(realpathSync(dirname(file)), basename(file));
|
|
1918
|
+
} catch {
|
|
1919
|
+
return file;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
});
|
|
1535
1923
|
server.middlewares.use(createTimberMiddleware(server, ctx));
|
|
1924
|
+
registerDevDiscovery(server.httpServer, ctx.root, server.config);
|
|
1536
1925
|
if (ctx.holdingServer) {
|
|
1537
1926
|
const originalListen = server.listen.bind(server);
|
|
1538
1927
|
const holdingRef = ctx.holdingServer;
|
|
@@ -2071,7 +2460,7 @@ function timberEntries(ctx) {
|
|
|
2071
2460
|
}
|
|
2072
2461
|
//#endregion
|
|
2073
2462
|
//#region src/plugins/mdx.ts
|
|
2074
|
-
var
|
|
2463
|
+
var MDX_EXTENSIONS_UNDOTTED = [...MDX_EXTENSIONS].map((ext) => ext.slice(1));
|
|
2075
2464
|
/**
|
|
2076
2465
|
* Check if mdx-components.tsx (or .ts, .jsx, .js) exists at the project root
|
|
2077
2466
|
* or in src/. Root takes precedence, matching Next.js behavior.
|
|
@@ -2096,7 +2485,7 @@ function findMdxComponents(root) {
|
|
|
2096
2485
|
function shouldActivate(ctx) {
|
|
2097
2486
|
if (ctx.config.mdx === false) return false;
|
|
2098
2487
|
const exts = ctx.config.pageExtensions;
|
|
2099
|
-
if (exts && exts.some((ext) =>
|
|
2488
|
+
if (exts && exts.some((ext) => MDX_EXTENSIONS_UNDOTTED.includes(ext))) return true;
|
|
2100
2489
|
if (existsSync(join(ctx.root, "content"))) return true;
|
|
2101
2490
|
return false;
|
|
2102
2491
|
}
|
|
@@ -2121,7 +2510,8 @@ function shouldActivate(ctx) {
|
|
|
2121
2510
|
*/
|
|
2122
2511
|
async function tryImport(name, projectRoot) {
|
|
2123
2512
|
try {
|
|
2124
|
-
const
|
|
2513
|
+
const resolved = createRequire(join(projectRoot, "package.json")).resolve(name);
|
|
2514
|
+
const mod = await import(pathToFileURL(resolved).href);
|
|
2125
2515
|
return mod.default ?? mod;
|
|
2126
2516
|
} catch {
|
|
2127
2517
|
try {
|
|
@@ -2382,6 +2772,7 @@ var ROUTE_FILE_PATTERNS = /\/(page|layout|middleware|access|route|error|global-e
|
|
|
2382
2772
|
*/
|
|
2383
2773
|
function writeCodegen(ctx) {
|
|
2384
2774
|
if (!ctx.routeTree) return;
|
|
2775
|
+
if (process.env.TIMBER_ANALYZE === "1") return;
|
|
2385
2776
|
writeRouteCodegen(ctx.routeTree, ctx.appDir, ctx.root).catch((err) => {
|
|
2386
2777
|
console.warn("[timber] Failed to write codegen output:", err);
|
|
2387
2778
|
});
|
|
@@ -2609,9 +3000,7 @@ function warnSchemaValidation(ctx) {
|
|
|
2609
3000
|
case "bracket-mismatch":
|
|
2610
3001
|
console.warn(`[timber] ${w.message}`);
|
|
2611
3002
|
break;
|
|
2612
|
-
case "missing-key":
|
|
2613
|
-
console.warn(`[timber] ${w.message}`);
|
|
2614
|
-
break;
|
|
3003
|
+
case "missing-key": console.warn(`[timber] ${w.message}`);
|
|
2615
3004
|
}
|
|
2616
3005
|
}
|
|
2617
3006
|
}
|
|
@@ -2633,14 +3022,13 @@ var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
2633
3022
|
var PKG_ROOT = __dirname.endsWith("plugins") ? resolve(__dirname, "..", "..") : resolve(__dirname, "..");
|
|
2634
3023
|
var SHIMS_DIR = resolve(PKG_ROOT, "src", "shims");
|
|
2635
3024
|
/**
|
|
2636
|
-
*
|
|
2637
|
-
*
|
|
2638
|
-
*
|
|
2639
|
-
* -
|
|
2640
|
-
*
|
|
3025
|
+
* The server-only marker's virtual ID, needed directly by the
|
|
3026
|
+
* `#server-only-guard` resolution branch below. All poison-pill rules
|
|
3027
|
+
* (specifiers, virtual IDs, error messages, environment policy) live in
|
|
3028
|
+
* analyze/poison-rules.ts — the single source of truth shared with the
|
|
3029
|
+
* `timber graph` reporter (design/47 §3).
|
|
2641
3030
|
*/
|
|
2642
|
-
var SERVER_ONLY_VIRTUAL = "
|
|
2643
|
-
var CLIENT_ONLY_VIRTUAL = "\0timber:client-only";
|
|
3031
|
+
var SERVER_ONLY_VIRTUAL = markerFor("server-only").virtualId;
|
|
2644
3032
|
/**
|
|
2645
3033
|
* Map from @timber-js/app/<subpath> to relative src/ file paths.
|
|
2646
3034
|
*
|
|
@@ -2767,8 +3155,7 @@ function timberShims(_ctx) {
|
|
|
2767
3155
|
* the browser.
|
|
2768
3156
|
*/
|
|
2769
3157
|
resolveId(id) {
|
|
2770
|
-
if (id ===
|
|
2771
|
-
if (id === "client-only") return CLIENT_ONLY_VIRTUAL;
|
|
3158
|
+
for (const marker of EXPLICIT_MARKERS) if (id === marker.specifier) return marker.virtualId;
|
|
2772
3159
|
const cleanId = stripJsExtension(id);
|
|
2773
3160
|
if (cleanId in SHIM_MAP) {
|
|
2774
3161
|
if (envName(this) === "client" && cleanId === "next/navigation") return resolve(SHIMS_DIR, "navigation-client.ts");
|
|
@@ -2817,21 +3204,8 @@ function timberShims(_ctx) {
|
|
|
2817
3204
|
* clearly identifies the boundary violation.
|
|
2818
3205
|
*/
|
|
2819
3206
|
load(id) {
|
|
2820
|
-
const
|
|
2821
|
-
if (id ===
|
|
2822
|
-
if (isClient) return `throw new Error(
|
|
2823
|
-
"This module cannot be imported from a Client Component module. " +
|
|
2824
|
-
"It should only be used from a Server Component."
|
|
2825
|
-
);`;
|
|
2826
|
-
return "export {};";
|
|
2827
|
-
}
|
|
2828
|
-
if (id === CLIENT_ONLY_VIRTUAL) {
|
|
2829
|
-
if (!isClient) return `throw new Error(
|
|
2830
|
-
"This module cannot be imported from a Server Component module. " +
|
|
2831
|
-
"It should only be used from a Client Component."
|
|
2832
|
-
);`;
|
|
2833
|
-
return "export {};";
|
|
2834
|
-
}
|
|
3207
|
+
const env = envName(this);
|
|
3208
|
+
for (const marker of EXPLICIT_MARKERS) if (id === marker.virtualId) return poisonPillSource(marker, env);
|
|
2835
3209
|
if (id === "\0timber:server-empty") return `
|
|
2836
3210
|
const msg = "[timber] @timber-js/app/server was imported from client code. " +
|
|
2837
3211
|
"Server modules (headers, cookies, redirect, deny, etc.) cannot be used in client components. " +
|
|
@@ -4448,7 +4822,7 @@ function encodeInteger(builder, num, relative) {
|
|
|
4448
4822
|
} while (delta > 0);
|
|
4449
4823
|
return num;
|
|
4450
4824
|
}
|
|
4451
|
-
var bufLength =
|
|
4825
|
+
var bufLength = 16384;
|
|
4452
4826
|
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { decode(buf) {
|
|
4453
4827
|
return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString();
|
|
4454
4828
|
} } : { decode(buf) {
|
|
@@ -4501,7 +4875,7 @@ function encode(decoded) {
|
|
|
4501
4875
|
return writer.flush();
|
|
4502
4876
|
}
|
|
4503
4877
|
//#endregion
|
|
4504
|
-
//#region ../../node_modules/.pnpm/magic-string@
|
|
4878
|
+
//#region ../../node_modules/.pnpm/magic-string@1.2.2/node_modules/magic-string/dist/index.mjs
|
|
4505
4879
|
var BitSet = class BitSet {
|
|
4506
4880
|
constructor(arg) {
|
|
4507
4881
|
this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
|
|
@@ -4545,14 +4919,16 @@ var Chunk = class Chunk {
|
|
|
4545
4919
|
return this.start < index && index < this.end;
|
|
4546
4920
|
}
|
|
4547
4921
|
eachNext(fn) {
|
|
4548
|
-
|
|
4922
|
+
fn(this);
|
|
4923
|
+
let chunk = this.next;
|
|
4549
4924
|
while (chunk) {
|
|
4550
4925
|
fn(chunk);
|
|
4551
4926
|
chunk = chunk.next;
|
|
4552
4927
|
}
|
|
4553
4928
|
}
|
|
4554
4929
|
eachPrevious(fn) {
|
|
4555
|
-
|
|
4930
|
+
fn(this);
|
|
4931
|
+
let chunk = this.previous;
|
|
4556
4932
|
while (chunk) {
|
|
4557
4933
|
fn(chunk);
|
|
4558
4934
|
chunk = chunk.previous;
|
|
@@ -4610,10 +4986,8 @@ var Chunk = class Chunk {
|
|
|
4610
4986
|
if (this.outro.length) return true;
|
|
4611
4987
|
const trimmed = this.content.replace(rx, "");
|
|
4612
4988
|
if (trimmed.length) {
|
|
4613
|
-
if (trimmed !== this.content)
|
|
4614
|
-
|
|
4615
|
-
if (this.edited) this.edit(trimmed, this.storeName, true);
|
|
4616
|
-
}
|
|
4989
|
+
if (trimmed !== this.content) if (this.edited) this.edit(trimmed, this.storeName, true);
|
|
4990
|
+
else this.split(this.start + trimmed.length).edit("", void 0, true);
|
|
4617
4991
|
return true;
|
|
4618
4992
|
} else {
|
|
4619
4993
|
this.edit("", void 0, true);
|
|
@@ -4626,9 +5000,9 @@ var Chunk = class Chunk {
|
|
|
4626
5000
|
if (this.intro.length) return true;
|
|
4627
5001
|
const trimmed = this.content.replace(rx, "");
|
|
4628
5002
|
if (trimmed.length) {
|
|
4629
|
-
if (trimmed !== this.content)
|
|
4630
|
-
|
|
4631
|
-
|
|
5003
|
+
if (trimmed !== this.content) if (this.edited) this.edit(trimmed, this.storeName, true);
|
|
5004
|
+
else {
|
|
5005
|
+
this.split(this.end - trimmed.length);
|
|
4632
5006
|
this.edit("", void 0, true);
|
|
4633
5007
|
}
|
|
4634
5008
|
return true;
|
|
@@ -4639,14 +5013,27 @@ var Chunk = class Chunk {
|
|
|
4639
5013
|
}
|
|
4640
5014
|
}
|
|
4641
5015
|
};
|
|
5016
|
+
/**
|
|
5017
|
+
* The single error type thrown by MagicString.
|
|
5018
|
+
*
|
|
5019
|
+
* Every message is prefixed with `[MagicString]` so its source is obvious at a
|
|
5020
|
+
* glance, and is kept short and consistent in tone.
|
|
5021
|
+
*/
|
|
5022
|
+
var MagicStringError = class extends Error {
|
|
5023
|
+
name = "MagicStringError";
|
|
5024
|
+
constructor(message, options) {
|
|
5025
|
+
super(`[MagicString] ${message}`, options);
|
|
5026
|
+
}
|
|
5027
|
+
};
|
|
4642
5028
|
function getBtoa() {
|
|
4643
5029
|
if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
5030
|
+
const buffer = globalThis["Buffer"];
|
|
5031
|
+
if (buffer) return (str) => buffer.from(str, "utf-8").toString("base64");
|
|
5032
|
+
return () => {
|
|
5033
|
+
throw new MagicStringError("unsupported environment: `btoa` or `Buffer` is required");
|
|
4647
5034
|
};
|
|
4648
5035
|
}
|
|
4649
|
-
var btoa =
|
|
5036
|
+
var btoa = /* #__PURE__ */ getBtoa();
|
|
4650
5037
|
var SourceMap = class {
|
|
4651
5038
|
constructor(properties) {
|
|
4652
5039
|
this.version = 3;
|
|
@@ -4658,43 +5045,20 @@ var SourceMap = class {
|
|
|
4658
5045
|
if (typeof properties.x_google_ignoreList !== "undefined") this.x_google_ignoreList = properties.x_google_ignoreList;
|
|
4659
5046
|
if (typeof properties.debugId !== "undefined") this.debugId = properties.debugId;
|
|
4660
5047
|
}
|
|
5048
|
+
/**
|
|
5049
|
+
* Returns the equivalent of `JSON.stringify(map)`
|
|
5050
|
+
*/
|
|
4661
5051
|
toString() {
|
|
4662
5052
|
return JSON.stringify(this);
|
|
4663
5053
|
}
|
|
5054
|
+
/**
|
|
5055
|
+
* Returns a DataURI containing the sourcemap. Useful for doing this sort of thing:
|
|
5056
|
+
* `generateMap(options?: SourceMapOptions): SourceMap;`
|
|
5057
|
+
*/
|
|
4664
5058
|
toUrl() {
|
|
4665
|
-
return
|
|
5059
|
+
return `data:application/json;charset=utf-8;base64,${btoa(this.toString())}`;
|
|
4666
5060
|
}
|
|
4667
5061
|
};
|
|
4668
|
-
function guessIndent(code) {
|
|
4669
|
-
const lines = code.split("\n");
|
|
4670
|
-
const tabbed = lines.filter((line) => /^\t+/.test(line));
|
|
4671
|
-
const spaced = lines.filter((line) => /^ {2,}/.test(line));
|
|
4672
|
-
if (tabbed.length === 0 && spaced.length === 0) return null;
|
|
4673
|
-
if (tabbed.length >= spaced.length) return " ";
|
|
4674
|
-
const min = spaced.reduce((previous, current) => {
|
|
4675
|
-
const numSpaces = /^ +/.exec(current)[0].length;
|
|
4676
|
-
return Math.min(numSpaces, previous);
|
|
4677
|
-
}, Infinity);
|
|
4678
|
-
return new Array(min + 1).join(" ");
|
|
4679
|
-
}
|
|
4680
|
-
function getRelativePath(from, to) {
|
|
4681
|
-
const fromParts = from.split(/[/\\]/);
|
|
4682
|
-
const toParts = to.split(/[/\\]/);
|
|
4683
|
-
fromParts.pop();
|
|
4684
|
-
while (fromParts[0] === toParts[0]) {
|
|
4685
|
-
fromParts.shift();
|
|
4686
|
-
toParts.shift();
|
|
4687
|
-
}
|
|
4688
|
-
if (fromParts.length) {
|
|
4689
|
-
let i = fromParts.length;
|
|
4690
|
-
while (i--) fromParts[i] = "..";
|
|
4691
|
-
}
|
|
4692
|
-
return fromParts.concat(toParts).join("/");
|
|
4693
|
-
}
|
|
4694
|
-
var toString = Object.prototype.toString;
|
|
4695
|
-
function isObject(thing) {
|
|
4696
|
-
return toString.call(thing) === "[object Object]";
|
|
4697
|
-
}
|
|
4698
5062
|
function getLocator(source) {
|
|
4699
5063
|
const originalLines = source.split("\n");
|
|
4700
5064
|
const lineOffsets = [];
|
|
@@ -4717,6 +5081,36 @@ function getLocator(source) {
|
|
|
4717
5081
|
};
|
|
4718
5082
|
};
|
|
4719
5083
|
}
|
|
5084
|
+
function getRelativePath(from, to) {
|
|
5085
|
+
const fromParts = from.split(/[/\\]/);
|
|
5086
|
+
const toParts = to.split(/[/\\]/);
|
|
5087
|
+
fromParts.pop();
|
|
5088
|
+
while (fromParts[0] === toParts[0]) {
|
|
5089
|
+
fromParts.shift();
|
|
5090
|
+
toParts.shift();
|
|
5091
|
+
}
|
|
5092
|
+
if (fromParts.length) {
|
|
5093
|
+
let i = fromParts.length;
|
|
5094
|
+
while (i--) fromParts[i] = "..";
|
|
5095
|
+
}
|
|
5096
|
+
return fromParts.concat(toParts).join("/");
|
|
5097
|
+
}
|
|
5098
|
+
function guessIndent(code) {
|
|
5099
|
+
const lines = code.split("\n");
|
|
5100
|
+
const tabbed = lines.filter((line) => /^\t+/.test(line));
|
|
5101
|
+
const spaced = lines.filter((line) => /^ {2,}/.test(line));
|
|
5102
|
+
if (tabbed.length === 0 && spaced.length === 0) return null;
|
|
5103
|
+
if (tabbed.length >= spaced.length) return " ";
|
|
5104
|
+
const min = spaced.reduce((previous, current) => {
|
|
5105
|
+
const numSpaces = /^ +/.exec(current)[0].length;
|
|
5106
|
+
return Math.min(numSpaces, previous);
|
|
5107
|
+
}, Infinity);
|
|
5108
|
+
return " ".repeat(min);
|
|
5109
|
+
}
|
|
5110
|
+
var toString = Object.prototype.toString;
|
|
5111
|
+
function isObject(thing) {
|
|
5112
|
+
return toString.call(thing) === "[object Object]";
|
|
5113
|
+
}
|
|
4720
5114
|
var wordRegex = /\w/;
|
|
4721
5115
|
var Mappings = class {
|
|
4722
5116
|
constructor(hires) {
|
|
@@ -4816,6 +5210,8 @@ var Mappings = class {
|
|
|
4816
5210
|
}
|
|
4817
5211
|
};
|
|
4818
5212
|
var n = "\n";
|
|
5213
|
+
var NEWLINE_CHAR = "\n".charCodeAt(0);
|
|
5214
|
+
var CR_CHAR = "\r".charCodeAt(0);
|
|
4819
5215
|
var warned = {
|
|
4820
5216
|
insertLeft: false,
|
|
4821
5217
|
insertRight: false,
|
|
@@ -4851,11 +5247,11 @@ var MagicString = class MagicString {
|
|
|
4851
5247
|
},
|
|
4852
5248
|
byStart: {
|
|
4853
5249
|
writable: true,
|
|
4854
|
-
value:
|
|
5250
|
+
value: /* @__PURE__ */ new Map([[0, chunk]])
|
|
4855
5251
|
},
|
|
4856
5252
|
byEnd: {
|
|
4857
5253
|
writable: true,
|
|
4858
|
-
value:
|
|
5254
|
+
value: /* @__PURE__ */ new Map([[string.length, chunk]])
|
|
4859
5255
|
},
|
|
4860
5256
|
filename: {
|
|
4861
5257
|
writable: true,
|
|
@@ -4884,47 +5280,69 @@ var MagicString = class MagicString {
|
|
|
4884
5280
|
offset: {
|
|
4885
5281
|
writable: true,
|
|
4886
5282
|
value: options.offset || 0
|
|
5283
|
+
},
|
|
5284
|
+
hasMovedChunks: {
|
|
5285
|
+
writable: true,
|
|
5286
|
+
value: false
|
|
4887
5287
|
}
|
|
4888
5288
|
});
|
|
4889
|
-
this.byStart[0] = chunk;
|
|
4890
|
-
this.byEnd[string.length] = chunk;
|
|
4891
5289
|
}
|
|
5290
|
+
/**
|
|
5291
|
+
* Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false.
|
|
5292
|
+
*/
|
|
4892
5293
|
addSourcemapLocation(char) {
|
|
4893
5294
|
this.sourcemapLocations.add(char);
|
|
4894
5295
|
}
|
|
5296
|
+
/**
|
|
5297
|
+
* Appends the specified content to the end of the string.
|
|
5298
|
+
*/
|
|
4895
5299
|
append(content) {
|
|
4896
|
-
if (typeof content !== "string") throw new
|
|
5300
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
4897
5301
|
this.outro += content;
|
|
4898
5302
|
return this;
|
|
4899
5303
|
}
|
|
5304
|
+
/**
|
|
5305
|
+
* Appends the specified content at the index in the original string.
|
|
5306
|
+
* If a range *ending* with index is subsequently moved, the insert will be moved with it.
|
|
5307
|
+
* See also `s.prependLeft(...)`.
|
|
5308
|
+
*/
|
|
4900
5309
|
appendLeft(index, content) {
|
|
4901
5310
|
index = index + this.offset;
|
|
4902
|
-
if (typeof content !== "string") throw new
|
|
5311
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
4903
5312
|
this._split(index);
|
|
4904
|
-
const chunk = this.byEnd
|
|
5313
|
+
const chunk = this.byEnd.get(index);
|
|
4905
5314
|
if (chunk) chunk.appendLeft(content);
|
|
4906
5315
|
else this.intro += content;
|
|
4907
5316
|
return this;
|
|
4908
5317
|
}
|
|
5318
|
+
/**
|
|
5319
|
+
* Appends the specified content at the index in the original string.
|
|
5320
|
+
* If a range *starting* with index is subsequently moved, the insert will be moved with it.
|
|
5321
|
+
* See also `s.prependRight(...)`.
|
|
5322
|
+
*/
|
|
4909
5323
|
appendRight(index, content) {
|
|
4910
5324
|
index = index + this.offset;
|
|
4911
|
-
if (typeof content !== "string") throw new
|
|
5325
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
4912
5326
|
this._split(index);
|
|
4913
|
-
const chunk = this.byStart
|
|
5327
|
+
const chunk = this.byStart.get(index);
|
|
4914
5328
|
if (chunk) chunk.appendRight(content);
|
|
4915
5329
|
else this.outro += content;
|
|
4916
5330
|
return this;
|
|
4917
5331
|
}
|
|
5332
|
+
/**
|
|
5333
|
+
* Does what you'd expect.
|
|
5334
|
+
*/
|
|
4918
5335
|
clone() {
|
|
4919
5336
|
const cloned = new MagicString(this.original, {
|
|
4920
5337
|
filename: this.filename,
|
|
5338
|
+
ignoreList: this.ignoreList,
|
|
4921
5339
|
offset: this.offset
|
|
4922
5340
|
});
|
|
4923
5341
|
let originalChunk = this.firstChunk;
|
|
4924
5342
|
let clonedChunk = cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone();
|
|
4925
5343
|
while (originalChunk) {
|
|
4926
|
-
cloned.byStart
|
|
4927
|
-
cloned.byEnd
|
|
5344
|
+
cloned.byStart.set(clonedChunk.start, clonedChunk);
|
|
5345
|
+
cloned.byEnd.set(clonedChunk.end, clonedChunk);
|
|
4928
5346
|
const nextOriginalChunk = originalChunk.next;
|
|
4929
5347
|
const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
|
|
4930
5348
|
if (nextClonedChunk) {
|
|
@@ -4937,10 +5355,16 @@ var MagicString = class MagicString {
|
|
|
4937
5355
|
cloned.lastChunk = clonedChunk;
|
|
4938
5356
|
if (this.indentExclusionRanges) cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
|
|
4939
5357
|
cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
|
|
5358
|
+
cloned.storedNames = { ...this.storedNames };
|
|
4940
5359
|
cloned.intro = this.intro;
|
|
4941
5360
|
cloned.outro = this.outro;
|
|
5361
|
+
cloned.hasMovedChunks = this.hasMovedChunks;
|
|
4942
5362
|
return cloned;
|
|
4943
5363
|
}
|
|
5364
|
+
/**
|
|
5365
|
+
* Generates a sourcemap object with raw mappings in array form, rather than encoded as a string.
|
|
5366
|
+
* Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead.
|
|
5367
|
+
*/
|
|
4944
5368
|
generateDecodedMap(options) {
|
|
4945
5369
|
options = options || {};
|
|
4946
5370
|
const sourceIndex = 0;
|
|
@@ -4965,12 +5389,17 @@ var MagicString = class MagicString {
|
|
|
4965
5389
|
x_google_ignoreList: this.ignoreList ? [sourceIndex] : void 0
|
|
4966
5390
|
};
|
|
4967
5391
|
}
|
|
5392
|
+
/**
|
|
5393
|
+
* Generates a version 3 sourcemap.
|
|
5394
|
+
*/
|
|
4968
5395
|
generateMap(options) {
|
|
4969
5396
|
return new SourceMap(this.generateDecodedMap(options));
|
|
4970
5397
|
}
|
|
5398
|
+
/** @internal */
|
|
4971
5399
|
_ensureindentStr() {
|
|
4972
5400
|
if (this.indentStr === void 0) this.indentStr = guessIndent(this.original);
|
|
4973
5401
|
}
|
|
5402
|
+
/** @internal */
|
|
4974
5403
|
_getRawIndentString() {
|
|
4975
5404
|
this._ensureindentStr();
|
|
4976
5405
|
return this.indentStr;
|
|
@@ -4990,6 +5419,7 @@ var MagicString = class MagicString {
|
|
|
4990
5419
|
indentStr = this.indentStr || " ";
|
|
4991
5420
|
}
|
|
4992
5421
|
if (indentStr === "") return this;
|
|
5422
|
+
const resolvedIndentStr = indentStr;
|
|
4993
5423
|
options = options || {};
|
|
4994
5424
|
const isExcluded = {};
|
|
4995
5425
|
if (options.exclude) (typeof options.exclude[0] === "number" ? [options.exclude] : options.exclude).forEach((exclusion) => {
|
|
@@ -4997,13 +5427,22 @@ var MagicString = class MagicString {
|
|
|
4997
5427
|
});
|
|
4998
5428
|
let shouldIndentNextCharacter = options.indentStart !== false;
|
|
4999
5429
|
const replacer = (match) => {
|
|
5000
|
-
if (shouldIndentNextCharacter) return `${
|
|
5430
|
+
if (shouldIndentNextCharacter) return `${resolvedIndentStr}${match}`;
|
|
5001
5431
|
shouldIndentNextCharacter = true;
|
|
5002
5432
|
return match;
|
|
5003
5433
|
};
|
|
5004
5434
|
this.intro = this.intro.replace(pattern, replacer);
|
|
5005
5435
|
let charIndex = 0;
|
|
5006
5436
|
let chunk = this.firstChunk;
|
|
5437
|
+
const indentAt = (index) => {
|
|
5438
|
+
shouldIndentNextCharacter = false;
|
|
5439
|
+
if (index === chunk.start) chunk.prependRight(resolvedIndentStr);
|
|
5440
|
+
else {
|
|
5441
|
+
this._splitChunk(chunk, index);
|
|
5442
|
+
chunk = chunk.next;
|
|
5443
|
+
chunk.prependRight(resolvedIndentStr);
|
|
5444
|
+
}
|
|
5445
|
+
};
|
|
5007
5446
|
while (chunk) {
|
|
5008
5447
|
const end = chunk.end;
|
|
5009
5448
|
if (chunk.edited) {
|
|
@@ -5011,24 +5450,34 @@ var MagicString = class MagicString {
|
|
|
5011
5450
|
chunk.content = chunk.content.replace(pattern, replacer);
|
|
5012
5451
|
if (chunk.content.length) shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === "\n";
|
|
5013
5452
|
}
|
|
5014
|
-
} else {
|
|
5453
|
+
} else if (options.exclude) {
|
|
5015
5454
|
charIndex = chunk.start;
|
|
5016
5455
|
while (charIndex < end) {
|
|
5017
5456
|
if (!isExcluded[charIndex]) {
|
|
5018
|
-
const char = this.original
|
|
5019
|
-
if (char ===
|
|
5020
|
-
else if (char !==
|
|
5021
|
-
shouldIndentNextCharacter = false;
|
|
5022
|
-
if (charIndex === chunk.start) chunk.prependRight(indentStr);
|
|
5023
|
-
else {
|
|
5024
|
-
this._splitChunk(chunk, charIndex);
|
|
5025
|
-
chunk = chunk.next;
|
|
5026
|
-
chunk.prependRight(indentStr);
|
|
5027
|
-
}
|
|
5028
|
-
}
|
|
5457
|
+
const char = this.original.charCodeAt(charIndex);
|
|
5458
|
+
if (char === NEWLINE_CHAR) shouldIndentNextCharacter = true;
|
|
5459
|
+
else if (char !== CR_CHAR && shouldIndentNextCharacter) indentAt(charIndex);
|
|
5029
5460
|
}
|
|
5030
5461
|
charIndex += 1;
|
|
5031
5462
|
}
|
|
5463
|
+
} else {
|
|
5464
|
+
charIndex = chunk.start;
|
|
5465
|
+
while (charIndex < end) {
|
|
5466
|
+
if (!shouldIndentNextCharacter) {
|
|
5467
|
+
const nextLine = this.original.indexOf(n, charIndex);
|
|
5468
|
+
if (nextLine === -1 || nextLine >= end) break;
|
|
5469
|
+
shouldIndentNextCharacter = true;
|
|
5470
|
+
charIndex = nextLine + 1;
|
|
5471
|
+
continue;
|
|
5472
|
+
}
|
|
5473
|
+
const char = this.original.charCodeAt(charIndex);
|
|
5474
|
+
if (char === NEWLINE_CHAR || char === CR_CHAR) {
|
|
5475
|
+
charIndex += 1;
|
|
5476
|
+
continue;
|
|
5477
|
+
}
|
|
5478
|
+
indentAt(charIndex);
|
|
5479
|
+
charIndex += 1;
|
|
5480
|
+
}
|
|
5032
5481
|
}
|
|
5033
5482
|
charIndex = chunk.end;
|
|
5034
5483
|
chunk = chunk.next;
|
|
@@ -5036,9 +5485,11 @@ var MagicString = class MagicString {
|
|
|
5036
5485
|
this.outro = this.outro.replace(pattern, replacer);
|
|
5037
5486
|
return this;
|
|
5038
5487
|
}
|
|
5488
|
+
/** @internal */
|
|
5039
5489
|
insert() {
|
|
5040
|
-
throw new
|
|
5490
|
+
throw new MagicStringError("insert() is deprecated, use appendLeft() or prependRight()");
|
|
5041
5491
|
}
|
|
5492
|
+
/** @internal */
|
|
5042
5493
|
insertLeft(index, content) {
|
|
5043
5494
|
if (!warned.insertLeft) {
|
|
5044
5495
|
console.warn("magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead");
|
|
@@ -5046,6 +5497,7 @@ var MagicString = class MagicString {
|
|
|
5046
5497
|
}
|
|
5047
5498
|
return this.appendLeft(index, content);
|
|
5048
5499
|
}
|
|
5500
|
+
/** @internal */
|
|
5049
5501
|
insertRight(index, content) {
|
|
5050
5502
|
if (!warned.insertRight) {
|
|
5051
5503
|
console.warn("magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead");
|
|
@@ -5053,19 +5505,30 @@ var MagicString = class MagicString {
|
|
|
5053
5505
|
}
|
|
5054
5506
|
return this.prependRight(index, content);
|
|
5055
5507
|
}
|
|
5508
|
+
/**
|
|
5509
|
+
* Moves the characters from `start` and `end` to `index`.
|
|
5510
|
+
*/
|
|
5056
5511
|
move(start, end, index) {
|
|
5057
5512
|
start = start + this.offset;
|
|
5058
5513
|
end = end + this.offset;
|
|
5059
5514
|
index = index + this.offset;
|
|
5060
|
-
if (
|
|
5515
|
+
if (start === end) return this;
|
|
5516
|
+
if (index >= start && index <= end) throw new MagicStringError("cannot move a selection inside itself");
|
|
5061
5517
|
this._split(start);
|
|
5062
5518
|
this._split(end);
|
|
5063
5519
|
this._split(index);
|
|
5064
|
-
const first = this.byStart
|
|
5065
|
-
const last = this.byEnd
|
|
5520
|
+
const first = this.byStart.get(start);
|
|
5521
|
+
const last = this.byEnd.get(end);
|
|
5522
|
+
if (this.hasMovedChunks) {
|
|
5523
|
+
let cursor = first;
|
|
5524
|
+
while (cursor !== last) {
|
|
5525
|
+
cursor = cursor.next;
|
|
5526
|
+
if (!cursor || cursor.start < start || cursor.end > end) throw new MagicStringError(`cannot move ${start} to ${end} because an earlier move split that range`);
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5066
5529
|
const oldLeft = first.previous;
|
|
5067
5530
|
const oldRight = last.next;
|
|
5068
|
-
const newRight = this.byStart
|
|
5531
|
+
const newRight = this.byStart.get(index);
|
|
5069
5532
|
if (!newRight && last === this.lastChunk) return this;
|
|
5070
5533
|
const newLeft = newRight ? newRight.previous : this.lastChunk;
|
|
5071
5534
|
if (oldLeft) oldLeft.next = oldRight;
|
|
@@ -5081,25 +5544,45 @@ var MagicString = class MagicString {
|
|
|
5081
5544
|
last.next = newRight || null;
|
|
5082
5545
|
if (!newLeft) this.firstChunk = first;
|
|
5083
5546
|
if (!newRight) this.lastChunk = last;
|
|
5547
|
+
this.hasMovedChunks = true;
|
|
5084
5548
|
return this;
|
|
5085
5549
|
}
|
|
5550
|
+
/**
|
|
5551
|
+
* Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in
|
|
5552
|
+
* that range. The same restrictions as `s.remove()` apply.
|
|
5553
|
+
*
|
|
5554
|
+
* The fourth argument is optional. It can have a storeName property - if true, the original name will be stored
|
|
5555
|
+
* for later inclusion in a sourcemap's names array - and a contentOnly property which determines whether only
|
|
5556
|
+
* the content is overwritten, or anything that was appended/prepended to the range as well.
|
|
5557
|
+
*
|
|
5558
|
+
* It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content.
|
|
5559
|
+
*/
|
|
5086
5560
|
overwrite(start, end, content, options) {
|
|
5087
|
-
|
|
5561
|
+
const optionObject = typeof options === "object" && options ? options : {};
|
|
5088
5562
|
return this.update(start, end, content, {
|
|
5089
|
-
...
|
|
5090
|
-
overwrite: !
|
|
5563
|
+
...optionObject,
|
|
5564
|
+
overwrite: !optionObject.contentOnly
|
|
5091
5565
|
});
|
|
5092
5566
|
}
|
|
5567
|
+
/**
|
|
5568
|
+
* Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply.
|
|
5569
|
+
*
|
|
5570
|
+
* The fourth argument is optional. It can have a storeName property - if true, the original name will be stored
|
|
5571
|
+
* for later inclusion in a sourcemap's names array - and an overwrite property which determines whether only
|
|
5572
|
+
* the content is overwritten, or anything that was appended/prepended to the range as well.
|
|
5573
|
+
*/
|
|
5093
5574
|
update(start, end, content, options) {
|
|
5094
5575
|
start = start + this.offset;
|
|
5095
5576
|
end = end + this.offset;
|
|
5096
|
-
if (typeof content !== "string") throw new
|
|
5577
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
5097
5578
|
if (this.original.length !== 0) {
|
|
5098
5579
|
while (start < 0) start += this.original.length;
|
|
5099
5580
|
while (end < 0) end += this.original.length;
|
|
5100
5581
|
}
|
|
5101
|
-
if (
|
|
5102
|
-
if (
|
|
5582
|
+
if (start < 0) throw new MagicStringError(`start ${start} is out of bounds`);
|
|
5583
|
+
if (end > this.original.length) throw new MagicStringError(`end ${end} is out of bounds`);
|
|
5584
|
+
if (start === end) throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`);
|
|
5585
|
+
if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
|
|
5103
5586
|
this._split(start);
|
|
5104
5587
|
this._split(end);
|
|
5105
5588
|
if (options === true) {
|
|
@@ -5109,8 +5592,9 @@ var MagicString = class MagicString {
|
|
|
5109
5592
|
}
|
|
5110
5593
|
options = { storeName: true };
|
|
5111
5594
|
}
|
|
5112
|
-
const
|
|
5113
|
-
const
|
|
5595
|
+
const optionObject = typeof options === "object" && options ? options : {};
|
|
5596
|
+
const storeName = optionObject.storeName || false;
|
|
5597
|
+
const overwrite = optionObject.overwrite || false;
|
|
5114
5598
|
if (storeName) {
|
|
5115
5599
|
const original = this.original.slice(start, end);
|
|
5116
5600
|
Object.defineProperty(this.storedNames, original, {
|
|
@@ -5119,12 +5603,12 @@ var MagicString = class MagicString {
|
|
|
5119
5603
|
enumerable: true
|
|
5120
5604
|
});
|
|
5121
5605
|
}
|
|
5122
|
-
const first = this.byStart
|
|
5123
|
-
const last = this.byEnd
|
|
5606
|
+
const first = this.byStart.get(start);
|
|
5607
|
+
const last = this.byEnd.get(end);
|
|
5124
5608
|
if (first) {
|
|
5125
5609
|
let chunk = first;
|
|
5126
5610
|
while (chunk !== last) {
|
|
5127
|
-
if (chunk.next !== this.byStart
|
|
5611
|
+
if (chunk.next !== this.byStart.get(chunk.end)) throw new MagicStringError("cannot overwrite across a split point");
|
|
5128
5612
|
chunk = chunk.next;
|
|
5129
5613
|
chunk.edit("", false);
|
|
5130
5614
|
}
|
|
@@ -5136,29 +5620,42 @@ var MagicString = class MagicString {
|
|
|
5136
5620
|
}
|
|
5137
5621
|
return this;
|
|
5138
5622
|
}
|
|
5623
|
+
/**
|
|
5624
|
+
* Prepends the string with the specified content.
|
|
5625
|
+
*/
|
|
5139
5626
|
prepend(content) {
|
|
5140
|
-
if (typeof content !== "string") throw new
|
|
5627
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
5141
5628
|
this.intro = content + this.intro;
|
|
5142
5629
|
return this;
|
|
5143
5630
|
}
|
|
5631
|
+
/**
|
|
5632
|
+
* Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index
|
|
5633
|
+
*/
|
|
5144
5634
|
prependLeft(index, content) {
|
|
5145
5635
|
index = index + this.offset;
|
|
5146
|
-
if (typeof content !== "string") throw new
|
|
5636
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
5147
5637
|
this._split(index);
|
|
5148
|
-
const chunk = this.byEnd
|
|
5638
|
+
const chunk = this.byEnd.get(index);
|
|
5149
5639
|
if (chunk) chunk.prependLeft(content);
|
|
5150
5640
|
else this.intro = content + this.intro;
|
|
5151
5641
|
return this;
|
|
5152
5642
|
}
|
|
5643
|
+
/**
|
|
5644
|
+
* Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index`
|
|
5645
|
+
*/
|
|
5153
5646
|
prependRight(index, content) {
|
|
5154
5647
|
index = index + this.offset;
|
|
5155
|
-
if (typeof content !== "string") throw new
|
|
5648
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
5156
5649
|
this._split(index);
|
|
5157
|
-
const chunk = this.byStart
|
|
5650
|
+
const chunk = this.byStart.get(index);
|
|
5158
5651
|
if (chunk) chunk.prependRight(content);
|
|
5159
5652
|
else this.outro = content + this.outro;
|
|
5160
5653
|
return this;
|
|
5161
5654
|
}
|
|
5655
|
+
/**
|
|
5656
|
+
* Removes the characters from `start` to `end` (of the original string, **not** the generated string).
|
|
5657
|
+
* Removing the same content twice, or making removals that partially overlap, will cause an error.
|
|
5658
|
+
*/
|
|
5162
5659
|
remove(start, end) {
|
|
5163
5660
|
start = start + this.offset;
|
|
5164
5661
|
end = end + this.offset;
|
|
@@ -5167,19 +5664,22 @@ var MagicString = class MagicString {
|
|
|
5167
5664
|
while (end < 0) end += this.original.length;
|
|
5168
5665
|
}
|
|
5169
5666
|
if (start === end) return this;
|
|
5170
|
-
if (start < 0 || end > this.original.length) throw new
|
|
5171
|
-
if (start > end) throw new
|
|
5667
|
+
if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
|
|
5668
|
+
if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
|
|
5172
5669
|
this._split(start);
|
|
5173
5670
|
this._split(end);
|
|
5174
|
-
let chunk = this.byStart
|
|
5671
|
+
let chunk = this.byStart.get(start);
|
|
5175
5672
|
while (chunk) {
|
|
5176
5673
|
chunk.intro = "";
|
|
5177
5674
|
chunk.outro = "";
|
|
5178
5675
|
chunk.edit("");
|
|
5179
|
-
chunk = end > chunk.end ? this.byStart
|
|
5676
|
+
chunk = end > chunk.end ? this.byStart.get(chunk.end) : null;
|
|
5180
5677
|
}
|
|
5181
5678
|
return this;
|
|
5182
5679
|
}
|
|
5680
|
+
/**
|
|
5681
|
+
* Reset the modified characters from `start` to `end` (of the original string, **not** the generated string).
|
|
5682
|
+
*/
|
|
5183
5683
|
reset(start, end) {
|
|
5184
5684
|
start = start + this.offset;
|
|
5185
5685
|
end = end + this.offset;
|
|
@@ -5188,25 +5688,26 @@ var MagicString = class MagicString {
|
|
|
5188
5688
|
while (end < 0) end += this.original.length;
|
|
5189
5689
|
}
|
|
5190
5690
|
if (start === end) return this;
|
|
5191
|
-
if (start < 0 || end > this.original.length) throw new
|
|
5192
|
-
if (start > end) throw new
|
|
5691
|
+
if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
|
|
5692
|
+
if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
|
|
5193
5693
|
this._split(start);
|
|
5194
5694
|
this._split(end);
|
|
5195
|
-
let chunk = this.byStart
|
|
5695
|
+
let chunk = this.byStart.get(start);
|
|
5196
5696
|
while (chunk) {
|
|
5197
5697
|
chunk.reset();
|
|
5198
|
-
chunk = end > chunk.end ? this.byStart
|
|
5698
|
+
chunk = end > chunk.end ? this.byStart.get(chunk.end) : null;
|
|
5199
5699
|
}
|
|
5200
5700
|
return this;
|
|
5201
5701
|
}
|
|
5202
5702
|
lastChar() {
|
|
5203
5703
|
if (this.outro.length) return this.outro[this.outro.length - 1];
|
|
5204
5704
|
let chunk = this.lastChunk;
|
|
5205
|
-
|
|
5705
|
+
while (chunk) {
|
|
5206
5706
|
if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];
|
|
5207
5707
|
if (chunk.content.length) return chunk.content[chunk.content.length - 1];
|
|
5208
5708
|
if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];
|
|
5209
|
-
|
|
5709
|
+
chunk = chunk.previous;
|
|
5710
|
+
}
|
|
5210
5711
|
if (this.intro.length) return this.intro[this.intro.length - 1];
|
|
5211
5712
|
return "";
|
|
5212
5713
|
}
|
|
@@ -5215,7 +5716,7 @@ var MagicString = class MagicString {
|
|
|
5215
5716
|
if (lineIndex !== -1) return this.outro.substr(lineIndex + 1);
|
|
5216
5717
|
let lineStr = this.outro;
|
|
5217
5718
|
let chunk = this.lastChunk;
|
|
5218
|
-
|
|
5719
|
+
while (chunk) {
|
|
5219
5720
|
if (chunk.outro.length > 0) {
|
|
5220
5721
|
lineIndex = chunk.outro.lastIndexOf(n);
|
|
5221
5722
|
if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;
|
|
@@ -5231,11 +5732,16 @@ var MagicString = class MagicString {
|
|
|
5231
5732
|
if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;
|
|
5232
5733
|
lineStr = chunk.intro + lineStr;
|
|
5233
5734
|
}
|
|
5234
|
-
|
|
5735
|
+
chunk = chunk.previous;
|
|
5736
|
+
}
|
|
5235
5737
|
lineIndex = this.intro.lastIndexOf(n);
|
|
5236
5738
|
if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;
|
|
5237
5739
|
return this.intro + lineStr;
|
|
5238
5740
|
}
|
|
5741
|
+
/**
|
|
5742
|
+
* Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string.
|
|
5743
|
+
* Throws error if the indices are for characters that were already removed.
|
|
5744
|
+
*/
|
|
5239
5745
|
slice(start = 0, end = this.original.length - this.offset) {
|
|
5240
5746
|
start = start + this.offset;
|
|
5241
5747
|
end = end + this.offset;
|
|
@@ -5249,12 +5755,12 @@ var MagicString = class MagicString {
|
|
|
5249
5755
|
if (chunk.start < end && chunk.end >= end) return result;
|
|
5250
5756
|
chunk = chunk.next;
|
|
5251
5757
|
}
|
|
5252
|
-
if (chunk && chunk.edited && chunk.start !== start) throw new
|
|
5758
|
+
if (chunk && chunk.edited && chunk.start !== start) throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`);
|
|
5253
5759
|
const startChunk = chunk;
|
|
5254
5760
|
while (chunk) {
|
|
5255
5761
|
if (chunk.intro && (startChunk !== chunk || chunk.start === start)) result += chunk.intro;
|
|
5256
5762
|
const containsEnd = chunk.start < end && chunk.end >= end;
|
|
5257
|
-
if (containsEnd && chunk.edited && chunk.end !== end) throw new
|
|
5763
|
+
if (containsEnd && chunk.edited && chunk.end !== end) throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`);
|
|
5258
5764
|
const sliceStart = startChunk === chunk ? start - chunk.start : 0;
|
|
5259
5765
|
const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
|
|
5260
5766
|
result += chunk.content.slice(sliceStart, sliceEnd);
|
|
@@ -5264,37 +5770,45 @@ var MagicString = class MagicString {
|
|
|
5264
5770
|
}
|
|
5265
5771
|
return result;
|
|
5266
5772
|
}
|
|
5773
|
+
/**
|
|
5774
|
+
* Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed.
|
|
5775
|
+
*/
|
|
5267
5776
|
snip(start, end) {
|
|
5268
5777
|
const clone = this.clone();
|
|
5269
5778
|
clone.remove(0, start);
|
|
5270
5779
|
clone.remove(end, clone.original.length);
|
|
5271
5780
|
return clone;
|
|
5272
5781
|
}
|
|
5782
|
+
/** @internal */
|
|
5273
5783
|
_split(index) {
|
|
5274
|
-
if (this.byStart
|
|
5784
|
+
if (this.byStart.get(index) || this.byEnd.get(index)) return;
|
|
5275
5785
|
let chunk = this.lastSearchedChunk;
|
|
5276
5786
|
let previousChunk = chunk;
|
|
5277
5787
|
const searchForward = index > chunk.end;
|
|
5278
5788
|
while (chunk) {
|
|
5279
5789
|
if (chunk.contains(index)) return this._splitChunk(chunk, index);
|
|
5280
|
-
chunk = searchForward ? this.byStart
|
|
5790
|
+
chunk = searchForward ? this.byStart.get(chunk.end) : this.byEnd.get(chunk.start);
|
|
5281
5791
|
if (chunk === previousChunk) return;
|
|
5282
5792
|
previousChunk = chunk;
|
|
5283
5793
|
}
|
|
5284
5794
|
}
|
|
5795
|
+
/** @internal */
|
|
5285
5796
|
_splitChunk(chunk, index) {
|
|
5286
5797
|
if (chunk.edited && chunk.content.length) {
|
|
5287
5798
|
const loc = getLocator(this.original)(index);
|
|
5288
|
-
throw new
|
|
5799
|
+
throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`);
|
|
5289
5800
|
}
|
|
5290
5801
|
const newChunk = chunk.split(index);
|
|
5291
|
-
this.byEnd
|
|
5292
|
-
this.byStart
|
|
5293
|
-
this.byEnd
|
|
5802
|
+
this.byEnd.set(index, chunk);
|
|
5803
|
+
this.byStart.set(index, newChunk);
|
|
5804
|
+
this.byEnd.set(newChunk.end, newChunk);
|
|
5294
5805
|
if (chunk === this.lastChunk) this.lastChunk = newChunk;
|
|
5295
5806
|
this.lastSearchedChunk = chunk;
|
|
5296
5807
|
return true;
|
|
5297
5808
|
}
|
|
5809
|
+
/**
|
|
5810
|
+
* Returns the generated string.
|
|
5811
|
+
*/
|
|
5298
5812
|
toString() {
|
|
5299
5813
|
let str = this.intro;
|
|
5300
5814
|
let chunk = this.firstChunk;
|
|
@@ -5304,29 +5818,41 @@ var MagicString = class MagicString {
|
|
|
5304
5818
|
}
|
|
5305
5819
|
return str + this.outro;
|
|
5306
5820
|
}
|
|
5821
|
+
/**
|
|
5822
|
+
* Returns true if the resulting source is empty (disregarding white space).
|
|
5823
|
+
*/
|
|
5307
5824
|
isEmpty() {
|
|
5308
5825
|
let chunk = this.firstChunk;
|
|
5309
|
-
|
|
5826
|
+
while (chunk) {
|
|
5310
5827
|
if (chunk.intro.length && chunk.intro.trim() || chunk.content.length && chunk.content.trim() || chunk.outro.length && chunk.outro.trim()) return false;
|
|
5311
|
-
|
|
5828
|
+
chunk = chunk.next;
|
|
5829
|
+
}
|
|
5312
5830
|
return true;
|
|
5313
5831
|
}
|
|
5314
5832
|
length() {
|
|
5315
5833
|
let chunk = this.firstChunk;
|
|
5316
5834
|
let length = 0;
|
|
5317
|
-
|
|
5835
|
+
while (chunk) {
|
|
5318
5836
|
length += chunk.intro.length + chunk.content.length + chunk.outro.length;
|
|
5319
|
-
|
|
5837
|
+
chunk = chunk.next;
|
|
5838
|
+
}
|
|
5320
5839
|
return length;
|
|
5321
5840
|
}
|
|
5841
|
+
/**
|
|
5842
|
+
* Removes empty lines from the start and end.
|
|
5843
|
+
*/
|
|
5322
5844
|
trimLines() {
|
|
5323
5845
|
return this.trim("[\\r\\n]");
|
|
5324
5846
|
}
|
|
5847
|
+
/**
|
|
5848
|
+
* Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end.
|
|
5849
|
+
*/
|
|
5325
5850
|
trim(charType) {
|
|
5326
5851
|
return this.trimStart(charType).trimEnd(charType);
|
|
5327
5852
|
}
|
|
5853
|
+
/** @internal */
|
|
5328
5854
|
trimEndAborted(charType) {
|
|
5329
|
-
const rx = new RegExp(
|
|
5855
|
+
const rx = new RegExp(`${charType || "\\s"}+$`);
|
|
5330
5856
|
this.outro = this.outro.replace(rx, "");
|
|
5331
5857
|
if (this.outro.length) return true;
|
|
5332
5858
|
let chunk = this.lastChunk;
|
|
@@ -5335,21 +5861,25 @@ var MagicString = class MagicString {
|
|
|
5335
5861
|
const aborted = chunk.trimEnd(rx);
|
|
5336
5862
|
if (chunk.end !== end) {
|
|
5337
5863
|
if (this.lastChunk === chunk) this.lastChunk = chunk.next;
|
|
5338
|
-
this.byEnd
|
|
5339
|
-
this.byStart
|
|
5340
|
-
this.byEnd
|
|
5864
|
+
this.byEnd.set(chunk.end, chunk);
|
|
5865
|
+
this.byStart.set(chunk.next.start, chunk.next);
|
|
5866
|
+
this.byEnd.set(chunk.next.end, chunk.next);
|
|
5341
5867
|
}
|
|
5342
5868
|
if (aborted) return true;
|
|
5343
5869
|
chunk = chunk.previous;
|
|
5344
5870
|
} while (chunk);
|
|
5345
5871
|
return false;
|
|
5346
5872
|
}
|
|
5873
|
+
/**
|
|
5874
|
+
* Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end.
|
|
5875
|
+
*/
|
|
5347
5876
|
trimEnd(charType) {
|
|
5348
5877
|
this.trimEndAborted(charType);
|
|
5349
5878
|
return this;
|
|
5350
5879
|
}
|
|
5880
|
+
/** @internal */
|
|
5351
5881
|
trimStartAborted(charType) {
|
|
5352
|
-
const rx = new RegExp(
|
|
5882
|
+
const rx = new RegExp(`^${charType || "\\s"}+`);
|
|
5353
5883
|
this.intro = this.intro.replace(rx, "");
|
|
5354
5884
|
if (this.intro.length) return true;
|
|
5355
5885
|
let chunk = this.firstChunk;
|
|
@@ -5358,22 +5888,41 @@ var MagicString = class MagicString {
|
|
|
5358
5888
|
const aborted = chunk.trimStart(rx);
|
|
5359
5889
|
if (chunk.end !== end) {
|
|
5360
5890
|
if (chunk === this.lastChunk) this.lastChunk = chunk.next;
|
|
5361
|
-
this.byEnd
|
|
5362
|
-
this.byStart
|
|
5363
|
-
this.byEnd
|
|
5891
|
+
this.byEnd.set(chunk.end, chunk);
|
|
5892
|
+
this.byStart.set(chunk.next.start, chunk.next);
|
|
5893
|
+
this.byEnd.set(chunk.next.end, chunk.next);
|
|
5364
5894
|
}
|
|
5365
5895
|
if (aborted) return true;
|
|
5366
5896
|
chunk = chunk.next;
|
|
5367
5897
|
} while (chunk);
|
|
5368
5898
|
return false;
|
|
5369
5899
|
}
|
|
5900
|
+
/**
|
|
5901
|
+
* Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start.
|
|
5902
|
+
*/
|
|
5370
5903
|
trimStart(charType) {
|
|
5371
5904
|
this.trimStartAborted(charType);
|
|
5372
5905
|
return this;
|
|
5373
5906
|
}
|
|
5907
|
+
/**
|
|
5908
|
+
* Indicates if the string has been changed.
|
|
5909
|
+
*/
|
|
5374
5910
|
hasChanged() {
|
|
5375
|
-
|
|
5911
|
+
if (this.intro || this.outro) return true;
|
|
5912
|
+
let outputIndex = 0;
|
|
5913
|
+
let chunk = this.firstChunk;
|
|
5914
|
+
while (chunk) {
|
|
5915
|
+
if (chunk.intro || chunk.outro) return true;
|
|
5916
|
+
if (!chunk.edited && chunk.start === outputIndex) outputIndex = chunk.end;
|
|
5917
|
+
else {
|
|
5918
|
+
if (!this.original.startsWith(chunk.content, outputIndex)) return true;
|
|
5919
|
+
outputIndex += chunk.content.length;
|
|
5920
|
+
}
|
|
5921
|
+
chunk = chunk.next;
|
|
5922
|
+
}
|
|
5923
|
+
return outputIndex !== this.original.length;
|
|
5376
5924
|
}
|
|
5925
|
+
/** @internal */
|
|
5377
5926
|
_replaceRegexp(searchValue, replacement) {
|
|
5378
5927
|
function getReplacement(match, str) {
|
|
5379
5928
|
if (typeof replacement === "string") return replacement.replace(/\$(\$|&|\d+)/g, (_, i) => {
|
|
@@ -5382,12 +5931,15 @@ var MagicString = class MagicString {
|
|
|
5382
5931
|
if (+i < match.length) return match[+i];
|
|
5383
5932
|
return `$${i}`;
|
|
5384
5933
|
});
|
|
5385
|
-
else return replacement(...match, match.index, str, match.groups);
|
|
5934
|
+
else return replacement(match[0], ...match.slice(1), match.index, str, match.groups);
|
|
5386
5935
|
}
|
|
5387
5936
|
function matchAll(re, str) {
|
|
5388
|
-
let match;
|
|
5389
5937
|
const matches = [];
|
|
5390
|
-
while (
|
|
5938
|
+
while (true) {
|
|
5939
|
+
const match = re.exec(str);
|
|
5940
|
+
if (!match) break;
|
|
5941
|
+
matches.push(match);
|
|
5942
|
+
}
|
|
5391
5943
|
return matches;
|
|
5392
5944
|
}
|
|
5393
5945
|
if (searchValue.global) matchAll(searchValue, this.original).forEach((match) => {
|
|
@@ -5405,6 +5957,7 @@ var MagicString = class MagicString {
|
|
|
5405
5957
|
}
|
|
5406
5958
|
return this;
|
|
5407
5959
|
}
|
|
5960
|
+
/** @internal */
|
|
5408
5961
|
_replaceString(string, replacement) {
|
|
5409
5962
|
const { original } = this;
|
|
5410
5963
|
const index = original.indexOf(string);
|
|
@@ -5414,24 +5967,30 @@ var MagicString = class MagicString {
|
|
|
5414
5967
|
}
|
|
5415
5968
|
return this;
|
|
5416
5969
|
}
|
|
5970
|
+
/**
|
|
5971
|
+
* String replacement with RegExp or string.
|
|
5972
|
+
*/
|
|
5417
5973
|
replace(searchValue, replacement) {
|
|
5418
5974
|
if (typeof searchValue === "string") return this._replaceString(searchValue, replacement);
|
|
5419
5975
|
return this._replaceRegexp(searchValue, replacement);
|
|
5420
5976
|
}
|
|
5977
|
+
/** @internal */
|
|
5421
5978
|
_replaceAllString(string, replacement) {
|
|
5422
5979
|
const { original } = this;
|
|
5423
5980
|
const stringLength = string.length;
|
|
5424
5981
|
for (let index = original.indexOf(string); index !== -1; index = original.indexOf(string, index + stringLength)) {
|
|
5425
5982
|
const previous = original.slice(index, index + stringLength);
|
|
5426
|
-
|
|
5427
|
-
if (typeof replacement === "function") _replacement = replacement(previous, index, original);
|
|
5983
|
+
const _replacement = typeof replacement === "function" ? replacement(previous, index, original) : replacement;
|
|
5428
5984
|
if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);
|
|
5429
5985
|
}
|
|
5430
5986
|
return this;
|
|
5431
5987
|
}
|
|
5988
|
+
/**
|
|
5989
|
+
* Same as `s.replace`, but replace all matched strings instead of just one.
|
|
5990
|
+
*/
|
|
5432
5991
|
replaceAll(searchValue, replacement) {
|
|
5433
5992
|
if (typeof searchValue === "string") return this._replaceAllString(searchValue, replacement);
|
|
5434
|
-
if (!searchValue.global) throw new
|
|
5993
|
+
if (!searchValue.global) throw new MagicStringError("replaceAll() requires a global RegExp");
|
|
5435
5994
|
return this._replaceRegexp(searchValue, replacement);
|
|
5436
5995
|
}
|
|
5437
5996
|
};
|
|
@@ -5832,6 +6391,7 @@ function timberFonts(ctx) {
|
|
|
5832
6391
|
if (pipeline.cssIdMap.matches(id)) {
|
|
5833
6392
|
const importer = pipeline.cssIdMap.importerFor(id);
|
|
5834
6393
|
if (!importer) return "";
|
|
6394
|
+
if (process.env.TIMBER_ANALYZE === "1") return "";
|
|
5835
6395
|
const skipFonts = process.env.TIMBER_SKIP_FONTS === "1";
|
|
5836
6396
|
for (const font of pipeline.googleFonts()) {
|
|
5837
6397
|
if (font.importer !== importer) continue;
|
|
@@ -7339,8 +7899,10 @@ function lookupFacades(id, sharedModuleFacades) {
|
|
|
7339
7899
|
if (!isBareSpecifier(id)) return void 0;
|
|
7340
7900
|
const needle = `/node_modules/${id}/`;
|
|
7341
7901
|
let merged;
|
|
7342
|
-
for (const [key, facades] of sharedModuleFacades) if (key.includes(needle))
|
|
7343
|
-
|
|
7902
|
+
for (const [key, facades] of sharedModuleFacades) if (key.includes(needle)) {
|
|
7903
|
+
if (!merged) merged = [...facades];
|
|
7904
|
+
else merged.push(...facades);
|
|
7905
|
+
}
|
|
7344
7906
|
return merged;
|
|
7345
7907
|
}
|
|
7346
7908
|
/**
|
|
@@ -7415,6 +7977,7 @@ function clientChunkGroup(meta, appDir, root, sharedModuleFacades) {
|
|
|
7415
7977
|
*
|
|
7416
7978
|
* Design docs: design/11-platform.md, design/25-production-deployments.md
|
|
7417
7979
|
*/
|
|
7980
|
+
var POISON_MARKER_SPECIFIERS = EXPLICIT_MARKERS.map((m) => m.specifier);
|
|
7418
7981
|
var NODE_BUILTINS = builtinModules.flatMap((m) => [m, `node:${m}`]);
|
|
7419
7982
|
var CLOUDFLARE_BUILTINS = [
|
|
7420
7983
|
"cloudflare:workers",
|
|
@@ -7439,12 +8002,8 @@ function timberServerBundle() {
|
|
|
7439
8002
|
name: "timber-server-bundle",
|
|
7440
8003
|
config(_cfg, { command }) {
|
|
7441
8004
|
if (command === "serve") return { environments: {
|
|
7442
|
-
rsc: { resolve: { noExternal: [
|
|
7443
|
-
ssr: { resolve: { noExternal: [
|
|
7444
|
-
"server-only",
|
|
7445
|
-
"client-only",
|
|
7446
|
-
"nuqs"
|
|
7447
|
-
] } }
|
|
8005
|
+
rsc: { resolve: { noExternal: [...POISON_MARKER_SPECIFIERS] } },
|
|
8006
|
+
ssr: { resolve: { noExternal: [...POISON_MARKER_SPECIFIERS, "nuqs"] } }
|
|
7448
8007
|
} };
|
|
7449
8008
|
const serverDefine = { "process.env.NODE_ENV": JSON.stringify("production") };
|
|
7450
8009
|
return {
|
|
@@ -7572,9 +8131,7 @@ function collectPatternNames(node, out) {
|
|
|
7572
8131
|
for (const prop of node.properties ?? []) if (prop.type === "RestElement") collectPatternNames(prop, out);
|
|
7573
8132
|
else collectPatternNames(prop.value, out);
|
|
7574
8133
|
break;
|
|
7575
|
-
case "TSParameterProperty":
|
|
7576
|
-
if (node.parameter) collectPatternNames(node.parameter, out);
|
|
7577
|
-
break;
|
|
8134
|
+
case "TSParameterProperty": if (node.parameter) collectPatternNames(node.parameter, out);
|
|
7578
8135
|
}
|
|
7579
8136
|
}
|
|
7580
8137
|
/** Return the intersection of param names with `tracked`, or null if none. */
|
|
@@ -7946,7 +8503,8 @@ function timberCacheTransform(ctx) {
|
|
|
7946
8503
|
}
|
|
7947
8504
|
if (callSites.length === 0) return;
|
|
7948
8505
|
callSites.sort((a, b) => a.call.start - b.call.start);
|
|
7949
|
-
const
|
|
8506
|
+
const root = ctx.root || process.cwd();
|
|
8507
|
+
const relPath = relative(root, id);
|
|
7950
8508
|
const s = new MagicString(code);
|
|
7951
8509
|
const occurrences = /* @__PURE__ */ new Map();
|
|
7952
8510
|
for (const { call, stmt } of callSites) {
|
|
@@ -8271,9 +8829,7 @@ function analyzeModule(program) {
|
|
|
8271
8829
|
case "ExportAllDeclaration":
|
|
8272
8830
|
collectExportAll(stmt, facts);
|
|
8273
8831
|
break;
|
|
8274
|
-
case "ExportDefaultDeclaration":
|
|
8275
|
-
collectExportDefault(stmt, facts);
|
|
8276
|
-
break;
|
|
8832
|
+
case "ExportDefaultDeclaration": collectExportDefault(stmt, facts);
|
|
8277
8833
|
}
|
|
8278
8834
|
walk(program, facts);
|
|
8279
8835
|
return facts;
|
|
@@ -9354,7 +9910,8 @@ function timberPrebuilt(ctx) {
|
|
|
9354
9910
|
if (bindings.named.size === 0 && bindings.namespaces.size === 0) return;
|
|
9355
9911
|
const callSites = collectModuleScopeSites(program, bindings);
|
|
9356
9912
|
if (callSites.length === 0) return;
|
|
9357
|
-
const
|
|
9913
|
+
const root = ctx.root || process.cwd();
|
|
9914
|
+
const relPath = relative(root, id);
|
|
9358
9915
|
const s = new MagicString(code);
|
|
9359
9916
|
const occurrences = /* @__PURE__ */ new Map();
|
|
9360
9917
|
const wrapperName = ctx.dev ? "__prebuiltDev" : "__prebuilt";
|
|
@@ -9514,27 +10071,24 @@ function timberPrebuilt(ctx) {
|
|
|
9514
10071
|
* `export const prerender` to descendant pages via most-specific-wins:
|
|
9515
10072
|
* walk the segment tree from leaf to root, first explicit value wins.
|
|
9516
10073
|
*
|
|
9517
|
-
*
|
|
9518
|
-
*
|
|
9519
|
-
*
|
|
9520
|
-
*
|
|
9521
|
-
* Propagation.
|
|
10074
|
+
* Layout declarations are propagation policy only. Layouts receive the real
|
|
10075
|
+
* descendant React element as `children` to preserve the server-layout
|
|
10076
|
+
* containment boundary, so their props are not cache-keyable and the layout
|
|
10077
|
+
* itself must not be registered for capture.
|
|
9522
10078
|
*
|
|
9523
10079
|
* This transform runs BEFORE timber-prebuilt so the generated
|
|
9524
10080
|
* `cache.component(...)` call is picked up by the callsite rewrite.
|
|
9525
10081
|
*/
|
|
9526
10082
|
/**
|
|
9527
10083
|
* Walk the segment tree and resolve the effective prerender value for
|
|
9528
|
-
* every page
|
|
10084
|
+
* every page. Returns a map from page file path to resolved value.
|
|
9529
10085
|
*
|
|
9530
10086
|
* **Pages:** walk from leaf toward root; first explicit `export const prerender`
|
|
9531
10087
|
* wins (page > nearest layout > ... > root layout). If none, dynamic.
|
|
9532
10088
|
*
|
|
9533
|
-
* **Layouts:**
|
|
9534
|
-
*
|
|
9535
|
-
*
|
|
9536
|
-
* inherit from ancestors, because wrapping a layout's shell without the
|
|
9537
|
-
* author's explicit opt-in would cache content they may expect to be dynamic.
|
|
10089
|
+
* **Layouts:** declarations propagate to descendant pages but layouts are not
|
|
10090
|
+
* included in the result. Their real React-element `children` preserve secure
|
|
10091
|
+
* containment and deliberately make child-independent layout caching invalid.
|
|
9538
10092
|
*/
|
|
9539
10093
|
function resolvePagePrerender(root) {
|
|
9540
10094
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -9542,7 +10096,6 @@ function resolvePagePrerender(root) {
|
|
|
9542
10096
|
if (node.segmentType === "intercepting" || node.segmentType === "private") return;
|
|
9543
10097
|
const layoutValue = node.layout ? getPrerenderExport(node.layout.filePath) : void 0;
|
|
9544
10098
|
const stack = layoutValue !== void 0 ? [layoutValue, ...ancestorStack] : ancestorStack;
|
|
9545
|
-
if (node.layout && layoutValue !== void 0 && layoutValue !== false) result.set(node.layout.filePath, layoutValue);
|
|
9546
10099
|
if (node.page) {
|
|
9547
10100
|
const pageValue = getPrerenderExport(node.page.filePath);
|
|
9548
10101
|
const resolved = pageValue !== void 0 ? pageValue : stack[0];
|
|
@@ -10529,27 +11082,6 @@ function defineConfig(config) {
|
|
|
10529
11082
|
return config;
|
|
10530
11083
|
}
|
|
10531
11084
|
/**
|
|
10532
|
-
* Resolve the React Compiler plugin via @rolldown/plugin-babel.
|
|
10533
|
-
*
|
|
10534
|
-
* Uses the `reactCompilerPreset` from @vitejs/plugin-react, which:
|
|
10535
|
-
* - Uses Babel ONLY for the compiler pass (OXC handles JSX)
|
|
10536
|
-
* - Automatically scopes to client environment via applyToEnvironmentHook
|
|
10537
|
-
* - Uses react/compiler-runtime built into React 19
|
|
10538
|
-
*
|
|
10539
|
-
* @rolldown/plugin-babel and babel-plugin-react-compiler are optional peer deps.
|
|
10540
|
-
* If either is missing, require() fails with a clear error message.
|
|
10541
|
-
*/
|
|
10542
|
-
function resolveReactCompilerPlugin(config, req) {
|
|
10543
|
-
let babel;
|
|
10544
|
-
try {
|
|
10545
|
-
babel = req("@rolldown/plugin-babel");
|
|
10546
|
-
} catch {
|
|
10547
|
-
throw new Error("[timber] reactCompiler requires @rolldown/plugin-babel. Install it: pnpm add -D @rolldown/plugin-babel babel-plugin-react-compiler");
|
|
10548
|
-
}
|
|
10549
|
-
const options = typeof config === "object" ? config : {};
|
|
10550
|
-
return (babel.default ?? babel)({ presets: [reactCompilerPreset(options)] });
|
|
10551
|
-
}
|
|
10552
|
-
/**
|
|
10553
11085
|
* Build the options object for @vitejs/plugin-rsc.
|
|
10554
11086
|
*
|
|
10555
11087
|
* Uses a getter for `enableActionEncryption` so the RSC plugin reads
|
|
@@ -10592,6 +11124,24 @@ function createRscOptions(ctx, encryptionKeyExpr) {
|
|
|
10592
11124
|
* causing file-based config for reactCompiler, actionEncryption, and
|
|
10593
11125
|
* output mode to be silently ignored. See TIM-451.
|
|
10594
11126
|
*/
|
|
11127
|
+
/**
|
|
11128
|
+
* Wrap plugin-react's `vite:react-compiler` configResolved so it always
|
|
11129
|
+
* sees `isProduction: true` during builds. The compiler plugin uses
|
|
11130
|
+
* `!config.isProduction` to decide whether to emit jsxDEV calls, but
|
|
11131
|
+
* Vite derives isProduction from process.env.NODE_ENV — which may be
|
|
11132
|
+
* "development" in the shell. Rather than mutating the env, we pass a
|
|
11133
|
+
* prototype-based view with the single property overridden.
|
|
11134
|
+
*/
|
|
11135
|
+
function patchReactCompilerForProdJsx(plugins) {
|
|
11136
|
+
for (const p of plugins) if (p && typeof p === "object" && "name" in p && p.name === "vite:react-compiler") {
|
|
11137
|
+
const orig = p.configResolved;
|
|
11138
|
+
if (typeof orig === "function") p.configResolved = function(config) {
|
|
11139
|
+
const view = config.command === "build" && !config.isProduction ? Object.create(config, { isProduction: { value: true } }) : config;
|
|
11140
|
+
return orig.call(this, view);
|
|
11141
|
+
};
|
|
11142
|
+
}
|
|
11143
|
+
return plugins;
|
|
11144
|
+
}
|
|
10595
11145
|
function timber(config) {
|
|
10596
11146
|
const ctx = createPluginContext(config);
|
|
10597
11147
|
const consumerRequire = createRequire(join(process.cwd(), "package.json"));
|
|
@@ -10625,7 +11175,8 @@ function timber(config) {
|
|
|
10625
11175
|
}
|
|
10626
11176
|
let resolvedDevPort = null;
|
|
10627
11177
|
let resolvedDevPortExplicit = false;
|
|
10628
|
-
|
|
11178
|
+
const isMiddlewareMode = Boolean(userConfig.server?.middlewareMode);
|
|
11179
|
+
if (command === "serve" && !isPreview && !isMiddlewareMode) {
|
|
10629
11180
|
ctx.holdingServer = createHoldingServer();
|
|
10630
11181
|
const holdingRef = ctx.holdingServer;
|
|
10631
11182
|
const result = await startDevServerPort({
|
|
@@ -10706,22 +11257,18 @@ function timber(config) {
|
|
|
10706
11257
|
ctx.buildDir = resolve(resolved.root, resolved.build.outDir);
|
|
10707
11258
|
if (!ctx.dev) ctx.timer = createNoopTimer();
|
|
10708
11259
|
else ctx.timer.start("dev-server-setup");
|
|
10709
|
-
const { validateConfig, formatConfigErrors, checkPeerDependencies, formatMissingPeers } = (init_config_validation(), __toCommonJS(config_validation_exports));
|
|
10710
11260
|
const configErrors = validateConfig(ctx.config);
|
|
10711
11261
|
if (configErrors.length > 0) process.stderr.write(`${formatConfigErrors(configErrors)}\n\n`);
|
|
10712
11262
|
const peerWarning = formatMissingPeers(checkPeerDependencies(ctx.root));
|
|
10713
11263
|
if (peerWarning) process.stderr.write(`${peerWarning}\n\n`);
|
|
10714
11264
|
}
|
|
10715
11265
|
};
|
|
10716
|
-
const
|
|
10717
|
-
const effectiveReactCompiler = config?.reactCompiler ?? earlyFileConfig?.reactCompiler;
|
|
10718
|
-
if (effectiveReactCompiler) reactCompilerPlugins.push(resolveReactCompilerPlugin(effectiveReactCompiler, consumerRequire));
|
|
11266
|
+
const effectiveReactCompiler = config?.reactCompiler ?? earlyFileConfig?.reactCompiler ?? true;
|
|
10719
11267
|
// @vitejs/plugin-rsc handles:
|
|
10720
11268
|
return [
|
|
10721
11269
|
rootSync,
|
|
10722
11270
|
timberReactProd(),
|
|
10723
|
-
react(),
|
|
10724
|
-
...reactCompilerPlugins,
|
|
11271
|
+
...patchReactCompilerForProdJsx(react({ compiler: effectiveReactCompiler || false })),
|
|
10725
11272
|
vitePluginRsc(createRscOptions(ctx, encryptionKeyExpr)),
|
|
10726
11273
|
timberShims(ctx),
|
|
10727
11274
|
timberRouting(ctx),
|