@timber-js/app 0.2.0-alpha.207 → 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-BndF-3Td.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-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
- 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 +20 -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 +95 -108
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +20 -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 +3 -8
- 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/segment-cache.d.ts +44 -4
- package/dist/client/segment-cache.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 +632 -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/react-resolve.d.ts +49 -0
- package/dist/plugins/react-resolve.d.ts.map +1 -0
- 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 +7 -3
- 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 +35 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +41 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +96 -132
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +62 -21
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/segment-cache.ts +110 -11
- 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 +26 -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/react-resolve.ts +149 -0
- 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-BndF-3Td.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-DwQBrLBz.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
package/dist/adapters/nitro.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { t as RSC_CONTENT_TYPE } from "../_chunks/rsc-media-type-DDc7duTD.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as STATIC_CACHE, i as IMMUTABLE_CACHE, n as runSharedBuildSteps, o as adapterBase, r as writeHeadersFile, t as buildStaticDirectoryOutput } from "../_chunks/build-output-helper-RV_BRcF1.js";
|
|
3
3
|
import { transformWithOxc } from "vite";
|
|
4
|
-
import { basename, dirname, join, relative } from "node:path";
|
|
4
|
+
import { basename, dirname, join, relative, sep } from "node:path";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
5
6
|
import { cp, glob, readFile, writeFile } from "node:fs/promises";
|
|
6
7
|
import { execFile } from "node:child_process";
|
|
7
8
|
//#region src/server/compress.ts?raw
|
|
@@ -55,11 +56,21 @@ var MODULE_SPECIFIERS = [
|
|
|
55
56
|
function inlineCompressImports(code) {
|
|
56
57
|
let out = code;
|
|
57
58
|
for (const { pattern, replacement } of INLINED_IMPORTS) out = out.replace(pattern, replacement);
|
|
58
|
-
|
|
59
|
-
if (surviving) throw new Error(`[timber] server/compress.ts is emitted as a standalone _compress.mjs (type-stripped, not bundled), so it cannot import anything at runtime. Found: ${surviving[0].trim()}\n Either inline the value in adapters/compress-module.ts (see INLINED_IMPORTS) or keep the dependency out of server/compress.ts.`);
|
|
59
|
+
assertStandalone(out, "server/compress.ts", "_compress.mjs");
|
|
60
60
|
return out;
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
|
+
* Throw if type-stripped server source still imports anything but a Node
|
|
64
|
+
* builtin. Such a module is emitted alone into the build output, where no
|
|
65
|
+
* specifier has anything to resolve to.
|
|
66
|
+
*
|
|
67
|
+
* @internal Shared by the standalone-module generators.
|
|
68
|
+
*/
|
|
69
|
+
function assertStandalone(code, source, emitted) {
|
|
70
|
+
const surviving = MODULE_SPECIFIERS.map((pattern) => pattern.exec(code)).find(Boolean);
|
|
71
|
+
if (surviving) throw new Error(`[timber] ${source} is emitted as a standalone ${emitted} (type-stripped, not bundled), so it cannot import anything at runtime. Found: ${surviving[0].trim()}\n Either inline the value in the generator in adapters/ or keep the dependency out of ${source}.`);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
63
74
|
* Compile server/compress.ts into a standalone ESM module.
|
|
64
75
|
*
|
|
65
76
|
* Uses Vite's OXC transform to strip TypeScript types from the
|
|
@@ -72,12 +83,27 @@ async function generateCompressModule() {
|
|
|
72
83
|
return "// Generated by @timber-js/app — compiled from server/compress.ts.\n// Do not edit — this file is regenerated on each build.\n" + inlineCompressImports((await transformWithOxc(compress_default, "compress.ts", { lang: "ts" })).code);
|
|
73
84
|
}
|
|
74
85
|
//#endregion
|
|
86
|
+
//#region src/server/canonicalize.ts?raw
|
|
87
|
+
var canonicalize_default = "/**\n * URL canonicalization — runs once at the request boundary.\n *\n * Every layer (proxy.ts, middleware.ts, access.ts, components) sees the same\n * canonical path. No re-decoding occurs at any later stage.\n *\n * See design/07-routing.md §\"URL Canonicalization & Security\"\n */\n\n/** Result of canonicalization — either a clean path or a rejection. */\nexport type CanonicalizeResult = { ok: true; pathname: string } | { ok: false; status: 400 };\n\n/**\n * Encoded separators that produce a 400 rejection.\n * %2f (/) and %5c (\\) cause path-confusion attacks.\n *\n * Shared between the runtime canonicalizer and the build-time route scanner\n * to ensure both enforce identical security rules. See design/13-security.md.\n */\nexport const ENCODED_SEPARATOR_RE = /%2f|%5c/i;\n\n/** Null byte — rejected. Shared with the route scanner. */\nexport const NULL_BYTE_RE = /%00/i;\n\n/**\n * Canonicalize a URL pathname.\n *\n * 1. Reject encoded separators (%2f, %5c) and null bytes (%00)\n * 2. Single percent-decode\n * 3. Collapse // → /\n * 4. Resolve .. segments (reject if escaping root)\n * 5. Strip trailing slash (except root \"/\")\n *\n * @param rawPathname - The raw pathname from the request URL (percent-encoded)\n * @param stripTrailingSlash - Whether to strip trailing slashes. Default: true.\n */\nexport function canonicalize(rawPathname: string, stripTrailingSlash = true): CanonicalizeResult {\n // Step 1: Reject dangerous encoded sequences BEFORE decoding.\n // This must happen on the raw input so %252f doesn't bypass after a single decode.\n if (ENCODED_SEPARATOR_RE.test(rawPathname)) {\n return { ok: false, status: 400 };\n }\n if (NULL_BYTE_RE.test(rawPathname)) {\n return { ok: false, status: 400 };\n }\n\n // Step 2: Single percent-decode.\n // Double-encoded input (%2561 → %61) stays as %61 — not decoded again.\n let decoded: string;\n try {\n decoded = decodeURIComponent(rawPathname);\n } catch {\n // Malformed percent-encoding → 400\n return { ok: false, status: 400 };\n }\n\n // Reject null bytes that appeared after decoding (from valid %00-like sequences\n // that weren't caught above — belt and suspenders).\n if (decoded.includes('\\0')) {\n return { ok: false, status: 400 };\n }\n\n // Backslash is NOT a path separator — keep as literal character.\n // But reject if it would create // after normalization (e.g., /\\evil.com).\n // We do NOT convert \\ to / — it stays as a literal.\n\n // Step 3: Collapse consecutive slashes.\n let pathname = decoded.replace(/\\/\\/+/g, '/');\n\n // Step 4: Resolve .. and . segments.\n const segments = pathname.split('/');\n const resolved: string[] = [];\n for (const seg of segments) {\n if (seg === '..') {\n if (resolved.length <= 1) {\n // Trying to escape root — 400\n return { ok: false, status: 400 };\n }\n resolved.pop();\n } else if (seg !== '.') {\n resolved.push(seg);\n }\n }\n\n pathname = resolved.join('/') || '/';\n\n // Step 5: Strip trailing slash (except root \"/\").\n if (stripTrailingSlash && pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1);\n }\n\n return { ok: true, pathname };\n}\n";
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/adapters/canonicalize-module.ts
|
|
90
|
+
/**
|
|
91
|
+
* Compile server/canonicalize.ts into a standalone ESM module exporting
|
|
92
|
+
* `canonicalize`.
|
|
93
|
+
*
|
|
94
|
+
* @internal Exported for testing.
|
|
95
|
+
*/
|
|
96
|
+
async function generateCanonicalizeModule() {
|
|
97
|
+
const result = await transformWithOxc(canonicalize_default, "canonicalize.ts", { lang: "ts" });
|
|
98
|
+
assertStandalone(result.code, "server/canonicalize.ts", "_canonicalize.mjs");
|
|
99
|
+
return "// Generated by @timber-js/app — compiled from server/canonicalize.ts.\n// Do not edit — this file is regenerated on each build.\n" + result.code;
|
|
100
|
+
}
|
|
101
|
+
//#endregion
|
|
75
102
|
//#region src/adapters/nitro-presets.ts
|
|
76
103
|
var PRESET_CONFIGS = {
|
|
77
104
|
"vercel": {
|
|
78
105
|
nitroPreset: "vercel",
|
|
79
106
|
outputDir: ".vercel/output",
|
|
80
|
-
serverBundleDir: "functions/__server.func",
|
|
81
107
|
supportsWaitUntil: true,
|
|
82
108
|
supportsEarlyHints: false,
|
|
83
109
|
runtimeName: "vercel",
|
|
@@ -86,7 +112,6 @@ var PRESET_CONFIGS = {
|
|
|
86
112
|
"vercel-edge": {
|
|
87
113
|
nitroPreset: "vercel-edge",
|
|
88
114
|
outputDir: ".vercel/output",
|
|
89
|
-
serverBundleDir: "functions/__server.func",
|
|
90
115
|
supportsWaitUntil: true,
|
|
91
116
|
supportsEarlyHints: false,
|
|
92
117
|
runtimeName: "vercel-edge"
|
|
@@ -94,7 +119,6 @@ var PRESET_CONFIGS = {
|
|
|
94
119
|
"netlify": {
|
|
95
120
|
nitroPreset: "netlify",
|
|
96
121
|
outputDir: ".netlify/functions-internal",
|
|
97
|
-
serverBundleDir: "server",
|
|
98
122
|
supportsWaitUntil: false,
|
|
99
123
|
supportsEarlyHints: false,
|
|
100
124
|
runtimeName: "netlify"
|
|
@@ -102,7 +126,6 @@ var PRESET_CONFIGS = {
|
|
|
102
126
|
"netlify-edge": {
|
|
103
127
|
nitroPreset: "netlify-edge",
|
|
104
128
|
outputDir: ".netlify/edge-functions",
|
|
105
|
-
serverBundleDir: "server",
|
|
106
129
|
supportsWaitUntil: true,
|
|
107
130
|
supportsEarlyHints: false,
|
|
108
131
|
runtimeName: "netlify-edge"
|
|
@@ -110,7 +133,6 @@ var PRESET_CONFIGS = {
|
|
|
110
133
|
"aws-lambda": {
|
|
111
134
|
nitroPreset: "aws-lambda",
|
|
112
135
|
outputDir: ".output",
|
|
113
|
-
serverBundleDir: "server",
|
|
114
136
|
supportsWaitUntil: false,
|
|
115
137
|
supportsEarlyHints: false,
|
|
116
138
|
runtimeName: "aws-lambda"
|
|
@@ -118,7 +140,6 @@ var PRESET_CONFIGS = {
|
|
|
118
140
|
"deno-deploy": {
|
|
119
141
|
nitroPreset: "deno-deploy",
|
|
120
142
|
outputDir: ".output",
|
|
121
|
-
serverBundleDir: "server",
|
|
122
143
|
supportsWaitUntil: true,
|
|
123
144
|
supportsEarlyHints: false,
|
|
124
145
|
runtimeName: "deno-deploy"
|
|
@@ -126,7 +147,6 @@ var PRESET_CONFIGS = {
|
|
|
126
147
|
"azure-functions": {
|
|
127
148
|
nitroPreset: "azure-functions",
|
|
128
149
|
outputDir: ".output",
|
|
129
|
-
serverBundleDir: "server",
|
|
130
150
|
supportsWaitUntil: false,
|
|
131
151
|
supportsEarlyHints: false,
|
|
132
152
|
runtimeName: "azure-functions"
|
|
@@ -134,7 +154,6 @@ var PRESET_CONFIGS = {
|
|
|
134
154
|
"node-server": {
|
|
135
155
|
nitroPreset: "node-server",
|
|
136
156
|
outputDir: ".output",
|
|
137
|
-
serverBundleDir: "server",
|
|
138
157
|
supportsWaitUntil: true,
|
|
139
158
|
supportsEarlyHints: false,
|
|
140
159
|
runtimeName: "node-server"
|
|
@@ -142,7 +161,6 @@ var PRESET_CONFIGS = {
|
|
|
142
161
|
"bun": {
|
|
143
162
|
nitroPreset: "bun",
|
|
144
163
|
outputDir: ".output",
|
|
145
|
-
serverBundleDir: "server",
|
|
146
164
|
supportsWaitUntil: true,
|
|
147
165
|
supportsEarlyHints: false,
|
|
148
166
|
runtimeName: "bun"
|
|
@@ -150,139 +168,111 @@ var PRESET_CONFIGS = {
|
|
|
150
168
|
};
|
|
151
169
|
/** Presets that produce a locally-runnable server entry. */
|
|
152
170
|
var LOCALLY_PREVIEWABLE = /* @__PURE__ */ new Set(["node-server", "bun"]);
|
|
153
|
-
/**
|
|
154
|
-
* Get the preset configuration for a given preset name.
|
|
155
|
-
* @internal Exported for testing.
|
|
156
|
-
*/
|
|
157
|
-
function getPresetConfig(preset) {
|
|
158
|
-
return PRESET_CONFIGS[preset];
|
|
159
|
-
}
|
|
160
171
|
//#endregion
|
|
161
172
|
//#region src/adapters/nitro-preview.ts
|
|
162
173
|
/**
|
|
174
|
+
* Content-Type by file extension for the preview server. Static hosts decide
|
|
175
|
+
* this themselves; the table covers the file types a web build ships so the
|
|
176
|
+
* preview does not turn ordinary files into downloads. An extension missing
|
|
177
|
+
* here is served as `application/octet-stream`.
|
|
178
|
+
*/
|
|
179
|
+
var PREVIEW_MIME_TYPES = {
|
|
180
|
+
".html": "text/html; charset=utf-8",
|
|
181
|
+
".htm": "text/html; charset=utf-8",
|
|
182
|
+
".css": "text/css; charset=utf-8",
|
|
183
|
+
".js": "text/javascript; charset=utf-8",
|
|
184
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
185
|
+
".cjs": "text/javascript; charset=utf-8",
|
|
186
|
+
".map": "application/json; charset=utf-8",
|
|
187
|
+
".json": "application/json; charset=utf-8",
|
|
188
|
+
".jsonld": "application/ld+json",
|
|
189
|
+
".webmanifest": "application/manifest+json",
|
|
190
|
+
".xml": "application/xml",
|
|
191
|
+
".rss": "application/rss+xml",
|
|
192
|
+
".atom": "application/atom+xml",
|
|
193
|
+
".txt": "text/plain; charset=utf-8",
|
|
194
|
+
".md": "text/markdown; charset=utf-8",
|
|
195
|
+
".csv": "text/csv; charset=utf-8",
|
|
196
|
+
".ics": "text/calendar; charset=utf-8",
|
|
197
|
+
".vtt": "text/vtt; charset=utf-8",
|
|
198
|
+
".pdf": "application/pdf",
|
|
199
|
+
".wasm": "application/wasm",
|
|
200
|
+
".zip": "application/zip",
|
|
201
|
+
".gz": "application/gzip",
|
|
202
|
+
".png": "image/png",
|
|
203
|
+
".apng": "image/apng",
|
|
204
|
+
".jpg": "image/jpeg",
|
|
205
|
+
".jpeg": "image/jpeg",
|
|
206
|
+
".gif": "image/gif",
|
|
207
|
+
".svg": "image/svg+xml",
|
|
208
|
+
".ico": "image/x-icon",
|
|
209
|
+
".webp": "image/webp",
|
|
210
|
+
".avif": "image/avif",
|
|
211
|
+
".bmp": "image/bmp",
|
|
212
|
+
".tif": "image/tiff",
|
|
213
|
+
".tiff": "image/tiff",
|
|
214
|
+
".woff": "font/woff",
|
|
215
|
+
".woff2": "font/woff2",
|
|
216
|
+
".ttf": "font/ttf",
|
|
217
|
+
".otf": "font/otf",
|
|
218
|
+
".mp3": "audio/mpeg",
|
|
219
|
+
".wav": "audio/wav",
|
|
220
|
+
".ogg": "audio/ogg",
|
|
221
|
+
".oga": "audio/ogg",
|
|
222
|
+
".m4a": "audio/mp4",
|
|
223
|
+
".flac": "audio/flac",
|
|
224
|
+
".mp4": "video/mp4",
|
|
225
|
+
".webm": "video/webm",
|
|
226
|
+
".ogv": "video/ogg",
|
|
227
|
+
".mov": "video/quicktime"
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
163
230
|
* Generate a standalone preview server script that uses Node's built-in
|
|
164
231
|
* HTTP server. This bypasses Nitro entirely — the Nitro entry.ts imports
|
|
165
232
|
* h3 which isn't available outside a Nitro build. For local preview we
|
|
166
|
-
* just need to serve static files and
|
|
233
|
+
* just need to serve static files and, in a server build, route requests
|
|
234
|
+
* to the RSC handler.
|
|
235
|
+
*
|
|
236
|
+
* Generated at build time rather than at preview time, so everything it
|
|
237
|
+
* serves comes from the build's artifacts instead of guesses about the
|
|
238
|
+
* directory it runs in.
|
|
167
239
|
*
|
|
168
240
|
* @internal Exported for testing.
|
|
169
241
|
*/
|
|
170
|
-
function generatePreviewScript(
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
import { createServer } from 'node:http';
|
|
180
|
-
import { readFile, stat } from 'node:fs/promises';
|
|
181
|
-
import { join, extname } from 'node:path';
|
|
182
|
-
import { fileURLToPath } from 'node:url';
|
|
183
|
-
import { existsSync } from 'node:fs';
|
|
184
|
-
|
|
185
|
-
// Set runtime before importing the handler.
|
|
186
|
-
process.env.TIMBER_RUNTIME = '${getPresetConfig(preset).runtimeName}';
|
|
187
|
-
|
|
188
|
-
// Load the build manifest if it exists.
|
|
189
|
-
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
190
|
-
const manifestPath = join(__dirname, '${manifestInitPath}');
|
|
191
|
-
if (existsSync(manifestPath)) {
|
|
192
|
-
await import('${manifestInitPath}');
|
|
193
|
-
}
|
|
194
|
-
|
|
242
|
+
function generatePreviewScript(options) {
|
|
243
|
+
const immutablePrefixes = options.immutableDirs.map((dir) => `/${dir}/`);
|
|
244
|
+
const contentTypes = options.output === "static" ? options.contentTypes : {};
|
|
245
|
+
const handlerSetup = options.output === "server" ? `// Set runtime before importing the handler.
|
|
246
|
+
process.env.TIMBER_RUNTIME = ${JSON.stringify(options.runtimeName)};
|
|
247
|
+
${options.hasManifestInit ? `
|
|
248
|
+
// Load the build manifest before the handler reads it.
|
|
249
|
+
await import('./_timber-manifest-init.js');
|
|
250
|
+
` : ""}
|
|
195
251
|
// Import the RSC handler (default export is the fetch-like handler).
|
|
196
|
-
const { default: handler, runWithEarlyHintsSender } = await import(
|
|
252
|
+
const { default: handler, runWithEarlyHintsSender } = await import(${JSON.stringify(options.rscEntry)});
|
|
197
253
|
|
|
198
254
|
// Import compression helper for self-hosted response compression.
|
|
199
255
|
const { compressResponse } = await import('./_compress.mjs');
|
|
200
256
|
|
|
201
257
|
// Web→Node response bridge with backpressure (TIM-1154).
|
|
202
258
|
const { sendNodeResponse } = await import('./_send-response.mjs');
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
'.css': 'text/css',
|
|
209
|
-
'.json': 'application/json',
|
|
210
|
-
'.png': 'image/png',
|
|
211
|
-
'.jpg': 'image/jpeg',
|
|
212
|
-
'.jpeg': 'image/jpeg',
|
|
213
|
-
'.gif': 'image/gif',
|
|
214
|
-
'.svg': 'image/svg+xml',
|
|
215
|
-
'.ico': 'image/x-icon',
|
|
216
|
-
'.woff': 'font/woff',
|
|
217
|
-
'.woff2': 'font/woff2',
|
|
218
|
-
'.ttf': 'font/ttf',
|
|
219
|
-
'.otf': 'font/otf',
|
|
220
|
-
'.webp': 'image/webp',
|
|
221
|
-
'.avif': 'image/avif',
|
|
222
|
-
'.webm': 'video/webm',
|
|
223
|
-
'.mp4': 'video/mp4',
|
|
224
|
-
'.txt': 'text/plain',
|
|
225
|
-
'.xml': 'application/xml',
|
|
226
|
-
'.wasm': 'application/wasm',
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
const publicDir = join(__dirname, '${publicDir}');
|
|
230
|
-
|
|
231
|
-
// Port resolution (TIM-842):
|
|
232
|
-
// - Default to 3000
|
|
233
|
-
// - If PORT env var is set, honor it strictly (fail loudly on conflict)
|
|
234
|
-
// - Otherwise auto-bump from 3000 until a free port is found
|
|
235
|
-
// Mirrors the dev server behavior so timber dev/preview/production all
|
|
236
|
-
// behave the same way around port selection.
|
|
237
|
-
const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : null;
|
|
238
|
-
const portIsExplicit = envPort != null && Number.isFinite(envPort) && envPort > 0;
|
|
239
|
-
const startPort = portIsExplicit ? envPort : 3000;
|
|
240
|
-
const host = process.env.HOST || 'localhost';
|
|
241
|
-
|
|
242
|
-
// Set after listenWithBump() resolves so request handlers can build
|
|
243
|
-
// absolute URLs from the actual bound port (which may differ from
|
|
244
|
-
// startPort after an auto-bump).
|
|
245
|
-
let boundPort = startPort;
|
|
246
|
-
|
|
247
|
-
const server = createServer(async (req, res) => {
|
|
248
|
-
// Scheme from the socket's TLS state — a hardcoded http:// breaks CSRF
|
|
249
|
-
// origin comparison and absolute-URL construction when TLS is terminated
|
|
250
|
-
// at this server (TIM-1073; mirrors the dev-server fix in TIM-1067).
|
|
251
|
-
// X-Forwarded-Proto is intentionally not consulted here: on a direct
|
|
252
|
-
// connection it would be attacker-controlled. The CSRF layer honors it
|
|
253
|
-
// separately for reverse-proxy deployments.
|
|
254
|
-
const scheme = req.socket?.encrypted ? 'https' : 'http';
|
|
255
|
-
const url = new URL(req.url || '/', \`\${scheme}://\${host}:\${boundPort}\`);
|
|
256
|
-
|
|
257
|
-
// Try serving static files from the public directory first.
|
|
258
|
-
const filePath = join(publicDir, url.pathname);
|
|
259
|
-
// Prevent path traversal.
|
|
260
|
-
if (filePath.startsWith(publicDir)) {
|
|
261
|
-
try {
|
|
262
|
-
const fileStat = await stat(filePath);
|
|
263
|
-
if (fileStat.isFile()) {
|
|
264
|
-
const ext = extname(filePath);
|
|
265
|
-
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
266
|
-
const body = await readFile(filePath);
|
|
267
|
-
// Hashed assets get immutable cache, others get short cache.
|
|
268
|
-
const isImmutable =
|
|
269
|
-
url.pathname.startsWith('/assets/') || url.pathname.startsWith('/_timber/fonts/');
|
|
270
|
-
const cacheControl = isImmutable
|
|
271
|
-
? 'public, max-age=31536000, immutable'
|
|
272
|
-
: 'public, max-age=3600, must-revalidate';
|
|
273
|
-
res.writeHead(200, {
|
|
274
|
-
'Content-Type': contentType,
|
|
275
|
-
'Content-Length': body.length,
|
|
276
|
-
'Cache-Control': cacheControl,
|
|
277
|
-
});
|
|
278
|
-
res.end(body);
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
} catch {
|
|
282
|
-
// File not found — fall through to the RSC handler.
|
|
283
|
-
}
|
|
259
|
+
` : "";
|
|
260
|
+
const fallback = options.output === "static" ? ` if (badPath) {
|
|
261
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
262
|
+
res.end('Bad Request');
|
|
263
|
+
return;
|
|
284
264
|
}
|
|
285
|
-
|
|
265
|
+
const notFound = await findFile('/404.html');
|
|
266
|
+
if (notFound) {
|
|
267
|
+
await sendFile(req, res, notFound, 404, 'text/html', 'public, max-age=0, must-revalidate');
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
271
|
+
res.end('Not Found');
|
|
272
|
+
` : ` await handleDynamic(req, res, url);
|
|
273
|
+
`;
|
|
274
|
+
const dynamicHandler = options.output === "server" ? `
|
|
275
|
+
async function handleDynamic(req, res, url) {
|
|
286
276
|
// Convert Node request to Web Request.
|
|
287
277
|
const headers = new Headers();
|
|
288
278
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
@@ -336,7 +326,124 @@ const server = createServer(async (req, res) => {
|
|
|
336
326
|
}
|
|
337
327
|
res.end('Internal Server Error');
|
|
338
328
|
}
|
|
339
|
-
}
|
|
329
|
+
}
|
|
330
|
+
` : "";
|
|
331
|
+
return `// Generated by @timber-js/app — standalone preview server.
|
|
332
|
+
// Do not edit — this file is regenerated on each build.
|
|
333
|
+
// Uses Node's built-in HTTP server to serve the build's files${options.output === "server" ? " and route\n// dynamic requests through the RSC handler" : ""}. No Nitro/h3 dependency.
|
|
334
|
+
|
|
335
|
+
import { createServer } from 'node:http';
|
|
336
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
337
|
+
import { join, extname, sep } from 'node:path';
|
|
338
|
+
import { fileURLToPath } from 'node:url';
|
|
339
|
+
import { canonicalize } from './_canonicalize.mjs';
|
|
340
|
+
|
|
341
|
+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
|
342
|
+
|
|
343
|
+
${handlerSetup}
|
|
344
|
+
const MIME_TYPES = ${JSON.stringify(PREVIEW_MIME_TYPES, null, 2)};
|
|
345
|
+
|
|
346
|
+
// Recorded by the build: content-hashed directories, and the Content-Type of
|
|
347
|
+
// each extensionless API route output (a file name cannot say it). Both are
|
|
348
|
+
// decoded route-space paths, matched against the decoded request path.
|
|
349
|
+
const IMMUTABLE_PREFIXES = ${JSON.stringify(immutablePrefixes)};
|
|
350
|
+
const BASE = ${JSON.stringify(options.base)};
|
|
351
|
+
const CONTENT_TYPES = ${JSON.stringify(contentTypes)};
|
|
352
|
+
const SERVE_DIRECTORY_INDEX = ${options.output === "static"};
|
|
353
|
+
|
|
354
|
+
const publicDir = join(__dirname, 'public');
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* The file under publicDir that a decoded URL path names, or null. A static
|
|
358
|
+
* build lays its pages out as <path>/index.html, so a directory serves its
|
|
359
|
+
* index there.
|
|
360
|
+
*/
|
|
361
|
+
async function findFile(pathname) {
|
|
362
|
+
const filePath = join(publicDir, pathname);
|
|
363
|
+
// Prevent path traversal (and a sibling like public-other/ passing a bare
|
|
364
|
+
// prefix check).
|
|
365
|
+
if (!filePath.startsWith(publicDir + sep)) return null;
|
|
366
|
+
try {
|
|
367
|
+
const fileStat = await stat(filePath);
|
|
368
|
+
if (fileStat.isFile()) return filePath;
|
|
369
|
+
if (SERVE_DIRECTORY_INDEX && fileStat.isDirectory()) {
|
|
370
|
+
const index = join(filePath, 'index.html');
|
|
371
|
+
if ((await stat(index)).isFile()) return index;
|
|
372
|
+
}
|
|
373
|
+
} catch {
|
|
374
|
+
// Not found.
|
|
375
|
+
}
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* The route-space path for a request path, or null when the request is
|
|
381
|
+
* outside the deployment base (it names no file of this build).
|
|
382
|
+
*/
|
|
383
|
+
function stripBase(pathname) {
|
|
384
|
+
if (BASE === '/') return pathname;
|
|
385
|
+
if (pathname === BASE.slice(0, -1)) return '/';
|
|
386
|
+
if (!pathname.startsWith(BASE)) return null;
|
|
387
|
+
return pathname.slice(BASE.length - 1);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
async function sendFile(req, res, filePath, status, contentType, cacheControl) {
|
|
391
|
+
const body = await readFile(filePath);
|
|
392
|
+
res.writeHead(status, {
|
|
393
|
+
'Content-Type': contentType,
|
|
394
|
+
'Content-Length': body.length,
|
|
395
|
+
'Cache-Control': cacheControl,
|
|
396
|
+
});
|
|
397
|
+
res.end(req.method === 'HEAD' ? undefined : body);
|
|
398
|
+
}
|
|
399
|
+
${dynamicHandler}
|
|
400
|
+
// Port resolution (TIM-842):
|
|
401
|
+
// - Default to 3000
|
|
402
|
+
// - If PORT env var is set, honor it strictly (fail loudly on conflict)
|
|
403
|
+
// - Otherwise auto-bump from 3000 until a free port is found
|
|
404
|
+
// Mirrors the dev server behavior so timber dev/preview/production all
|
|
405
|
+
// behave the same way around port selection.
|
|
406
|
+
const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : null;
|
|
407
|
+
const portIsExplicit = envPort != null && Number.isFinite(envPort) && envPort > 0;
|
|
408
|
+
const startPort = portIsExplicit ? envPort : 3000;
|
|
409
|
+
const host = process.env.HOST || 'localhost';
|
|
410
|
+
|
|
411
|
+
// Set after listenWithBump() resolves so request handlers can build
|
|
412
|
+
// absolute URLs from the actual bound port (which may differ from
|
|
413
|
+
// startPort after an auto-bump).
|
|
414
|
+
let boundPort = startPort;
|
|
415
|
+
|
|
416
|
+
const server = createServer(async (req, res) => {
|
|
417
|
+
// Scheme from the socket's TLS state — a hardcoded http:// breaks CSRF
|
|
418
|
+
// origin comparison and absolute-URL construction when TLS is terminated
|
|
419
|
+
// at this server (TIM-1073; mirrors the dev-server fix in TIM-1067).
|
|
420
|
+
// X-Forwarded-Proto is intentionally not consulted here: on a direct
|
|
421
|
+
// connection it would be attacker-controlled. The CSRF layer honors it
|
|
422
|
+
// separately for reverse-proxy deployments.
|
|
423
|
+
const scheme = req.socket?.encrypted ? 'https' : 'http';
|
|
424
|
+
const url = new URL(req.url || '/', \`\${scheme}://\${host}:\${boundPort}\`);
|
|
425
|
+
|
|
426
|
+
// The runtime's own request-boundary canonicalizer (_canonicalize.mjs,
|
|
427
|
+
// compiled from server/canonicalize.ts): one decode, and the same 400s for
|
|
428
|
+
// encoded separators, null bytes, malformed encoding, and escaping the root
|
|
429
|
+
// (design/13-security.md). The base is stripped from its canonical result,
|
|
430
|
+
// so an encoded spelling of the base is the same path. What remains, in
|
|
431
|
+
// route space, is looked up in public/; null names no file.
|
|
432
|
+
const canonical = canonicalize(url.pathname, false);
|
|
433
|
+
const badPath = !canonical.ok;
|
|
434
|
+
const pathname = canonical.ok ? stripBase(canonical.pathname) : null;
|
|
435
|
+
const filePath = pathname === null ? null : await findFile(pathname);
|
|
436
|
+
if (filePath) {
|
|
437
|
+
const contentType =
|
|
438
|
+
CONTENT_TYPES[pathname] || MIME_TYPES[extname(filePath).toLowerCase()] || 'application/octet-stream';
|
|
439
|
+
// Hashed assets get immutable cache, others get short cache.
|
|
440
|
+
const isImmutable = IMMUTABLE_PREFIXES.some((prefix) => pathname.startsWith(prefix));
|
|
441
|
+
const cacheControl = isImmutable ? ${JSON.stringify(IMMUTABLE_CACHE)} : ${JSON.stringify(STATIC_CACHE)};
|
|
442
|
+
await sendFile(req, res, filePath, 200, contentType, cacheControl);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
${fallback}});
|
|
340
447
|
|
|
341
448
|
function listenWithBump(port, attempt = 0) {
|
|
342
449
|
return new Promise((resolveListen, rejectListen) => {
|
|
@@ -483,12 +590,19 @@ function nitro(options = {}) {
|
|
|
483
590
|
const compress = options.compress ?? true;
|
|
484
591
|
return {
|
|
485
592
|
name: `nitro-${preset}`,
|
|
486
|
-
async buildOutput(config,
|
|
487
|
-
const outDir = join(
|
|
488
|
-
if (
|
|
489
|
-
await buildStaticDirectoryOutput(config,
|
|
593
|
+
async buildOutput(config, artifacts) {
|
|
594
|
+
const outDir = join(artifacts.outputDir, "nitro");
|
|
595
|
+
if (artifacts.output === "static") {
|
|
596
|
+
await buildStaticDirectoryOutput(config, artifacts, outDir, "public");
|
|
490
597
|
const publicDir = join(outDir, "public");
|
|
491
|
-
await writeHeadersFile(publicDir, config,
|
|
598
|
+
await writeHeadersFile(publicDir, config, artifacts);
|
|
599
|
+
await writeFile(join(outDir, CANONICALIZE_MODULE), await generateCanonicalizeModule());
|
|
600
|
+
await writeFile(join(outDir, PREVIEW_SCRIPT), generatePreviewScript({
|
|
601
|
+
output: "static",
|
|
602
|
+
immutableDirs: artifacts.immutableDirs,
|
|
603
|
+
base: adapterBase(config),
|
|
604
|
+
contentTypes: artifacts.contentTypes
|
|
605
|
+
}));
|
|
492
606
|
if ((options.staticTarget ?? "generic") === "github-pages") {
|
|
493
607
|
await writeFile(join(publicDir, ".nojekyll"), "");
|
|
494
608
|
try {
|
|
@@ -499,36 +613,57 @@ function nitro(options = {}) {
|
|
|
499
613
|
}
|
|
500
614
|
await runSharedBuildSteps({
|
|
501
615
|
config,
|
|
502
|
-
|
|
616
|
+
artifacts,
|
|
503
617
|
outDir,
|
|
504
618
|
publicDirName: "public"
|
|
505
619
|
});
|
|
506
620
|
await writeFile(join(outDir, "_compress.mjs"), await generateCompressModule());
|
|
507
621
|
await writeFile(join(outDir, "_send-response.mjs"), generateSendResponseModule());
|
|
508
|
-
if (
|
|
622
|
+
if (LOCALLY_PREVIEWABLE.has(preset)) {
|
|
623
|
+
await writeFile(join(outDir, CANONICALIZE_MODULE), await generateCanonicalizeModule());
|
|
624
|
+
await writeFile(join(outDir, PREVIEW_SCRIPT), generatePreviewScript({
|
|
625
|
+
output: "server",
|
|
626
|
+
runtimeName: PRESET_CONFIGS[preset].runtimeName,
|
|
627
|
+
rscEntry: importSpecifier(outDir, join(artifacts.rsc.path, "index.js")),
|
|
628
|
+
hasManifestInit: !!artifacts.manifestInit,
|
|
629
|
+
immutableDirs: artifacts.immutableDirs,
|
|
630
|
+
base: adapterBase(config)
|
|
631
|
+
}));
|
|
632
|
+
}
|
|
633
|
+
if (artifacts.manifestInit) {
|
|
509
634
|
const rscEntry = join(outDir, "rsc", "index.js");
|
|
510
635
|
const rscContent = await readFile(rscEntry, "utf-8");
|
|
511
|
-
await writeFile(rscEntry, `${
|
|
636
|
+
await writeFile(rscEntry, `${artifacts.manifestInit}\n${rscContent}`);
|
|
512
637
|
}
|
|
513
|
-
const entry = generateNitroEntry(
|
|
638
|
+
const entry = generateNitroEntry(preset, compress);
|
|
514
639
|
await writeFile(join(outDir, "entry.ts"), entry);
|
|
515
|
-
const { serverDir } = await runNitroBuild(outDir, preset, options.nitroConfig);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
640
|
+
const { serverDir } = await runNitroBuild(outDir, preset, artifacts.immutableDirs, options.nitroConfig);
|
|
641
|
+
if (artifacts.prebuilt) {
|
|
642
|
+
const prebuiltSrc = artifacts.prebuilt.path;
|
|
643
|
+
await cp(prebuiltSrc, join(serverDir, "prebuilt"), { recursive: true });
|
|
644
|
+
if (preset === "vercel" || preset === "vercel-edge") await copyPrebuiltToVercelFuncClones(dirname(serverDir), prebuiltSrc, basename(serverDir));
|
|
645
|
+
}
|
|
521
646
|
},
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
647
|
+
async preview(_config, { output, outputDir }) {
|
|
648
|
+
if (output === "server" && !LOCALLY_PREVIEWABLE.has(preset)) throw new Error(`[timber] The nitro '${preset}' preset has no local runtime, so \`timber preview\` cannot run its server build. Preview with a node-server build, or with the platform's own tooling.`);
|
|
649
|
+
const nitroDir = join(outputDir, "nitro");
|
|
650
|
+
const script = join(nitroDir, PREVIEW_SCRIPT);
|
|
651
|
+
if (!existsSync(script)) throw new Error(`[timber] No preview server at ${script}. Run \`timber build\` before \`timber preview\`.`);
|
|
652
|
+
await spawnNitroPreview(output === "server" && preset === "bun" ? "bun" : process.execPath, [script], nitroDir);
|
|
653
|
+
}
|
|
528
654
|
};
|
|
529
655
|
}
|
|
656
|
+
/** The preview server buildOutput writes into the Nitro output directory. */
|
|
657
|
+
var PREVIEW_SCRIPT = "_preview-server.mjs";
|
|
658
|
+
/** The request-path canonicalizer the preview server imports beside it. */
|
|
659
|
+
var CANONICALIZE_MODULE = "_canonicalize.mjs";
|
|
660
|
+
/** A relative ESM import specifier for `file`, as imported from a module in `fromDir`. */
|
|
661
|
+
function importSpecifier(fromDir, file) {
|
|
662
|
+
const path = relative(fromDir, file).split(sep).join("/");
|
|
663
|
+
return path.startsWith("../") ? path : "./" + path;
|
|
664
|
+
}
|
|
530
665
|
/** @internal Exported for testing. */
|
|
531
|
-
function generateNitroEntry(
|
|
666
|
+
function generateNitroEntry(preset, compress = true) {
|
|
532
667
|
const serverEntryRelative = "./rsc/index.js";
|
|
533
668
|
const runtimeName = PRESET_CONFIGS[preset].runtimeName;
|
|
534
669
|
const earlyHints = PRESET_CONFIGS[preset].supportsEarlyHints;
|
|
@@ -645,7 +780,7 @@ function wrapNitroLoggerForBuild(logger, prefixes = SUPPRESSED_NITRO_HINT_PREFIX
|
|
|
645
780
|
function getPostBuildHint(preset) {
|
|
646
781
|
return LOCALLY_PREVIEWABLE.has(preset) ? "You can preview this build using `timber preview`" : null;
|
|
647
782
|
}
|
|
648
|
-
async function runNitroBuild(nitroDir, preset, userConfig) {
|
|
783
|
+
async function runNitroBuild(nitroDir, preset, immutableDirs, userConfig) {
|
|
649
784
|
const presetConfig = PRESET_CONFIGS[preset];
|
|
650
785
|
const { createNitro, build: nitroBuild, prepare, copyPublicAssets } = await import("nitro/builder");
|
|
651
786
|
const nitro = await createNitro({
|
|
@@ -653,10 +788,7 @@ async function runNitroBuild(nitroDir, preset, userConfig) {
|
|
|
653
788
|
preset: presetConfig.nitroPreset,
|
|
654
789
|
renderer: { handler: join(nitroDir, "entry.ts") },
|
|
655
790
|
output: { dir: join(nitroDir, presetConfig.outputDir) },
|
|
656
|
-
routeRules: {
|
|
657
|
-
"/assets/**": { headers: { "Cache-Control": IMMUTABLE_CACHE } },
|
|
658
|
-
"/_timber/fonts/**": { headers: { "Cache-Control": IMMUTABLE_CACHE } }
|
|
659
|
-
},
|
|
791
|
+
routeRules: Object.fromEntries(immutableDirs.map((dir) => [`/${dir}/**`, { headers: { "Cache-Control": IMMUTABLE_CACHE } }])),
|
|
660
792
|
rollupConfig: { external: [/\.\.\/rsc\//] },
|
|
661
793
|
...presetConfig.extraConfig,
|
|
662
794
|
...userConfig
|
|
@@ -674,21 +806,6 @@ async function runNitroBuild(nitroDir, preset, userConfig) {
|
|
|
674
806
|
return { serverDir };
|
|
675
807
|
}
|
|
676
808
|
/**
|
|
677
|
-
* Resolve the destination path for prebuilt flight payloads in the Nitro
|
|
678
|
-
* output directory. The RSC entry resolves `../prebuilt/` relative to its
|
|
679
|
-
* bundled chunk location (`<serverBundleDir>/_chunks/`), so prebuilt/ must
|
|
680
|
-
* live at `<serverBundleDir>/prebuilt/`.
|
|
681
|
-
*
|
|
682
|
-
* The serverBundleDir varies by preset — Nitro's Vercel preset uses
|
|
683
|
-
* `functions/__server.func` while most others use `server`.
|
|
684
|
-
*
|
|
685
|
-
* @internal Exported for testing.
|
|
686
|
-
*/
|
|
687
|
-
function resolvePrebuiltOutputPath(outDir, preset) {
|
|
688
|
-
const presetConfig = PRESET_CONFIGS[preset];
|
|
689
|
-
return join(outDir, presetConfig.outputDir, presetConfig.serverBundleDir, "prebuilt");
|
|
690
|
-
}
|
|
691
|
-
/**
|
|
692
809
|
* Copy prebuilt payloads into cloned Vercel function directories.
|
|
693
810
|
*
|
|
694
811
|
* When users configure `vercel.functionRules`, Nitro's compiled hook clones
|
|
@@ -705,11 +822,9 @@ async function copyPrebuiltToVercelFuncClones(functionsDir, prebuiltSrc, baseFun
|
|
|
705
822
|
} catch {
|
|
706
823
|
return;
|
|
707
824
|
}
|
|
708
|
-
await Promise.all(funcDirs.map((dir) => cp(prebuiltSrc, join(dir, "prebuilt"), { recursive: true })
|
|
709
|
-
if (e.code !== "ENOENT") throw e;
|
|
710
|
-
})));
|
|
825
|
+
await Promise.all(funcDirs.map((dir) => cp(prebuiltSrc, join(dir, "prebuilt"), { recursive: true })));
|
|
711
826
|
}
|
|
712
827
|
//#endregion
|
|
713
|
-
export { copyPrebuiltToVercelFuncClones, generateNitroEntry, getPostBuildHint, isSuppressedNitroHint, nitro,
|
|
828
|
+
export { copyPrebuiltToVercelFuncClones, generateNitroEntry, getPostBuildHint, isSuppressedNitroHint, nitro, selectSuppressedHintPrefixes, wrapNitroLoggerForBuild };
|
|
714
829
|
|
|
715
830
|
//# sourceMappingURL=nitro.js.map
|