@timber-js/app 0.2.0-alpha.208 → 0.2.0-alpha.209
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/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
- package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
- package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
- package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
- package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
- package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
- package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
- package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
- package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
- package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
- package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
- package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
- package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
- package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
- package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
- package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
- package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
- package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
- package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
- package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
- package/dist/_chunks/{error-boundary-BrHmG-2X.js → error-boundary-tA7kVfs4.js} +84 -104
- package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
- package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
- package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
- package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
- package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
- package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
- package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
- package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
- package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
- package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
- package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
- package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
- package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
- package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
- package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
- package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
- package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
- package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
- package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
- package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
- package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
- package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
- package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
- package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
- package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
- package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
- package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
- package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
- package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
- package/dist/_chunks/{status-page-marker-CNbpUOPB.js → status-page-marker-gaihi0KZ.js} +53 -20
- package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
- package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
- package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +7 -7
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/canonicalize-module.d.ts +8 -0
- package/dist/adapters/canonicalize-module.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +2 -2
- package/dist/adapters/cloudflare.d.ts +30 -8
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -2
- package/dist/adapters/compress-module.d.ts +8 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +2 -3
- package/dist/adapters/fs-identity.d.ts.map +1 -1
- package/dist/adapters/nitro-presets.d.ts +0 -6
- package/dist/adapters/nitro-presets.d.ts.map +1 -1
- package/dist/adapters/nitro-preview.d.ts +43 -11
- package/dist/adapters/nitro-preview.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +1 -13
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +291 -176
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +7 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +105 -21
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js +0 -0
- package/dist/analyze/crawl-entry.js +3 -3
- package/dist/analyze/graph-cache.d.ts.map +1 -1
- package/dist/analyze/graph-command.js +4 -4
- package/dist/cache/index.js +2 -2
- package/dist/cache/json-lossy-check.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts.map +1 -1
- package/dist/cache/stores/memory.js +1 -1
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.js +1 -1
- package/dist/cli-check.d.ts +7 -37
- package/dist/cli-check.d.ts.map +1 -1
- package/dist/cli-context.d.ts +54 -0
- package/dist/cli-context.d.ts.map +1 -0
- package/dist/cli.d.ts +9 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -24
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +19 -29
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +7 -7
- package/dist/client/browser-entry/post-hydration.d.ts +6 -9
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +6 -11
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +4 -3
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/error-reconstituter.d.ts +3 -9
- package/dist/client/error-reconstituter.d.ts.map +1 -1
- package/dist/client/history.d.ts +12 -11
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +3 -3
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +68 -104
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +16 -7
- package/dist/client/navigation-commit.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +3 -5
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/react-root.d.ts +3 -2
- package/dist/client/react-root.d.ts.map +1 -1
- package/dist/client/router-pipeline.d.ts +1 -6
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +45 -39
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router-url.d.ts +24 -0
- package/dist/client/router-url.d.ts.map +1 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +8 -4
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/ssr-data.d.ts +18 -64
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +2 -5
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts +1 -1
- package/dist/config-types.d.ts +2 -1
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/dev-tools/dev-page-shell.d.ts +17 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
- package/dist/dev-tools/index.d.ts +1 -1
- package/dist/dev-tools/index.d.ts.map +1 -1
- package/dist/dev-tools/instrumentation.d.ts +17 -2
- package/dist/dev-tools/instrumentation.d.ts.map +1 -1
- package/dist/dev-tools/overlay.d.ts +6 -27
- package/dist/dev-tools/overlay.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +531 -373
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +26 -40
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +15 -2
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/post-build.d.ts +110 -0
- package/dist/plugins/post-build.d.ts.map +1 -0
- package/dist/plugins/prebuilt-capture.d.ts +11 -4
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
- package/dist/plugins/prebuilt.d.ts +17 -1
- package/dist/plugins/prebuilt.d.ts.map +1 -1
- package/dist/plugins/prerender-sugar.d.ts.map +1 -1
- package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
- package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +32 -9
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts +0 -9
- package/dist/routing/codegen-write.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/routing/segment-codegen.d.ts.map +1 -1
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +5 -4
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +46 -7
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +58 -5
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/children-interception.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +2 -23
- package/dist/server/cookie-context.d.ts.map +1 -1
- package/dist/server/csp-nonce.d.ts +0 -9
- package/dist/server/csp-nonce.d.ts.map +1 -1
- package/dist/server/csrf.d.ts +27 -4
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/debug.d.ts +0 -1
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +2 -1
- package/dist/server/default-logger.d.ts.map +1 -1
- package/dist/server/deny-boundary.d.ts +12 -6
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -3
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +9 -2
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +4 -4
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +10 -3
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/internal.d.ts +1 -4
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +961 -581
- package/dist/server/internal.js.map +1 -1
- package/dist/server/json-status-response.d.ts +34 -0
- package/dist/server/json-status-response.d.ts.map +1 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +11 -6
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-helpers.d.ts +95 -7
- package/dist/server/pipeline-helpers.d.ts.map +1 -1
- package/dist/server/pipeline-interception.d.ts +11 -0
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +11 -1
- package/dist/server/pipeline-outcome.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +2 -2
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +23 -35
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/prebuilt/capture-render.d.ts +25 -0
- package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-routes.d.ts +37 -0
- package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +79 -35
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
- package/dist/server/prebuilt/lifetime.d.ts +38 -0
- package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +7 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
- package/dist/server/prebuilt-builder.d.ts.map +1 -1
- package/dist/server/prebuilt-runtime.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +6 -81
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/react-cache-bridge.d.ts +59 -0
- package/dist/server/react-cache-bridge.d.ts.map +1 -0
- package/dist/server/react-cache-scope.d.ts +49 -0
- package/dist/server/react-cache-scope.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +15 -0
- package/dist/server/render-timeout.d.ts.map +1 -1
- package/dist/server/render-utils.d.ts +9 -0
- package/dist/server/render-utils.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +26 -5
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +7 -0
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +7 -0
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +0 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +5 -15
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +5 -6
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-signals.d.ts +65 -0
- package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/signal-identity.d.ts +43 -0
- package/dist/server/signal-identity.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +4 -3
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/slot-subtree-contain.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +91 -53
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +8 -5
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +26 -40
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +1 -1
- package/dist/server/static-generator.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +12 -0
- package/dist/server/stream-utils.d.ts.map +1 -1
- package/dist/server/tracing.d.ts +12 -16
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/server/version-skew.d.ts +3 -3
- package/dist/shared/csrf-reject.d.ts +16 -0
- package/dist/shared/csrf-reject.d.ts.map +1 -0
- package/dist/shared/error-digest.d.ts +28 -0
- package/dist/shared/error-digest.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +11 -10
- package/dist/shared/payload-root.d.ts.map +1 -1
- package/dist/shared/rsc-payload-path.d.ts +6 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -1
- package/dist/utils/write-file-atomic.d.ts +17 -0
- package/dist/utils/write-file-atomic.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +17 -14
- package/docs/api/32-api-cache.mdx +51 -23
- package/docs/api/34-api-config.mdx +34 -6
- package/docs/api/36-cli.mdx +11 -1
- package/docs/learn/03-fetching-data.mdx +17 -1
- package/docs/learn/04-access-control.mdx +1 -1
- package/docs/learn/10-caching.mdx +29 -11
- package/docs/learn/11-middleware.mdx +8 -2
- package/docs/learn/12-error-handling.mdx +6 -1
- package/package.json +5 -1
- package/src/adapters/build-output-helper.ts +55 -53
- package/src/adapters/canonicalize-module.ts +29 -0
- package/src/adapters/cloudflare.ts +105 -63
- package/src/adapters/compress-module.ts +16 -5
- package/src/adapters/fs-identity.ts +2 -3
- package/src/adapters/nitro-presets.ts +0 -15
- package/src/adapters/nitro-preview.ts +272 -136
- package/src/adapters/nitro.ts +119 -82
- package/src/adapters/shared.ts +23 -14
- package/src/adapters/types.ts +110 -21
- package/src/analyze/graph-cache.ts +3 -4
- package/src/cache/json-lossy-check.ts +3 -9
- package/src/cache/singleflight.ts +5 -2
- package/src/cache/sizeof.ts +3 -1
- package/src/cache/tag-aware-handler.ts +43 -26
- package/src/cli-check.ts +8 -98
- package/src/cli-context.ts +119 -0
- package/src/cli.ts +19 -28
- package/src/client/browser-dev.ts +1 -1
- package/src/client/browser-entry/action-dispatch.ts +26 -4
- package/src/client/browser-entry/hydrate.ts +53 -58
- package/src/client/browser-entry/index.ts +16 -27
- package/src/client/browser-entry/post-hydration.ts +6 -40
- package/src/client/browser-entry/router-init.ts +66 -84
- package/src/client/error-boundary.tsx +9 -41
- package/src/client/error-reconstituter.tsx +10 -5
- package/src/client/history.ts +18 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +35 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +65 -128
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +43 -22
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/ssr-data.ts +19 -80
- package/src/client/state.ts +2 -9
- package/src/client/use-pathname.ts +1 -1
- package/src/config-types.ts +2 -1
- package/src/config-validation.ts +2 -1
- package/src/dev-tools/dev-page-shell.ts +18 -0
- package/src/dev-tools/index.ts +0 -2
- package/src/dev-tools/instrumentation.ts +50 -2
- package/src/dev-tools/overlay.ts +8 -238
- package/src/index.ts +24 -14
- package/src/plugin-context.ts +39 -40
- package/src/plugins/build-manifest.ts +4 -11
- package/src/plugins/build-report.ts +70 -70
- package/src/plugins/dev-server.ts +24 -44
- package/src/plugins/entries.ts +2 -1
- package/src/plugins/fonts.ts +35 -7
- package/src/plugins/post-build.ts +327 -0
- package/src/plugins/prebuilt-capture.ts +28 -32
- package/src/plugins/prebuilt.ts +54 -39
- package/src/plugins/prerender-sugar.ts +0 -4
- package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
- package/src/plugins/shims.ts +1 -0
- package/src/plugins/static-build.ts +42 -74
- package/src/routing/codegen-write.ts +25 -3
- package/src/routing/segment-codegen.ts +3 -2
- package/src/rsc-runtime/vendor-types.d.ts +8 -0
- package/src/server/access-gate.tsx +2 -1
- package/src/server/action-client.ts +1 -1
- package/src/server/action-handler.ts +253 -110
- package/src/server/actions.ts +73 -25
- package/src/server/als-registry.ts +73 -5
- package/src/server/chain-url-parts.ts +1 -1
- package/src/server/children-interception.ts +2 -1
- package/src/server/cookie-context.ts +18 -48
- package/src/server/csp-nonce.ts +0 -12
- package/src/server/csrf.ts +140 -8
- package/src/server/debug.ts +0 -1
- package/src/server/default-logger.ts +2 -1
- package/src/server/deny-boundary.ts +25 -13
- package/src/server/deny-renderer.ts +30 -97
- package/src/server/error-boundary-wrapper.ts +7 -3
- package/src/server/fallback-error.ts +26 -11
- package/src/server/flight-scripts.ts +1 -1
- package/src/server/head-response.ts +4 -4
- package/src/server/html-injector-core.ts +2 -2
- package/src/server/html-injectors.ts +2 -4
- package/src/server/index.ts +0 -4
- package/src/server/instrumentation.ts +10 -3
- package/src/server/internal.ts +1 -6
- package/src/server/json-status-response.ts +105 -0
- package/src/server/logger.ts +39 -3
- package/src/server/param-coercion.ts +15 -12
- package/src/server/pipeline-helpers.ts +257 -12
- package/src/server/pipeline-interception.ts +133 -0
- package/src/server/pipeline-outcome.ts +103 -31
- package/src/server/pipeline-phases.ts +127 -237
- package/src/server/pipeline.ts +204 -207
- package/src/server/prebuilt/capture-render.ts +118 -0
- package/src/server/prebuilt/capture-routes.ts +104 -0
- package/src/server/prebuilt/capture-state.ts +155 -48
- package/src/server/prebuilt/lifetime.ts +151 -0
- package/src/server/prebuilt/slots.ts +14 -2
- package/src/server/prebuilt/synthetic-store.ts +3 -0
- package/src/server/prebuilt-builder.ts +30 -320
- package/src/server/prebuilt-runtime.ts +125 -129
- package/src/server/primitives.ts +8 -168
- package/src/server/react-cache-bridge.ts +124 -0
- package/src/server/react-cache-scope.ts +104 -0
- package/src/server/render-timeout.ts +20 -0
- package/src/server/render-utils.ts +11 -1
- package/src/server/request-context.ts +36 -9
- package/src/server/route-element-builder.ts +11 -6
- package/src/server/route-handler.ts +36 -23
- package/src/server/route-matcher.ts +15 -1
- package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
- package/src/server/rsc-entry/api-handler.ts +27 -103
- package/src/server/rsc-entry/deny-fallback.ts +93 -26
- package/src/server/rsc-entry/error-renderer.ts +39 -91
- package/src/server/rsc-entry/helpers.ts +2 -4
- package/src/server/rsc-entry/index.ts +64 -58
- package/src/server/rsc-entry/render-route.ts +15 -80
- package/src/server/rsc-entry/render-signals.ts +108 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
- package/src/server/rsc-entry/rsc-payload.ts +28 -61
- package/src/server/rsc-entry/rsc-stream.ts +113 -213
- package/src/server/rsc-entry/ssr-bridge.ts +2 -2
- package/src/server/rsc-entry/ssr-renderer.ts +182 -263
- package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
- package/src/server/signal-identity.ts +112 -0
- package/src/server/slot-resolver.ts +18 -18
- package/src/server/slot-subtree-contain.ts +2 -1
- package/src/server/ssr-bridge-types.ts +92 -56
- package/src/server/ssr-entry.ts +87 -111
- package/src/server/ssr-render.ts +55 -64
- package/src/server/ssr-wrappers.tsx +2 -2
- package/src/server/static-generator.ts +7 -42
- package/src/server/static-not-found.ts +3 -3
- package/src/server/stream-utils.ts +51 -0
- package/src/server/tracing.ts +58 -75
- package/src/server/types.ts +1 -1
- package/src/server/version-skew.ts +5 -5
- package/src/shared/csrf-reject.ts +15 -0
- package/src/shared/error-digest.ts +46 -0
- package/src/shared/payload-root.ts +11 -10
- package/src/shared/rsc-payload-path.ts +8 -1
- package/src/utils/write-file-atomic.ts +32 -0
- package/dist/_chunks/actions-jNrXdzgs.js +0 -346
- package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
- package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
- package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
- package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
- package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
- package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
- package/dist/_chunks/error-boundary-BrHmG-2X.js.map +0 -1
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
- package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
- package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
- package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
- package/dist/_chunks/segment-context-D9_89u34.js +0 -34
- package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
- package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
- package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
- package/dist/_chunks/state-FippDgxN.js.map +0 -1
- package/dist/_chunks/status-page-marker-CNbpUOPB.js.map +0 -1
- package/dist/client/types.d.ts +0 -14
- package/dist/client/types.d.ts.map +0 -1
- package/dist/plugins/adapter-build.d.ts +0 -38
- package/dist/plugins/adapter-build.d.ts.map +0 -1
- package/dist/server/asset-headers.d.ts +0 -32
- package/dist/server/asset-headers.d.ts.map +0 -1
- package/dist/server/dev-source-map.d.ts +0 -22
- package/dist/server/dev-source-map.d.ts.map +0 -1
- package/src/client/types.ts +0 -21
- package/src/server/asset-headers.ts +0 -59
- package/src/server/dev-source-map.ts +0 -31
|
@@ -1,139 +1,179 @@
|
|
|
1
1
|
// Nitro local preview — standalone server codegen and process spawning.
|
|
2
2
|
//
|
|
3
|
-
// `
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// `buildOutput` writes `_preview-server.mjs` into the Nitro output directory,
|
|
4
|
+
// generated from the build's own artifacts; `timber preview` runs the
|
|
5
|
+
// adapter's preview(), which spawns it. See design/25-production-deployments.md
|
|
6
|
+
// §Preview.
|
|
6
7
|
|
|
7
8
|
import { execFile } from 'node:child_process';
|
|
8
|
-
import {
|
|
9
|
-
import { getPresetConfig, LOCALLY_PREVIEWABLE, type NitroPreset } from './nitro-presets.ts';
|
|
9
|
+
import { IMMUTABLE_CACHE, STATIC_CACHE } from './shared.ts';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @internal Exported for testing.
|
|
12
|
+
* Content-Type by file extension for the preview server. Static hosts decide
|
|
13
|
+
* this themselves; the table covers the file types a web build ships so the
|
|
14
|
+
* preview does not turn ordinary files into downloads. An extension missing
|
|
15
|
+
* here is served as `application/octet-stream`.
|
|
18
16
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Import the RSC handler (default export is the fetch-like handler).
|
|
47
|
-
const { default: handler, runWithEarlyHintsSender } = await import('${rscEntry}');
|
|
48
|
-
|
|
49
|
-
// Import compression helper for self-hosted response compression.
|
|
50
|
-
const { compressResponse } = await import('./_compress.mjs');
|
|
51
|
-
|
|
52
|
-
// Web→Node response bridge with backpressure (TIM-1154).
|
|
53
|
-
const { sendNodeResponse } = await import('./_send-response.mjs');
|
|
54
|
-
|
|
55
|
-
const MIME_TYPES = {
|
|
56
|
-
'.html': 'text/html',
|
|
57
|
-
'.js': 'application/javascript',
|
|
58
|
-
'.mjs': 'application/javascript',
|
|
59
|
-
'.css': 'text/css',
|
|
60
|
-
'.json': 'application/json',
|
|
17
|
+
const PREVIEW_MIME_TYPES: Readonly<Record<string, string>> = {
|
|
18
|
+
// Documents and code
|
|
19
|
+
'.html': 'text/html; charset=utf-8',
|
|
20
|
+
'.htm': 'text/html; charset=utf-8',
|
|
21
|
+
'.css': 'text/css; charset=utf-8',
|
|
22
|
+
'.js': 'text/javascript; charset=utf-8',
|
|
23
|
+
'.mjs': 'text/javascript; charset=utf-8',
|
|
24
|
+
'.cjs': 'text/javascript; charset=utf-8',
|
|
25
|
+
'.map': 'application/json; charset=utf-8',
|
|
26
|
+
'.json': 'application/json; charset=utf-8',
|
|
27
|
+
'.jsonld': 'application/ld+json',
|
|
28
|
+
'.webmanifest': 'application/manifest+json',
|
|
29
|
+
'.xml': 'application/xml',
|
|
30
|
+
'.rss': 'application/rss+xml',
|
|
31
|
+
'.atom': 'application/atom+xml',
|
|
32
|
+
'.txt': 'text/plain; charset=utf-8',
|
|
33
|
+
'.md': 'text/markdown; charset=utf-8',
|
|
34
|
+
'.csv': 'text/csv; charset=utf-8',
|
|
35
|
+
'.ics': 'text/calendar; charset=utf-8',
|
|
36
|
+
'.vtt': 'text/vtt; charset=utf-8',
|
|
37
|
+
'.pdf': 'application/pdf',
|
|
38
|
+
'.wasm': 'application/wasm',
|
|
39
|
+
'.zip': 'application/zip',
|
|
40
|
+
'.gz': 'application/gzip',
|
|
41
|
+
// Images
|
|
61
42
|
'.png': 'image/png',
|
|
43
|
+
'.apng': 'image/apng',
|
|
62
44
|
'.jpg': 'image/jpeg',
|
|
63
45
|
'.jpeg': 'image/jpeg',
|
|
64
46
|
'.gif': 'image/gif',
|
|
65
47
|
'.svg': 'image/svg+xml',
|
|
66
48
|
'.ico': 'image/x-icon',
|
|
49
|
+
'.webp': 'image/webp',
|
|
50
|
+
'.avif': 'image/avif',
|
|
51
|
+
'.bmp': 'image/bmp',
|
|
52
|
+
'.tif': 'image/tiff',
|
|
53
|
+
'.tiff': 'image/tiff',
|
|
54
|
+
// Fonts
|
|
67
55
|
'.woff': 'font/woff',
|
|
68
56
|
'.woff2': 'font/woff2',
|
|
69
57
|
'.ttf': 'font/ttf',
|
|
70
58
|
'.otf': 'font/otf',
|
|
71
|
-
|
|
72
|
-
'.
|
|
73
|
-
'.
|
|
59
|
+
// Audio and video
|
|
60
|
+
'.mp3': 'audio/mpeg',
|
|
61
|
+
'.wav': 'audio/wav',
|
|
62
|
+
'.ogg': 'audio/ogg',
|
|
63
|
+
'.oga': 'audio/ogg',
|
|
64
|
+
'.m4a': 'audio/mp4',
|
|
65
|
+
'.flac': 'audio/flac',
|
|
74
66
|
'.mp4': 'video/mp4',
|
|
75
|
-
'.
|
|
76
|
-
'.
|
|
77
|
-
'.
|
|
67
|
+
'.webm': 'video/webm',
|
|
68
|
+
'.ogv': 'video/ogg',
|
|
69
|
+
'.mov': 'video/quicktime',
|
|
78
70
|
};
|
|
79
71
|
|
|
80
|
-
|
|
72
|
+
/** What the generated preview server serves, as `buildOutput` knows it. */
|
|
73
|
+
export type PreviewScriptOptions = StaticPreviewScriptOptions | ServerPreviewScriptOptions;
|
|
81
74
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
75
|
+
interface PreviewScriptOptionsBase {
|
|
76
|
+
/**
|
|
77
|
+
* `BuildArtifacts.immutableDirs` — served with a one-year immutable
|
|
78
|
+
* `Cache-Control`, every other file with a revalidating one.
|
|
79
|
+
*/
|
|
80
|
+
immutableDirs: readonly string[];
|
|
81
|
+
/**
|
|
82
|
+
* The deployment base, normalized (`/` or `/repo/`). Requests arrive in
|
|
83
|
+
* deployed-URL space; files are laid out in route space, so the script
|
|
84
|
+
* strips it before looking anything up.
|
|
85
|
+
*/
|
|
86
|
+
base: string;
|
|
87
|
+
}
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
/** A static build: serve the pre-rendered site and nothing else. */
|
|
90
|
+
export interface StaticPreviewScriptOptions extends PreviewScriptOptionsBase {
|
|
91
|
+
output: 'static';
|
|
92
|
+
/** `StaticBuildArtifacts.contentTypes` — extensionless API route outputs. */
|
|
93
|
+
contentTypes: Readonly<Record<string, string>>;
|
|
94
|
+
}
|
|
97
95
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
96
|
+
/** A server build: serve `public/`, route everything else to the RSC handler. */
|
|
97
|
+
export interface ServerPreviewScriptOptions extends PreviewScriptOptionsBase {
|
|
98
|
+
output: 'server';
|
|
99
|
+
/** Value for `TIMBER_RUNTIME`, set before the handler evaluates. */
|
|
100
|
+
runtimeName: string;
|
|
101
|
+
/** Import specifier of the RSC handler, relative to the script. */
|
|
102
|
+
rscEntry: string;
|
|
103
|
+
/**
|
|
104
|
+
* Whether this build wrote `_timber-manifest-init.js` beside the script.
|
|
105
|
+
* Recorded from the build, never probed: the Nitro output directory is not
|
|
106
|
+
* cleaned between server builds, so a file on disk can be a stale one.
|
|
107
|
+
*/
|
|
108
|
+
hasManifestInit: boolean;
|
|
109
|
+
}
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Generate a standalone preview server script that uses Node's built-in
|
|
113
|
+
* HTTP server. This bypasses Nitro entirely — the Nitro entry.ts imports
|
|
114
|
+
* h3 which isn't available outside a Nitro build. For local preview we
|
|
115
|
+
* just need to serve static files and, in a server build, route requests
|
|
116
|
+
* to the RSC handler.
|
|
117
|
+
*
|
|
118
|
+
* Generated at build time rather than at preview time, so everything it
|
|
119
|
+
* serves comes from the build's artifacts instead of guesses about the
|
|
120
|
+
* directory it runs in.
|
|
121
|
+
*
|
|
122
|
+
* @internal Exported for testing.
|
|
123
|
+
*/
|
|
124
|
+
export function generatePreviewScript(options: PreviewScriptOptions): string {
|
|
125
|
+
const immutablePrefixes = options.immutableDirs.map((dir) => `/${dir}/`);
|
|
126
|
+
const contentTypes = options.output === 'static' ? options.contentTypes : {};
|
|
127
|
+
|
|
128
|
+
// A server build loads its handler (after the runtime and manifest are in
|
|
129
|
+
// place); a static build has no handler to load.
|
|
130
|
+
const handlerSetup =
|
|
131
|
+
options.output === 'server'
|
|
132
|
+
? `// Set runtime before importing the handler.
|
|
133
|
+
process.env.TIMBER_RUNTIME = ${JSON.stringify(options.runtimeName)};
|
|
134
|
+
${
|
|
135
|
+
options.hasManifestInit
|
|
136
|
+
? `
|
|
137
|
+
// Load the build manifest before the handler reads it.
|
|
138
|
+
await import('./_timber-manifest-init.js');
|
|
139
|
+
`
|
|
140
|
+
: ''
|
|
141
|
+
}
|
|
142
|
+
// Import the RSC handler (default export is the fetch-like handler).
|
|
143
|
+
const { default: handler, runWithEarlyHintsSender } = await import(${JSON.stringify(options.rscEntry)});
|
|
144
|
+
|
|
145
|
+
// Import compression helper for self-hosted response compression.
|
|
146
|
+
const { compressResponse } = await import('./_compress.mjs');
|
|
147
|
+
|
|
148
|
+
// Web→Node response bridge with backpressure (TIM-1154).
|
|
149
|
+
const { sendNodeResponse } = await import('./_send-response.mjs');
|
|
150
|
+
`
|
|
151
|
+
: '';
|
|
152
|
+
|
|
153
|
+
// What happens when no file matches: a static build answers with its own
|
|
154
|
+
// 404 page, a server build hands the request to the RSC handler.
|
|
155
|
+
const fallback =
|
|
156
|
+
options.output === 'static'
|
|
157
|
+
? ` if (badPath) {
|
|
158
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
159
|
+
res.end('Bad Request');
|
|
160
|
+
return;
|
|
135
161
|
}
|
|
162
|
+
const notFound = await findFile('/404.html');
|
|
163
|
+
if (notFound) {
|
|
164
|
+
await sendFile(req, res, notFound, 404, 'text/html', 'public, max-age=0, must-revalidate');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
168
|
+
res.end('Not Found');
|
|
169
|
+
`
|
|
170
|
+
: ` await handleDynamic(req, res, url);
|
|
171
|
+
`;
|
|
136
172
|
|
|
173
|
+
const dynamicHandler =
|
|
174
|
+
options.output === 'server'
|
|
175
|
+
? `
|
|
176
|
+
async function handleDynamic(req, res, url) {
|
|
137
177
|
// Convert Node request to Web Request.
|
|
138
178
|
const headers = new Headers();
|
|
139
179
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
@@ -187,7 +227,128 @@ const server = createServer(async (req, res) => {
|
|
|
187
227
|
}
|
|
188
228
|
res.end('Internal Server Error');
|
|
189
229
|
}
|
|
190
|
-
}
|
|
230
|
+
}
|
|
231
|
+
`
|
|
232
|
+
: '';
|
|
233
|
+
|
|
234
|
+
return `// Generated by @timber-js/app — standalone preview server.
|
|
235
|
+
// Do not edit — this file is regenerated on each build.
|
|
236
|
+
// Uses Node's built-in HTTP server to serve the build's files${
|
|
237
|
+
options.output === 'server' ? ' and route\n// dynamic requests through the RSC handler' : ''
|
|
238
|
+
}. No Nitro/h3 dependency.
|
|
239
|
+
|
|
240
|
+
import { createServer } from 'node:http';
|
|
241
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
242
|
+
import { join, extname, sep } from 'node:path';
|
|
243
|
+
import { fileURLToPath } from 'node:url';
|
|
244
|
+
import { canonicalize } from './_canonicalize.mjs';
|
|
245
|
+
|
|
246
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
247
|
+
|
|
248
|
+
${handlerSetup}
|
|
249
|
+
const MIME_TYPES = ${JSON.stringify(PREVIEW_MIME_TYPES, null, 2)};
|
|
250
|
+
|
|
251
|
+
// Recorded by the build: content-hashed directories, and the Content-Type of
|
|
252
|
+
// each extensionless API route output (a file name cannot say it). Both are
|
|
253
|
+
// decoded route-space paths, matched against the decoded request path.
|
|
254
|
+
const IMMUTABLE_PREFIXES = ${JSON.stringify(immutablePrefixes)};
|
|
255
|
+
const BASE = ${JSON.stringify(options.base)};
|
|
256
|
+
const CONTENT_TYPES = ${JSON.stringify(contentTypes)};
|
|
257
|
+
const SERVE_DIRECTORY_INDEX = ${options.output === 'static'};
|
|
258
|
+
|
|
259
|
+
const publicDir = join(__dirname, 'public');
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* The file under publicDir that a decoded URL path names, or null. A static
|
|
263
|
+
* build lays its pages out as <path>/index.html, so a directory serves its
|
|
264
|
+
* index there.
|
|
265
|
+
*/
|
|
266
|
+
async function findFile(pathname) {
|
|
267
|
+
const filePath = join(publicDir, pathname);
|
|
268
|
+
// Prevent path traversal (and a sibling like public-other/ passing a bare
|
|
269
|
+
// prefix check).
|
|
270
|
+
if (!filePath.startsWith(publicDir + sep)) return null;
|
|
271
|
+
try {
|
|
272
|
+
const fileStat = await stat(filePath);
|
|
273
|
+
if (fileStat.isFile()) return filePath;
|
|
274
|
+
if (SERVE_DIRECTORY_INDEX && fileStat.isDirectory()) {
|
|
275
|
+
const index = join(filePath, 'index.html');
|
|
276
|
+
if ((await stat(index)).isFile()) return index;
|
|
277
|
+
}
|
|
278
|
+
} catch {
|
|
279
|
+
// Not found.
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* The route-space path for a request path, or null when the request is
|
|
286
|
+
* outside the deployment base (it names no file of this build).
|
|
287
|
+
*/
|
|
288
|
+
function stripBase(pathname) {
|
|
289
|
+
if (BASE === '/') return pathname;
|
|
290
|
+
if (pathname === BASE.slice(0, -1)) return '/';
|
|
291
|
+
if (!pathname.startsWith(BASE)) return null;
|
|
292
|
+
return pathname.slice(BASE.length - 1);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async function sendFile(req, res, filePath, status, contentType, cacheControl) {
|
|
296
|
+
const body = await readFile(filePath);
|
|
297
|
+
res.writeHead(status, {
|
|
298
|
+
'Content-Type': contentType,
|
|
299
|
+
'Content-Length': body.length,
|
|
300
|
+
'Cache-Control': cacheControl,
|
|
301
|
+
});
|
|
302
|
+
res.end(req.method === 'HEAD' ? undefined : body);
|
|
303
|
+
}
|
|
304
|
+
${dynamicHandler}
|
|
305
|
+
// Port resolution (TIM-842):
|
|
306
|
+
// - Default to 3000
|
|
307
|
+
// - If PORT env var is set, honor it strictly (fail loudly on conflict)
|
|
308
|
+
// - Otherwise auto-bump from 3000 until a free port is found
|
|
309
|
+
// Mirrors the dev server behavior so timber dev/preview/production all
|
|
310
|
+
// behave the same way around port selection.
|
|
311
|
+
const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : null;
|
|
312
|
+
const portIsExplicit = envPort != null && Number.isFinite(envPort) && envPort > 0;
|
|
313
|
+
const startPort = portIsExplicit ? envPort : 3000;
|
|
314
|
+
const host = process.env.HOST || 'localhost';
|
|
315
|
+
|
|
316
|
+
// Set after listenWithBump() resolves so request handlers can build
|
|
317
|
+
// absolute URLs from the actual bound port (which may differ from
|
|
318
|
+
// startPort after an auto-bump).
|
|
319
|
+
let boundPort = startPort;
|
|
320
|
+
|
|
321
|
+
const server = createServer(async (req, res) => {
|
|
322
|
+
// Scheme from the socket's TLS state — a hardcoded http:// breaks CSRF
|
|
323
|
+
// origin comparison and absolute-URL construction when TLS is terminated
|
|
324
|
+
// at this server (TIM-1073; mirrors the dev-server fix in TIM-1067).
|
|
325
|
+
// X-Forwarded-Proto is intentionally not consulted here: on a direct
|
|
326
|
+
// connection it would be attacker-controlled. The CSRF layer honors it
|
|
327
|
+
// separately for reverse-proxy deployments.
|
|
328
|
+
const scheme = req.socket?.encrypted ? 'https' : 'http';
|
|
329
|
+
const url = new URL(req.url || '/', \`\${scheme}://\${host}:\${boundPort}\`);
|
|
330
|
+
|
|
331
|
+
// The runtime's own request-boundary canonicalizer (_canonicalize.mjs,
|
|
332
|
+
// compiled from server/canonicalize.ts): one decode, and the same 400s for
|
|
333
|
+
// encoded separators, null bytes, malformed encoding, and escaping the root
|
|
334
|
+
// (design/13-security.md). The base is stripped from its canonical result,
|
|
335
|
+
// so an encoded spelling of the base is the same path. What remains, in
|
|
336
|
+
// route space, is looked up in public/; null names no file.
|
|
337
|
+
const canonical = canonicalize(url.pathname, false);
|
|
338
|
+
const badPath = !canonical.ok;
|
|
339
|
+
const pathname = canonical.ok ? stripBase(canonical.pathname) : null;
|
|
340
|
+
const filePath = pathname === null ? null : await findFile(pathname);
|
|
341
|
+
if (filePath) {
|
|
342
|
+
const contentType =
|
|
343
|
+
CONTENT_TYPES[pathname] || MIME_TYPES[extname(filePath).toLowerCase()] || 'application/octet-stream';
|
|
344
|
+
// Hashed assets get immutable cache, others get short cache.
|
|
345
|
+
const isImmutable = IMMUTABLE_PREFIXES.some((prefix) => pathname.startsWith(prefix));
|
|
346
|
+
const cacheControl = isImmutable ? ${JSON.stringify(IMMUTABLE_CACHE)} : ${JSON.stringify(STATIC_CACHE)};
|
|
347
|
+
await sendFile(req, res, filePath, 200, contentType, cacheControl);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
${fallback}});
|
|
191
352
|
|
|
192
353
|
function listenWithBump(port, attempt = 0) {
|
|
193
354
|
return new Promise((resolveListen, rejectListen) => {
|
|
@@ -235,31 +396,6 @@ try {
|
|
|
235
396
|
`;
|
|
236
397
|
}
|
|
237
398
|
|
|
238
|
-
/** Command descriptor for Nitro preview — testable without spawning. */
|
|
239
|
-
export interface NitroPreviewCommand {
|
|
240
|
-
command: string;
|
|
241
|
-
args: string[];
|
|
242
|
-
cwd: string;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/** @internal Exported for testing. */
|
|
246
|
-
export function generateNitroPreviewCommand(
|
|
247
|
-
buildDir: string,
|
|
248
|
-
preset: NitroPreset
|
|
249
|
-
): NitroPreviewCommand | null {
|
|
250
|
-
if (!LOCALLY_PREVIEWABLE.has(preset)) return null;
|
|
251
|
-
|
|
252
|
-
const nitroDir = join(buildDir, 'nitro');
|
|
253
|
-
const entryPath = join(nitroDir, 'entry.ts');
|
|
254
|
-
|
|
255
|
-
const command = preset === 'bun' ? 'bun' : 'node';
|
|
256
|
-
return {
|
|
257
|
-
command,
|
|
258
|
-
args: [entryPath],
|
|
259
|
-
cwd: nitroDir,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
399
|
/** Spawn a Nitro preview process and pipe stdio. */
|
|
264
400
|
export function spawnNitroPreview(command: string, args: string[], cwd: string): Promise<void> {
|
|
265
401
|
return new Promise<void>((resolve, reject) => {
|