@timber-js/app 0.2.0-alpha.9 → 0.2.0-alpha.90
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/actions-DLnUaR65.js +421 -0
- package/dist/_chunks/actions-DLnUaR65.js.map +1 -0
- package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-HS0LGUl2.js} +1 -1
- package/dist/_chunks/als-registry-HS0LGUl2.js.map +1 -0
- package/dist/_chunks/chunk-BYIpzuS7.js +39 -0
- package/dist/_chunks/{debug-gwlJkDuf.js → debug-ECi_61pb.js} +2 -2
- package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
- package/dist/_chunks/define-C77ScO0m.js +106 -0
- package/dist/_chunks/define-C77ScO0m.js.map +1 -0
- package/dist/_chunks/define-Itxvcd7F.js +199 -0
- package/dist/_chunks/define-Itxvcd7F.js.map +1 -0
- package/dist/_chunks/define-cookie-BowvzoP0.js +94 -0
- package/dist/_chunks/define-cookie-BowvzoP0.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → dev-warnings-DpGRGoDi.js} +5 -44
- package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +1 -0
- package/dist/_chunks/format-CYBGxKtc.js +14 -0
- package/dist/_chunks/format-CYBGxKtc.js.map +1 -0
- package/dist/_chunks/{interception-BOoWmLUA.js → interception-DRlhJWbu.js} +219 -97
- package/dist/_chunks/interception-DRlhJWbu.js.map +1 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js +41 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DS3eKNmf.js} +1 -1
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-DS3eKNmf.js.map} +1 -1
- package/dist/_chunks/request-context-CK5tZqIP.js +478 -0
- package/dist/_chunks/request-context-CK5tZqIP.js.map +1 -0
- package/dist/_chunks/schema-bridge-C3xl_vfb.js +86 -0
- package/dist/_chunks/schema-bridge-C3xl_vfb.js.map +1 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js +65 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js.map +1 -0
- package/dist/_chunks/segment-context-fHFLF1PE.js +34 -0
- package/dist/_chunks/segment-context-fHFLF1PE.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-DzuI0bIV.js} +1 -1
- package/dist/_chunks/{ssr-data-MjmprTmO.js.map → ssr-data-DzuI0bIV.js.map} +1 -1
- package/dist/_chunks/stale-reload-BX5gL1r-.js +64 -0
- package/dist/_chunks/stale-reload-BX5gL1r-.js.map +1 -0
- package/dist/_chunks/{tracing-CemImE6h.js → tracing-CCYbKn5n.js} +60 -9
- package/dist/_chunks/tracing-CCYbKn5n.js.map +1 -0
- package/dist/_chunks/use-params-Br9YSUFV.js +295 -0
- package/dist/_chunks/use-params-Br9YSUFV.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-BiV5GJgm.js} +7 -4
- package/dist/_chunks/use-query-states-BiV5GJgm.js.map +1 -0
- package/dist/adapters/cloudflare-dev.d.ts +109 -0
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +73 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +95 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +148 -12
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +135 -11
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +17 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +56 -13
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/cache/cache-api.d.ts +24 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +31 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +23 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +142 -80
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/singleflight.d.ts +18 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts +22 -0
- package/dist/cache/sizeof.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cli.d.ts +6 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +8 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +27 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/hmr.d.ts +21 -0
- package/dist/client/browser-entry/hmr.d.ts.map +1 -0
- package/dist/client/browser-entry/hydrate.d.ts +46 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +30 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +26 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +23 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +19 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +12 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +10 -4
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/error-reconstituter.d.ts +54 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +6 -3
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +19 -4
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +9 -21
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +229 -1018
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +18 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +890 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link-pending-store.d.ts +63 -0
- package/dist/client/link-pending-store.d.ts.map +1 -0
- package/dist/client/link.d.ts +62 -55
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/nav-link-store.d.ts +36 -0
- package/dist/client/nav-link-store.d.ts.map +1 -0
- package/dist/client/navigation-api-types.d.ts +90 -0
- package/dist/client/navigation-api-types.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts +115 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +13 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router.d.ts +70 -4
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +38 -3
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +63 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +13 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-reload.d.ts +15 -0
- package/dist/client/stale-reload.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +5 -5
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/use-link-status.d.ts +5 -5
- package/dist/client/use-link-status.d.ts.map +1 -1
- package/dist/client/use-params.d.ts +6 -4
- package/dist/client/use-params.d.ts.map +1 -1
- package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- package/dist/codec.d.ts +33 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +2 -0
- package/dist/config-types.d.ts +266 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-validation.d.ts +51 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/content/index.d.ts +1 -10
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +0 -2
- package/dist/cookies/define-cookie.d.ts +35 -14
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -83
- package/dist/fonts/bundle.d.ts +48 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/css.d.ts +1 -0
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/pipeline.d.ts +138 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +72 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +45 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +59 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +45 -190
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4294 -2453
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +107 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +1 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +2 -2
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +3 -3
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +32 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-404-page.d.ts +56 -0
- package/dist/plugins/dev-404-page.d.ts.map +1 -0
- package/dist/plugins/dev-browser-logs.d.ts +84 -0
- package/dist/plugins/dev-browser-logs.d.ts.map +1 -0
- package/dist/plugins/dev-error-overlay.d.ts +49 -9
- package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
- package/dist/plugins/dev-error-page.d.ts +58 -0
- package/dist/plugins/dev-error-page.d.ts.map +1 -0
- package/dist/plugins/dev-logs.d.ts +1 -1
- package/dist/plugins/dev-logs.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/dev-terminal-error.d.ts +28 -0
- package/dist/plugins/dev-terminal-error.d.ts.map +1 -0
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +17 -73
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +6 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +4 -4
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen.d.ts +2 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/convention-lint.d.ts +41 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +3 -2
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/segment-classify.d.ts +46 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/status-file-lint.d.ts +2 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- package/dist/routing/types.d.ts +16 -4
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +76 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +139 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +32 -441
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/registry.d.ts +2 -2
- package/dist/search-params/registry.d.ts.map +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/segment-params/define.d.ts +78 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +3 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +2 -0
- package/dist/server/access-gate.d.ts +4 -0
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +41 -6
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-encryption.d.ts +76 -0
- package/dist/server/action-encryption.d.ts.map +1 -0
- package/dist/server/action-handler.d.ts +7 -0
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +3 -6
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +32 -4
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +2 -2
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/debug.d.ts +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/deny-page-resolver.d.ts +52 -0
- package/dist/server/deny-page-resolver.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-holding-server.d.ts +52 -0
- package/dist/server/dev-holding-server.d.ts.map +1 -0
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/dev-warnings.d.ts +1 -21
- package/dist/server/dev-warnings.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -5
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -1
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +12 -7
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +66 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +42 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/flush.d.ts.map +1 -1
- package/dist/server/form-data.d.ts +29 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts +51 -11
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -43
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +195 -2800
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +46 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +2900 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +25 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +19 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +113 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/page-deny-boundary.d.ts +31 -0
- package/dist/server/page-deny-boundary.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +1 -1
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +6 -0
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +52 -10
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +69 -18
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +112 -43
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +27 -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 +16 -2
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +2 -2
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +48 -5
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +20 -3
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +129 -0
- package/dist/server/sitemap-generator.d.ts.map +1 -0
- package/dist/server/sitemap-handler.d.ts +22 -0
- package/dist/server/sitemap-handler.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +23 -0
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +39 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +50 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +1 -1
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +36 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +4 -4
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +22 -19
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.js +42 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +26 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +20 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/headers.d.ts +2 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/navigation-client.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +3 -2
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/directive-parser.d.ts +5 -2
- package/dist/utils/directive-parser.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/package.json +51 -16
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +142 -0
- package/src/adapters/cloudflare.ts +342 -28
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +52 -8
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +38 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +81 -18
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/sizeof.ts +31 -0
- package/src/cache/timber-cache.ts +24 -20
- package/src/cli.ts +16 -6
- package/src/client/browser-dev.ts +128 -1
- package/src/client/browser-entry/action-dispatch.ts +116 -0
- package/src/client/browser-entry/hmr.ts +81 -0
- package/src/client/browser-entry/hydrate.ts +145 -0
- package/src/client/browser-entry/index.ts +143 -0
- package/src/client/browser-entry/post-hydration.ts +119 -0
- package/src/client/browser-entry/router-init.ts +193 -0
- package/src/client/browser-entry/rsc-stream.ts +157 -0
- package/src/client/browser-entry/scroll.ts +27 -0
- package/src/client/error-boundary.tsx +48 -16
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +14 -7
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +65 -38
- package/src/client/internal.ts +57 -0
- package/src/client/link-pending-store.ts +111 -0
- package/src/client/link.tsx +342 -113
- package/src/client/nav-link-store.ts +47 -0
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +332 -0
- package/src/client/navigation-context.ts +31 -6
- package/src/client/navigation-root.tsx +342 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router-ref.ts +1 -1
- package/src/client/router.ts +299 -72
- package/src/client/rsc-fetch.ts +97 -8
- package/src/client/segment-cache.ts +1 -1
- package/src/client/segment-outlet.tsx +86 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/stale-reload.ts +72 -3
- package/src/client/top-loader.tsx +18 -6
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-params.ts +7 -5
- package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
- package/src/client/use-query-states.ts +9 -3
- package/src/client/use-router.ts +1 -1
- package/src/codec.ts +49 -0
- package/src/config-types.ts +264 -0
- package/src/config-validation.ts +303 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +78 -25
- package/src/cookies/index.ts +8 -0
- package/src/fonts/bundle.ts +142 -0
- package/src/fonts/css.ts +2 -1
- package/src/fonts/dev-middleware.ts +74 -0
- package/src/fonts/pipeline.ts +275 -0
- package/src/fonts/transform.ts +353 -0
- package/src/fonts/types.ts +50 -1
- package/src/fonts/virtual-modules.ts +159 -0
- package/src/index.ts +314 -355
- package/src/plugin-context.ts +240 -0
- package/src/plugins/adapter-build.ts +9 -3
- package/src/plugins/build-manifest.ts +13 -2
- package/src/plugins/build-report.ts +3 -3
- package/src/plugins/client-chunks.ts +65 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-404-page.ts +418 -0
- package/src/plugins/dev-browser-logs.ts +288 -0
- package/src/plugins/dev-error-overlay.ts +286 -42
- package/src/plugins/dev-error-page.ts +536 -0
- package/src/plugins/dev-logs.ts +1 -1
- package/src/plugins/dev-server.ts +146 -19
- package/src/plugins/dev-terminal-error.ts +217 -0
- package/src/plugins/entries.ts +111 -10
- package/src/plugins/fonts.ts +133 -638
- package/src/plugins/mdx.ts +1 -1
- package/src/plugins/routing.ts +213 -31
- package/src/plugins/server-action-exports.ts +1 -1
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +136 -35
- package/src/plugins/static-build.ts +17 -11
- package/src/routing/codegen.ts +273 -105
- package/src/routing/convention-lint.ts +356 -0
- package/src/routing/index.ts +2 -0
- package/src/routing/scanner.ts +93 -23
- package/src/routing/segment-classify.ts +89 -0
- package/src/routing/status-file-lint.ts +3 -2
- package/src/routing/types.ts +17 -4
- package/src/rsc-runtime/rsc.ts +2 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
- package/src/search-params/define.ts +482 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +85 -0
- package/src/segment-params/define.ts +279 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +70 -29
- package/src/server/action-client.ts +88 -15
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +53 -6
- package/src/server/actions.ts +10 -9
- package/src/server/als-registry.ts +34 -6
- package/src/server/build-manifest.ts +10 -4
- package/src/server/compress.ts +25 -7
- package/src/server/debug.ts +1 -1
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-page-resolver.ts +154 -0
- package/src/server/deny-renderer.ts +24 -38
- package/src/server/dev-holding-server.ts +185 -0
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/dev-warnings.ts +4 -49
- package/src/server/early-hints.ts +36 -15
- package/src/server/error-boundary-wrapper.ts +74 -22
- package/src/server/fallback-error.ts +74 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/flush.ts +2 -1
- package/src/server/form-data.ts +76 -0
- package/src/server/html-injectors.ts +280 -120
- package/src/server/index.ts +25 -177
- package/src/server/internal.ts +169 -0
- package/src/server/logger.ts +44 -36
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +509 -0
- package/src/server/page-deny-boundary.tsx +56 -0
- package/src/server/pipeline-interception.ts +17 -16
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline.ts +261 -66
- package/src/server/primitives.ts +111 -28
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +293 -132
- package/src/server/route-element-builder.ts +283 -191
- package/src/server/route-handler.ts +24 -4
- package/src/server/route-matcher.ts +31 -20
- package/src/server/rsc-entry/api-handler.ts +15 -16
- package/src/server/rsc-entry/error-renderer.ts +305 -89
- package/src/server/rsc-entry/helpers.ts +134 -5
- package/src/server/rsc-entry/index.ts +304 -111
- package/src/server/rsc-entry/rsc-payload.ts +65 -18
- package/src/server/rsc-entry/rsc-stream.ts +81 -13
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +171 -38
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +126 -0
- package/src/server/slot-resolver.ts +244 -229
- package/src/server/ssr-entry.ts +215 -32
- package/src/server/ssr-render.ts +289 -67
- package/src/server/ssr-wrappers.tsx +139 -0
- package/src/server/status-code-resolver.ts +1 -1
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +20 -9
- package/src/server/tree-builder.ts +92 -58
- package/src/server/types.ts +3 -6
- package/src/server/version-skew.ts +104 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +5 -1
- package/src/shims/navigation-client.ts +1 -1
- package/src/shims/navigation.ts +7 -2
- package/src/utils/directive-parser.ts +5 -2
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
- package/dist/_chunks/format-DviM89f0.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
- package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/cache/register-cached-function.d.ts +0 -17
- package/dist/cache/register-cached-function.d.ts.map +0 -1
- package/dist/client/browser-entry.d.ts +0 -21
- package/dist/client/browser-entry.d.ts.map +0 -1
- package/dist/client/link-status-provider.d.ts +0 -11
- package/dist/client/link-status-provider.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/cookies/index.js.map +0 -1
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/codecs.d.ts +0 -53
- package/dist/search-params/codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/server/response-cache.d.ts +0 -54
- package/dist/server/response-cache.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -103
- package/src/client/browser-entry.ts +0 -678
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/transition-root.tsx +0 -166
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/create.ts +0 -321
- package/src/server/prerender.ts +0 -139
- package/src/server/response-cache.ts +0 -410
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* loadModule — enriched error context for route manifest .load() failures.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the lazy `load()` functions from the route manifest with a
|
|
5
|
+
* try/catch that re-throws with the file path and original cause.
|
|
6
|
+
*
|
|
7
|
+
* Callers that need fallthrough behavior (error renderers) can use
|
|
8
|
+
* `.catch(() => null)` or try/catch — the decision stays at the call site.
|
|
9
|
+
*
|
|
10
|
+
* See design/spike-TIM-551-dynamic-import-audit.md §"Proposed Wrapping Strategy"
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** A manifest file reference with a lazy import function and file path. */
|
|
14
|
+
export interface ManifestLoader {
|
|
15
|
+
load: () => Promise<unknown>;
|
|
16
|
+
filePath: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Custom error class for module load failures.
|
|
21
|
+
*
|
|
22
|
+
* Preserves the original error as `cause` while providing a
|
|
23
|
+
* human-readable message with the file path.
|
|
24
|
+
*/
|
|
25
|
+
export class ModuleLoadError extends Error {
|
|
26
|
+
/** The file path that failed to load. */
|
|
27
|
+
readonly filePath: string;
|
|
28
|
+
|
|
29
|
+
constructor(filePath: string, cause: unknown) {
|
|
30
|
+
const originalMessage = cause instanceof Error ? cause.message : String(cause);
|
|
31
|
+
super(`[timber] Failed to load module ${filePath}\n ${originalMessage}`, { cause });
|
|
32
|
+
this.name = 'ModuleLoadError';
|
|
33
|
+
this.filePath = filePath;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Load a route manifest module with enriched error context.
|
|
39
|
+
*
|
|
40
|
+
* On success: returns the module object (same as `loader.load()`).
|
|
41
|
+
* On failure: throws `ModuleLoadError` with file path and original cause.
|
|
42
|
+
*
|
|
43
|
+
* For error rendering paths that need fallthrough instead of throwing,
|
|
44
|
+
* callers should catch at the call site:
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* // Throwing (default) — route-element-builder, api-handler, etc.
|
|
48
|
+
* const mod = await loadModule(segment.page);
|
|
49
|
+
*
|
|
50
|
+
* // Fallthrough — error-renderer, error-boundary-wrapper
|
|
51
|
+
* const mod = await loadModule(segment.error).catch(() => null);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export async function loadModule<T = Record<string, unknown>>(loader: ManifestLoader): Promise<T> {
|
|
55
|
+
try {
|
|
56
|
+
return (await loader.load()) as T;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new ModuleLoadError(loader.filePath, error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sensitive field stripping — removes password/token/CVV-style fields
|
|
3
|
+
* from form values before they are echoed back to the client as
|
|
4
|
+
* `submittedValues` for form repopulation.
|
|
5
|
+
*
|
|
6
|
+
* Applied to both action paths:
|
|
7
|
+
* - With-JS action path: `createActionClient()` in `action-client.ts`
|
|
8
|
+
* - No-JS form POST path: `handleFormAction()` in `action-handler.ts`
|
|
9
|
+
*
|
|
10
|
+
* Why: on a validation failure, timber echoes submitted form values back so
|
|
11
|
+
* the user doesn't have to re-type everything. Without filtering, plaintext
|
|
12
|
+
* passwords / credit-card numbers / TOTP codes would travel through the RSC
|
|
13
|
+
* stream (with-JS) or land in the HTML as `defaultValue` attributes (no-JS)
|
|
14
|
+
* — ending up in browser history, proxy logs, disk caches, and the
|
|
15
|
+
* back-forward cache.
|
|
16
|
+
*
|
|
17
|
+
* Safe by default: the built-in deny-list is applied unconditionally unless
|
|
18
|
+
* the user explicitly opts out via `forms.stripSensitiveFields: false` in
|
|
19
|
+
* `timber.config.ts` or per-action via `createActionClient({ stripSensitiveFields: false })`.
|
|
20
|
+
*
|
|
21
|
+
* See design/08-forms-and-actions.md §"Validation errors"
|
|
22
|
+
* See design/13-security.md §"Sensitive field stripping"
|
|
23
|
+
* See TIM-816
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { isDebug } from './debug.js';
|
|
27
|
+
|
|
28
|
+
// ─── Public types ────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* How to strip sensitive fields from `submittedValues`.
|
|
32
|
+
*
|
|
33
|
+
* - `true` / `undefined` — use the built-in deny-list (default, safe).
|
|
34
|
+
* - `false` — do not strip anything (dev convenience; never do this in prod).
|
|
35
|
+
* - `string[]` — additional field names to strip, merged with the built-in list.
|
|
36
|
+
* - `(name) => boolean` — custom predicate, fully replaces the built-in list.
|
|
37
|
+
* Return `true` to strip, `false` to keep. The `name` argument is the raw
|
|
38
|
+
* (un-normalized) field name as it appeared in the submitted form.
|
|
39
|
+
*/
|
|
40
|
+
export type SensitiveFieldsOption = boolean | readonly string[] | ((name: string) => boolean);
|
|
41
|
+
|
|
42
|
+
// ─── Built-in deny-list ──────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Substring patterns matched against the normalized field name.
|
|
46
|
+
* Normalization = lowercase + strip `_` and `-`.
|
|
47
|
+
*
|
|
48
|
+
* Any field whose normalized name *contains* one of these strings is
|
|
49
|
+
* considered sensitive. Entries like `currentPassword`, `passwordConfirmation`,
|
|
50
|
+
* and `user.password` all match via the `password` substring.
|
|
51
|
+
*/
|
|
52
|
+
const BUILTIN_SUBSTRING_PATTERNS: readonly string[] = [
|
|
53
|
+
'password',
|
|
54
|
+
'passwd',
|
|
55
|
+
'pwd',
|
|
56
|
+
'secret',
|
|
57
|
+
'apikey',
|
|
58
|
+
'accesstoken',
|
|
59
|
+
'refreshtoken',
|
|
60
|
+
'cvv',
|
|
61
|
+
'cvc',
|
|
62
|
+
'cardnumber',
|
|
63
|
+
'cardcvc',
|
|
64
|
+
'ssn',
|
|
65
|
+
'socialsecuritynumber',
|
|
66
|
+
'otp',
|
|
67
|
+
'totp',
|
|
68
|
+
'mfacode',
|
|
69
|
+
'twofactorcode',
|
|
70
|
+
'privatekey',
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Exact matches against the normalized field name. These are field names that
|
|
75
|
+
* are too short or too common to substring-match safely. e.g. `token` alone
|
|
76
|
+
* would match `csrfToken`, which is not sensitive — so `token` is exact-only,
|
|
77
|
+
* while legitimate token fields are covered by `accesstoken` / `refreshtoken`.
|
|
78
|
+
*/
|
|
79
|
+
const BUILTIN_EXACT_PATTERNS: readonly string[] = ['token'];
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Normalize a field name for deny-list comparison.
|
|
83
|
+
* Lowercases the string and strips `_` and `-` so camelCase, snake_case, and
|
|
84
|
+
* kebab-case variants all compare equal (`api_key` / `apiKey` / `api-key` →
|
|
85
|
+
* `apikey`).
|
|
86
|
+
*/
|
|
87
|
+
function normalize(name: string): string {
|
|
88
|
+
let out = '';
|
|
89
|
+
for (let i = 0; i < name.length; i++) {
|
|
90
|
+
const ch = name.charCodeAt(i);
|
|
91
|
+
if (ch === 0x5f /* _ */ || ch === 0x2d /* - */) continue;
|
|
92
|
+
// A-Z → a-z
|
|
93
|
+
if (ch >= 0x41 && ch <= 0x5a) {
|
|
94
|
+
out += String.fromCharCode(ch + 32);
|
|
95
|
+
} else {
|
|
96
|
+
out += name[i];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Check whether a name matches the built-in deny-list (with optional extras).
|
|
104
|
+
* Extras are merged into the substring pattern list after normalization.
|
|
105
|
+
*/
|
|
106
|
+
function isBuiltinSensitive(name: string, extras?: readonly string[]): boolean {
|
|
107
|
+
const normalized = normalize(name);
|
|
108
|
+
if (BUILTIN_EXACT_PATTERNS.includes(normalized)) return true;
|
|
109
|
+
for (const pattern of BUILTIN_SUBSTRING_PATTERNS) {
|
|
110
|
+
if (normalized.includes(pattern)) return true;
|
|
111
|
+
}
|
|
112
|
+
if (extras && extras.length > 0) {
|
|
113
|
+
for (const extra of extras) {
|
|
114
|
+
const normExtra = normalize(extra);
|
|
115
|
+
if (normExtra.length === 0) continue;
|
|
116
|
+
if (normalized.includes(normExtra)) return true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ─── Predicate resolution ────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* A resolved predicate: `null` means "don't strip anything" (the option was
|
|
126
|
+
* explicitly `false`). Otherwise a function from raw field name → boolean.
|
|
127
|
+
*/
|
|
128
|
+
export type ResolvedSensitivePredicate = ((name: string) => boolean) | null;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Resolve a `SensitiveFieldsOption` into a concrete predicate.
|
|
132
|
+
* Precedence: per-action > global > built-in default.
|
|
133
|
+
*
|
|
134
|
+
* - Per-action `undefined` → fall back to global.
|
|
135
|
+
* - Global `undefined` → use built-in list.
|
|
136
|
+
* - Either level set to `false` → disable stripping entirely (returns `null`).
|
|
137
|
+
* - `true` → built-in list.
|
|
138
|
+
* - `string[]` → built-in ∪ extras.
|
|
139
|
+
* - function → custom, replaces the built-in list entirely.
|
|
140
|
+
*/
|
|
141
|
+
export function resolveSensitivePredicate(
|
|
142
|
+
perAction: SensitiveFieldsOption | undefined,
|
|
143
|
+
global: SensitiveFieldsOption | undefined
|
|
144
|
+
): ResolvedSensitivePredicate {
|
|
145
|
+
const chosen = perAction !== undefined ? perAction : global;
|
|
146
|
+
|
|
147
|
+
if (chosen === false) return null;
|
|
148
|
+
if (chosen === undefined || chosen === true) {
|
|
149
|
+
return (name) => isBuiltinSensitive(name);
|
|
150
|
+
}
|
|
151
|
+
if (typeof chosen === 'function') {
|
|
152
|
+
return chosen;
|
|
153
|
+
}
|
|
154
|
+
// Array of extra names merged with the built-in list.
|
|
155
|
+
const extras = chosen;
|
|
156
|
+
return (name) => isBuiltinSensitive(name, extras);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ─── Module-level global config ──────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
let globalConfig: SensitiveFieldsOption | undefined;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Set the global `forms.stripSensitiveFields` config from `timber.config.ts`.
|
|
165
|
+
* Called once at startup from `rsc-entry`.
|
|
166
|
+
*/
|
|
167
|
+
export function setGlobalSensitiveFieldsConfig(option: SensitiveFieldsOption | undefined): void {
|
|
168
|
+
globalConfig = option;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Read the global `forms.stripSensitiveFields` config. */
|
|
172
|
+
export function getGlobalSensitiveFieldsConfig(): SensitiveFieldsOption | undefined {
|
|
173
|
+
return globalConfig;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ─── Stripping ───────────────────────────────────────────────────────────
|
|
177
|
+
|
|
178
|
+
// One warning per field name per process — prevents log spam when a form is
|
|
179
|
+
// submitted many times in dev mode.
|
|
180
|
+
const warnedFields = new Set<string>();
|
|
181
|
+
|
|
182
|
+
function warnStripped(name: string): void {
|
|
183
|
+
if (!isDebug()) return;
|
|
184
|
+
if (warnedFields.has(name)) return;
|
|
185
|
+
warnedFields.add(name);
|
|
186
|
+
console.warn(
|
|
187
|
+
`[timber] stripped sensitive field "${name}" from submittedValues. ` +
|
|
188
|
+
`Override via forms.stripSensitiveFields in timber.config.ts.`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Walk an object (recursively) and return a copy with every key matching
|
|
194
|
+
* `predicate` removed. Nested objects like `{ user: { password: '...' } }`
|
|
195
|
+
* are handled — `user.password` is stripped while other `user.*` fields remain.
|
|
196
|
+
*
|
|
197
|
+
* - Arrays are walked element-wise (object entries inside arrays are cleaned).
|
|
198
|
+
* - Non-plain values (strings, numbers, Files, Dates, etc.) are returned as-is.
|
|
199
|
+
* - When a stripped key is encountered, it is omitted from the result entirely
|
|
200
|
+
* — we do NOT set it to an empty string, because that would overwrite a
|
|
201
|
+
* valid `defaultValue` the form author might have set.
|
|
202
|
+
*/
|
|
203
|
+
export function stripSensitiveFields<T>(value: T, predicate: ResolvedSensitivePredicate): T {
|
|
204
|
+
// Null predicate = stripping disabled entirely.
|
|
205
|
+
if (predicate === null) return value;
|
|
206
|
+
if (value === null || value === undefined) return value;
|
|
207
|
+
if (typeof value !== 'object') return value;
|
|
208
|
+
if (value instanceof File || value instanceof Date) return value;
|
|
209
|
+
|
|
210
|
+
if (Array.isArray(value)) {
|
|
211
|
+
return value.map((item) => stripSensitiveFields(item, predicate)) as unknown as T;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const result: Record<string, unknown> = {};
|
|
215
|
+
for (const [key, nested] of Object.entries(value as Record<string, unknown>)) {
|
|
216
|
+
if (predicate(key)) {
|
|
217
|
+
warnStripped(key);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
result[key] = stripSensitiveFields(nested, predicate);
|
|
221
|
+
}
|
|
222
|
+
return result as unknown as T;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ─── Test helpers ────────────────────────────────────────────────────────
|
|
226
|
+
|
|
227
|
+
/** Reset the "warned once" cache. Exposed for tests. */
|
|
228
|
+
export function __resetSensitiveFieldsWarnings(): void {
|
|
229
|
+
warnedFields.clear();
|
|
230
|
+
}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-generate sitemap.xml from the route tree.
|
|
3
|
+
*
|
|
4
|
+
* When enabled via `sitemap: { enabled: true, baseUrl: '...' }` in timber.config.ts,
|
|
5
|
+
* this module walks the route tree and produces sitemap XML for all discoverable pages.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Collects all static page routes automatically
|
|
9
|
+
* - Calls `generateStaticParams()` on dynamic routes to enumerate URLs
|
|
10
|
+
* - Skips API routes (route.ts), layout-only segments, slots, intercepting routes
|
|
11
|
+
* - Skips auth-protected routes (access.ts in segment chain) by default
|
|
12
|
+
* - Automatic pagination: sitemap index when > 50,000 URLs
|
|
13
|
+
*
|
|
14
|
+
* See design/16-metadata.md §"Auto-generated Sitemap"
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { serializeSitemap, serializeSitemapIndex } from './pipeline-metadata.js';
|
|
18
|
+
import type { SegmentNode } from '../routing/types.js';
|
|
19
|
+
|
|
20
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
/** Configuration for sitemap generation from timber.config.ts. */
|
|
23
|
+
export interface SitemapConfig {
|
|
24
|
+
/** Must be explicitly true to enable auto-generation. */
|
|
25
|
+
enabled: boolean;
|
|
26
|
+
/** Base URL for absolute URLs in the sitemap. Required. e.g., 'https://example.com' */
|
|
27
|
+
baseUrl: string;
|
|
28
|
+
/** Default changefreq for all entries. Optional. */
|
|
29
|
+
defaultChangeFrequency?: string;
|
|
30
|
+
/** Default priority for all entries (0.0–1.0). Optional. */
|
|
31
|
+
defaultPriority?: number;
|
|
32
|
+
/** Include routes protected by access.ts. Default: false. */
|
|
33
|
+
includeProtected?: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A single sitemap entry ready for serialization. */
|
|
37
|
+
export interface SitemapEntry {
|
|
38
|
+
url: string;
|
|
39
|
+
changeFrequency?: string;
|
|
40
|
+
priority?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A route discovered during tree walk that may need async resolution
|
|
45
|
+
* (dynamic routes with generateStaticParams).
|
|
46
|
+
*/
|
|
47
|
+
export interface SitemapRoute {
|
|
48
|
+
/** The URL path pattern (e.g., '/products/[id]'). */
|
|
49
|
+
urlPath: string;
|
|
50
|
+
/** Whether this route has dynamic segments that need generateStaticParams. */
|
|
51
|
+
isDynamic: boolean;
|
|
52
|
+
/** Loader for the page module (from route manifest). */
|
|
53
|
+
pageLoader?: { load: () => Promise<unknown>; filePath: string };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Function signature for loading a page module.
|
|
58
|
+
* Takes the manifest loader and returns the module exports.
|
|
59
|
+
*/
|
|
60
|
+
export type ModuleLoader = (loader: {
|
|
61
|
+
load: () => Promise<unknown>;
|
|
62
|
+
filePath: string;
|
|
63
|
+
}) => Promise<Record<string, unknown>>;
|
|
64
|
+
|
|
65
|
+
/** Result of sitemap generation. */
|
|
66
|
+
export type SitemapResult =
|
|
67
|
+
| { type: 'single'; xml: string }
|
|
68
|
+
| { type: 'index'; indexXml: string; pages: Map<number, string> };
|
|
69
|
+
|
|
70
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
/** Maximum URLs per sitemap file per the sitemap protocol. */
|
|
73
|
+
export const URLS_PER_SITEMAP = 50_000;
|
|
74
|
+
|
|
75
|
+
// ─── Tree Walking ────────────────────────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Walk the route tree and collect all routes eligible for the sitemap.
|
|
79
|
+
*
|
|
80
|
+
* Pure synchronous function — no module loading. Returns routes that may
|
|
81
|
+
* need async resolution (dynamic routes with generateStaticParams).
|
|
82
|
+
*
|
|
83
|
+
* @param root - The root segment node from the route tree
|
|
84
|
+
* @param config - Sitemap configuration
|
|
85
|
+
* @returns Array of sitemap routes to resolve
|
|
86
|
+
*/
|
|
87
|
+
export function collectSitemapRoutes(root: SegmentNode, config: SitemapConfig): SitemapRoute[] {
|
|
88
|
+
const routes: SitemapRoute[] = [];
|
|
89
|
+
walkNode(root, routes, config.includeProtected ?? false, false);
|
|
90
|
+
return routes;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Recursive tree walker. Collects page routes, skipping ineligible segments.
|
|
95
|
+
*
|
|
96
|
+
* @param node - Current segment node
|
|
97
|
+
* @param routes - Accumulator for discovered routes
|
|
98
|
+
* @param includeProtected - Whether to include routes with access.ts
|
|
99
|
+
* @param hasAccessInChain - Whether any ancestor has access.ts
|
|
100
|
+
*/
|
|
101
|
+
function walkNode(
|
|
102
|
+
node: SegmentNode,
|
|
103
|
+
routes: SitemapRoute[],
|
|
104
|
+
includeProtected: boolean,
|
|
105
|
+
hasAccessInChain: boolean
|
|
106
|
+
): void {
|
|
107
|
+
// Track whether this node or any ancestor has access.ts
|
|
108
|
+
const protectedChain = hasAccessInChain || !!node.access;
|
|
109
|
+
|
|
110
|
+
// Skip intercepting routes — they're conditional rewrites, not real pages
|
|
111
|
+
if (node.segmentType === 'intercepting') return;
|
|
112
|
+
|
|
113
|
+
// Skip private folders
|
|
114
|
+
if (node.segmentType === 'private') return;
|
|
115
|
+
|
|
116
|
+
// Skip slots — parallel routes don't contribute independent URLs
|
|
117
|
+
// (slots are handled via the parent's slots map, but we skip them here)
|
|
118
|
+
|
|
119
|
+
// Check if this node has a page (not a route.ts API endpoint)
|
|
120
|
+
if (node.page && !node.route) {
|
|
121
|
+
// Skip protected routes unless configured to include them
|
|
122
|
+
if (!protectedChain || includeProtected) {
|
|
123
|
+
const isDynamic = hasDynamicSegments(node.urlPath);
|
|
124
|
+
// At runtime (manifest), page has a `load` function. At scan time (RouteFile),
|
|
125
|
+
// it only has filePath + extension. We check for `load` at runtime.
|
|
126
|
+
const page = node.page as {
|
|
127
|
+
filePath: string;
|
|
128
|
+
extension: string;
|
|
129
|
+
load?: () => Promise<unknown>;
|
|
130
|
+
};
|
|
131
|
+
routes.push({
|
|
132
|
+
urlPath: node.urlPath,
|
|
133
|
+
isDynamic,
|
|
134
|
+
pageLoader: page.load ? { load: page.load, filePath: page.filePath } : undefined,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Recurse into children (not slots — slots don't contribute sitemap URLs)
|
|
140
|
+
for (const child of node.children) {
|
|
141
|
+
walkNode(child, routes, includeProtected, protectedChain);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Do NOT recurse into slots — they are parallel routes at the same URL
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Check if a URL path contains dynamic segments.
|
|
149
|
+
*
|
|
150
|
+
* Dynamic segments are enclosed in brackets: [param], [...param], [[...param]]
|
|
151
|
+
*/
|
|
152
|
+
export function hasDynamicSegments(urlPath: string): boolean {
|
|
153
|
+
return /\[/.test(urlPath);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ─── URL Resolution ──────────────────────────────────────────────────────────
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Resolve sitemap routes into concrete URLs.
|
|
160
|
+
*
|
|
161
|
+
* For static routes, the URL is derived directly from the path.
|
|
162
|
+
* For dynamic routes, calls `generateStaticParams()` from the page module.
|
|
163
|
+
*
|
|
164
|
+
* @param routes - Routes collected by collectSitemapRoutes
|
|
165
|
+
* @param config - Sitemap configuration
|
|
166
|
+
* @param loadModule - Async function to load a page module by file path
|
|
167
|
+
* @returns Array of sitemap entries with absolute URLs
|
|
168
|
+
*/
|
|
169
|
+
export async function resolveSitemapUrls(
|
|
170
|
+
routes: SitemapRoute[],
|
|
171
|
+
config: SitemapConfig,
|
|
172
|
+
loadModule?: ModuleLoader
|
|
173
|
+
): Promise<SitemapEntry[]> {
|
|
174
|
+
const baseUrl = config.baseUrl.replace(/\/+$/, ''); // strip trailing slash
|
|
175
|
+
const entries: SitemapEntry[] = [];
|
|
176
|
+
|
|
177
|
+
for (const route of routes) {
|
|
178
|
+
if (!route.isDynamic) {
|
|
179
|
+
// Static route — direct URL
|
|
180
|
+
const url = route.urlPath === '/' ? baseUrl + '/' : baseUrl + route.urlPath;
|
|
181
|
+
entries.push({
|
|
182
|
+
url,
|
|
183
|
+
changeFrequency: config.defaultChangeFrequency,
|
|
184
|
+
priority: config.defaultPriority,
|
|
185
|
+
});
|
|
186
|
+
} else if (loadModule && route.pageLoader) {
|
|
187
|
+
// Dynamic route — try to call generateStaticParams
|
|
188
|
+
try {
|
|
189
|
+
const mod = await loadModule(route.pageLoader);
|
|
190
|
+
const generateFn = mod.generateStaticParams;
|
|
191
|
+
if (typeof generateFn !== 'function') {
|
|
192
|
+
// No generateStaticParams export — skip this dynamic route
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const paramSets: Record<string, string>[] = await generateFn();
|
|
197
|
+
for (const params of paramSets) {
|
|
198
|
+
const resolvedPath = resolvePathWithParams(route.urlPath, params);
|
|
199
|
+
if (resolvedPath) {
|
|
200
|
+
entries.push({
|
|
201
|
+
url: baseUrl + resolvedPath,
|
|
202
|
+
changeFrequency: config.defaultChangeFrequency,
|
|
203
|
+
priority: config.defaultPriority,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
// Log and skip — don't fail the entire sitemap for one bad route
|
|
209
|
+
const filePath = route.pageLoader.filePath;
|
|
210
|
+
console.warn(
|
|
211
|
+
`[timber] sitemap: failed to call generateStaticParams for ${filePath}:`,
|
|
212
|
+
error instanceof Error ? error.message : error
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// If no loadModule provided and route is dynamic, skip it
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return entries;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Replace dynamic segments in a URL path with concrete param values.
|
|
224
|
+
*
|
|
225
|
+
* Handles:
|
|
226
|
+
* - `[param]` → single value
|
|
227
|
+
* - `[...param]` → slash-joined values
|
|
228
|
+
* - `[[...param]]` → slash-joined values (or empty string if not provided)
|
|
229
|
+
*
|
|
230
|
+
* @returns The resolved path, or null if params are missing
|
|
231
|
+
*/
|
|
232
|
+
export function resolvePathWithParams(
|
|
233
|
+
urlPath: string,
|
|
234
|
+
params: Record<string, string | string[]>
|
|
235
|
+
): string | null {
|
|
236
|
+
let resolved = urlPath;
|
|
237
|
+
|
|
238
|
+
// Optional catch-all: [[...param]]
|
|
239
|
+
resolved = resolved.replace(/\[\[\.\.\.([^\]]+)\]\]/g, (_, name) => {
|
|
240
|
+
const value = params[name];
|
|
241
|
+
if (value === undefined || value === '') return '';
|
|
242
|
+
if (Array.isArray(value)) return value.join('/');
|
|
243
|
+
return value;
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Catch-all: [...param]
|
|
247
|
+
resolved = resolved.replace(/\[\.\.\.([^\]]+)\]/g, (_, name) => {
|
|
248
|
+
const value = params[name];
|
|
249
|
+
if (value === undefined) return '';
|
|
250
|
+
if (Array.isArray(value)) return value.join('/');
|
|
251
|
+
return value;
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// Single dynamic: [param] — return null if a required param is missing
|
|
255
|
+
let missingRequired = false;
|
|
256
|
+
resolved = resolved.replace(/\[([^\]]+)\]/g, (match, name) => {
|
|
257
|
+
const value = params[name];
|
|
258
|
+
if (value === undefined) {
|
|
259
|
+
missingRequired = true;
|
|
260
|
+
return match; // keep original to avoid malformed URL
|
|
261
|
+
}
|
|
262
|
+
if (Array.isArray(value)) return value[0] ?? '';
|
|
263
|
+
return value;
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
if (missingRequired) return null;
|
|
267
|
+
|
|
268
|
+
// Clean up double slashes from empty optional catch-alls
|
|
269
|
+
resolved = resolved.replace(/\/+/g, '/');
|
|
270
|
+
|
|
271
|
+
// Remove trailing slash (except for root)
|
|
272
|
+
if (resolved.length > 1 && resolved.endsWith('/')) {
|
|
273
|
+
resolved = resolved.slice(0, -1);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return resolved;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// ─── Sitemap Generation ──────────────────────────────────────────────────────
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Generate the complete sitemap result from a route tree.
|
|
283
|
+
*
|
|
284
|
+
* Orchestrates tree walking, URL resolution, and XML serialization.
|
|
285
|
+
* Returns either a single sitemap or a paginated sitemap index.
|
|
286
|
+
*
|
|
287
|
+
* @param root - The root segment node from the route tree
|
|
288
|
+
* @param config - Sitemap configuration
|
|
289
|
+
* @param loadModule - Optional async function to load page modules (for generateStaticParams)
|
|
290
|
+
* @returns The sitemap result (single or index with pages)
|
|
291
|
+
*/
|
|
292
|
+
export async function generateSitemap(
|
|
293
|
+
root: SegmentNode,
|
|
294
|
+
config: SitemapConfig,
|
|
295
|
+
loadModule?: ModuleLoader
|
|
296
|
+
): Promise<SitemapResult> {
|
|
297
|
+
const routes = collectSitemapRoutes(root, config);
|
|
298
|
+
const entries = await resolveSitemapUrls(routes, config, loadModule);
|
|
299
|
+
|
|
300
|
+
if (entries.length <= URLS_PER_SITEMAP) {
|
|
301
|
+
// Single sitemap
|
|
302
|
+
return {
|
|
303
|
+
type: 'single',
|
|
304
|
+
xml: serializeSitemap(entries),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Paginated — split into chunks
|
|
309
|
+
const baseUrl = config.baseUrl.replace(/\/+$/, '');
|
|
310
|
+
const pageCount = Math.ceil(entries.length / URLS_PER_SITEMAP);
|
|
311
|
+
const pages = new Map<number, string>();
|
|
312
|
+
const sitemapUrls: string[] = [];
|
|
313
|
+
|
|
314
|
+
for (let i = 0; i < pageCount; i++) {
|
|
315
|
+
const start = i * URLS_PER_SITEMAP;
|
|
316
|
+
const end = Math.min(start + URLS_PER_SITEMAP, entries.length);
|
|
317
|
+
const chunk = entries.slice(start, end);
|
|
318
|
+
pages.set(i, serializeSitemap(chunk));
|
|
319
|
+
sitemapUrls.push(`${baseUrl}/sitemap/${i}.xml`);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
type: 'index',
|
|
324
|
+
indexXml: serializeSitemapIndex(sitemapUrls),
|
|
325
|
+
pages,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Check if the route tree root has a user-authored sitemap metadata route.
|
|
331
|
+
*
|
|
332
|
+
* When a user-authored sitemap exists at the root, auto-generation is disabled
|
|
333
|
+
* to avoid conflicts — the user takes full control.
|
|
334
|
+
*/
|
|
335
|
+
export function hasUserSitemap(root: SegmentNode): boolean {
|
|
336
|
+
if (!root.metadataRoutes) return false;
|
|
337
|
+
return root.metadataRoutes.has('sitemap');
|
|
338
|
+
}
|