@timber-js/app 0.2.0-alpha.12 → 0.2.0-alpha.121
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-Dy8vOjFt.js +1101 -0
- package/dist/_chunks/actions-Dy8vOjFt.js.map +1 -0
- package/dist/_chunks/build-output-helper-B1n0sUqj.js +61 -0
- package/dist/_chunks/build-output-helper-B1n0sUqj.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-ByZPGGmS.js +724 -0
- package/dist/_chunks/cli-schema-sync-ByZPGGmS.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-DHQLjFu3.js +2 -0
- package/dist/_chunks/codec-registry-G9hD5LOq.js +21 -0
- package/dist/_chunks/codec-registry-G9hD5LOq.js.map +1 -0
- package/dist/_chunks/define-CPVQaWbx.js +124 -0
- package/dist/_chunks/define-CPVQaWbx.js.map +1 -0
- package/dist/_chunks/define-jeHDXZGq.js +195 -0
- package/dist/_chunks/define-jeHDXZGq.js.map +1 -0
- package/dist/_chunks/format-BjN9HLu9.js +14 -0
- package/dist/_chunks/format-BjN9HLu9.js.map +1 -0
- package/dist/_chunks/handler-store-CcwNX-gk.js +54 -0
- package/dist/_chunks/handler-store-CcwNX-gk.js.map +1 -0
- package/dist/_chunks/logger-DDmK5skc.js +291 -0
- package/dist/_chunks/logger-DDmK5skc.js.map +1 -0
- package/dist/_chunks/merge-search-params-az6ZiBeU.js +41 -0
- package/dist/_chunks/merge-search-params-az6ZiBeU.js.map +1 -0
- package/dist/_chunks/navigation-root-DoRTeBm5.js +96 -0
- package/dist/_chunks/navigation-root-DoRTeBm5.js.map +1 -0
- package/dist/_chunks/registry-BI9cgCt7.js +20 -0
- package/dist/_chunks/registry-BI9cgCt7.js.map +1 -0
- package/dist/_chunks/resolve-schema-Bf8eC6q6.js +73 -0
- package/dist/_chunks/resolve-schema-Bf8eC6q6.js.map +1 -0
- package/dist/_chunks/router-ref-CpvjBqdu.js +28 -0
- package/dist/_chunks/router-ref-CpvjBqdu.js.map +1 -0
- package/dist/_chunks/schema-bridge-o0SwFtXW.js +86 -0
- package/dist/_chunks/schema-bridge-o0SwFtXW.js.map +1 -0
- package/dist/_chunks/segment-classify-CnfLLvir.js +137 -0
- package/dist/_chunks/segment-classify-CnfLLvir.js.map +1 -0
- package/dist/_chunks/segment-context-EsfQpS--.js +34 -0
- package/dist/_chunks/segment-context-EsfQpS--.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-m9-cNEIw.js} +1 -1
- package/dist/_chunks/ssr-data-m9-cNEIw.js.map +1 -0
- package/dist/_chunks/stale-reload-BN2kcE06.js +64 -0
- package/dist/_chunks/stale-reload-BN2kcE06.js.map +1 -0
- package/dist/_chunks/tracing-DvKLzCFa.js +329 -0
- package/dist/_chunks/tracing-DvKLzCFa.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-C9G6LP0F.js} +7 -20
- package/dist/_chunks/use-query-states-C9G6LP0F.js.map +1 -0
- package/dist/_chunks/use-segment-params-CtIAjqK0.js +185 -0
- package/dist/_chunks/use-segment-params-CtIAjqK0.js.map +1 -0
- package/dist/_chunks/validation-BMU5MPzP.js +84 -0
- package/dist/_chunks/validation-BMU5MPzP.js.map +1 -0
- package/dist/_chunks/walkers-DNp9tHyV.js +719 -0
- package/dist/_chunks/walkers-DNp9tHyV.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → warnings-B30wpfaS.js} +6 -45
- package/dist/_chunks/warnings-B30wpfaS.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +28 -0
- package/dist/adapters/build-output-helper.d.ts.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 +142 -38
- 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 +143 -45
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +16 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- 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 +151 -81
- 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-schema-sync.d.ts +37 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +14 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +42 -6
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +34 -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 +29 -6
- 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 +16 -27
- 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 -24
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +172 -1100
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +19 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +964 -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/state.d.ts +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-cookie.d.ts +12 -0
- package/dist/client/use-cookie.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-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/client/{use-params.d.ts → use-segment-params.d.ts} +8 -6
- package/dist/client/use-segment-params.d.ts.map +1 -0
- package/dist/codec.d.ts +69 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +75 -0
- package/dist/codec.js.map +1 -0
- package/dist/config-types.d.ts +294 -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 +58 -25
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +2 -1
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +251 -36
- package/dist/cookies/index.js.map +1 -1
- package/dist/cookies/json-cookie.d.ts +64 -0
- package/dist/cookies/json-cookie.d.ts.map +1 -0
- package/dist/cookies/validation.d.ts +46 -0
- package/dist/cookies/validation.d.ts.map +1 -0
- package/dist/dev-tools/404-page.d.ts +46 -0
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/dev-tools/browser-logs.d.ts +84 -0
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/dev-tools/error-page.d.ts +58 -0
- package/dist/dev-tools/error-page.d.ts.map +1 -0
- package/dist/dev-tools/holding-server.d.ts +54 -0
- package/dist/dev-tools/holding-server.d.ts.map +1 -0
- package/dist/dev-tools/index.d.ts +31 -0
- package/dist/dev-tools/index.d.ts.map +1 -0
- package/dist/{server/dev-span-processor.d.ts → dev-tools/instrumentation.d.ts} +26 -6
- package/dist/dev-tools/instrumentation.d.ts.map +1 -0
- package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
- package/dist/dev-tools/logger.d.ts.map +1 -0
- package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
- package/dist/dev-tools/logs.d.ts.map +1 -0
- package/dist/dev-tools/overlay.d.ts +91 -0
- package/dist/dev-tools/overlay.d.ts.map +1 -0
- package/dist/dev-tools/stack-classifier.d.ts +34 -0
- package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
- package/dist/dev-tools/terminal.d.ts +28 -0
- package/dist/dev-tools/terminal.d.ts.map +1 -0
- package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +2 -22
- package/dist/dev-tools/warnings.d.ts.map +1 -0
- package/dist/fonts/ast.d.ts +98 -6
- package/dist/fonts/ast.d.ts.map +1 -1
- package/dist/fonts/bundle.d.ts +48 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/local.d.ts +1 -1
- package/dist/fonts/pipeline.d.ts +167 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +78 -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 +94 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +46 -190
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4807 -12729
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +26 -0
- package/dist/params/codec-registry.d.ts.map +1 -0
- package/dist/params/define-schema.d.ts +81 -0
- package/dist/params/define-schema.d.ts.map +1 -0
- package/dist/params/index.d.ts +5 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +34 -0
- package/dist/params/index.js.map +1 -0
- package/dist/params/resolve-schema.d.ts +34 -0
- package/dist/params/resolve-schema.d.ts.map +1 -0
- 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 +9 -7
- 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-server.d.ts +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/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 +5 -26
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +63 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +60 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +7 -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 +7 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +4 -2
- package/dist/routing/link-codegen.d.ts +90 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts +1 -10
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/schema-validation.d.ts +35 -0
- package/dist/routing/schema-validation.d.ts.map +1 -0
- package/dist/routing/segment-classify.d.ts +75 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/segment-codegen.d.ts +38 -0
- package/dist/routing/segment-codegen.d.ts.map +1 -0
- package/dist/routing/types.d.ts +77 -25
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +51 -0
- package/dist/routing/walkers.d.ts.map +1 -0
- 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 +157 -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 +34 -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 +95 -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 +8 -3
- 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 +35 -1
- 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 +53 -5
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +1 -15
- package/dist/server/asset-headers.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/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/cookie-context.d.ts +170 -0
- package/dist/server/cookie-context.d.ts.map +1 -0
- package/dist/server/cookie-parsing.d.ts +51 -0
- package/dist/server/cookie-parsing.d.ts.map +1 -0
- 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-boundary.d.ts +90 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/early-hints-sender.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-injector-core.d.ts +213 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +81 -41
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +10 -46
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +155 -2905
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +48 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +2947 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +39 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +36 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +112 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/param-coercion.d.ts +54 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +95 -0
- package/dist/server/pipeline-helpers.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-outcome.d.ts +49 -0
- package/dist/server/pipeline-outcome.d.ts.map +1 -0
- package/dist/server/pipeline-phases.d.ts +52 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +118 -23
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/port-resolution.d.ts +117 -0
- package/dist/server/port-resolution.d.ts.map +1 -0
- 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 +62 -107
- 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 +21 -34
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
- 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 +49 -6
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +19 -8
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +50 -0
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
- 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 +17 -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/rsc-entry/wrap-action-dispatch.d.ts +119 -0
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
- 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 +30 -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/state-tree-diff.d.ts.map +1 -1
- package/dist/server/status-code-resolver.d.ts +16 -11
- 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 +5 -5
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +62 -30
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/tree-match.d.ts +41 -0
- package/dist/server/tree-match.d.ts.map +1 -0
- package/dist/server/types.d.ts +49 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/escape-html.d.ts +14 -0
- package/dist/server/utils/escape-html.d.ts.map +1 -0
- 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 +3 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +11 -5
- package/dist/shims/navigation.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 +62 -21
- package/src/adapters/build-output-helper.ts +77 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +142 -0
- package/src/adapters/cloudflare.ts +350 -76
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +142 -59
- package/src/adapters/shared.ts +40 -0
- 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 +33 -0
- package/src/cache/timber-cache.ts +25 -20
- package/src/cli-schema-sync.ts +207 -0
- package/src/cli.ts +65 -8
- package/src/client/browser-dev.ts +153 -1
- package/src/client/browser-entry/action-dispatch.ts +126 -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 +149 -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 +99 -22
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +31 -32
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +69 -44
- package/src/client/internal.ts +58 -0
- package/src/client/link-pending-store.ts +111 -0
- package/src/client/link.tsx +366 -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 +300 -73
- package/src/client/rsc-fetch.ts +112 -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/state.ts +2 -2
- package/src/client/top-loader.tsx +18 -6
- package/src/client/use-cookie.ts +31 -2
- package/src/client/use-link-status.ts +7 -7
- 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/client/{use-params.ts → use-segment-params.ts} +8 -6
- package/src/codec.ts +147 -0
- package/src/config-types.ts +292 -0
- package/src/config-validation.ts +303 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +233 -53
- package/src/cookies/index.ts +12 -1
- package/src/cookies/json-cookie.ts +105 -0
- package/src/cookies/validation.ts +134 -0
- package/src/dev-tools/404-page.ts +387 -0
- package/src/dev-tools/browser-logs.ts +291 -0
- package/src/dev-tools/error-page.ts +506 -0
- package/src/dev-tools/holding-server.ts +187 -0
- package/src/dev-tools/index.ts +90 -0
- package/src/dev-tools/instrumentation.ts +176 -0
- package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +9 -5
- package/src/dev-tools/overlay.ts +469 -0
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/dev-tools/terminal.ts +183 -0
- package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +5 -50
- package/src/fonts/ast.ts +525 -16
- package/src/fonts/bundle.ts +142 -0
- package/src/fonts/dev-middleware.ts +74 -0
- package/src/fonts/local.ts +1 -1
- package/src/fonts/pipeline.ts +314 -0
- package/src/fonts/transform.ts +317 -0
- package/src/fonts/types.ts +50 -1
- package/src/fonts/virtual-modules.ts +233 -0
- package/src/index.ts +409 -357
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +114 -0
- package/src/params/index.ts +17 -0
- package/src/params/resolve-schema.ts +101 -0
- package/src/plugin-context.ts +240 -0
- package/src/plugins/adapter-build.ts +12 -4
- package/src/plugins/build-manifest.ts +13 -2
- package/src/plugins/build-report.ts +16 -25
- package/src/plugins/client-chunks.ts +65 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-server.ts +175 -35
- package/src/plugins/entries.ts +111 -9
- package/src/plugins/fonts.ts +157 -654
- package/src/plugins/mdx.ts +47 -10
- package/src/plugins/routing.ts +371 -45
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +136 -35
- package/src/plugins/static-build.ts +15 -89
- package/src/routing/codegen-shared.ts +109 -0
- package/src/routing/codegen-types.ts +61 -0
- package/src/routing/codegen.ts +316 -177
- package/src/routing/convention-lint.ts +357 -0
- package/src/routing/index.ts +10 -1
- package/src/routing/interception.ts +1 -1
- package/src/routing/link-codegen.ts +308 -0
- package/src/routing/scanner.ts +165 -110
- package/src/routing/schema-validation.ts +149 -0
- package/src/routing/segment-classify.ts +188 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/types.ts +78 -25
- package/src/routing/walkers.ts +90 -0
- 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 +538 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +92 -0
- package/src/segment-params/define.ts +336 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +76 -34
- package/src/server/action-client.ts +88 -15
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +112 -14
- package/src/server/actions.ts +10 -9
- package/src/server/als-registry.ts +55 -7
- package/src/server/asset-headers.ts +8 -34
- package/src/server/build-manifest.ts +10 -4
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +25 -7
- package/src/server/cookie-context.ts +468 -0
- package/src/server/cookie-parsing.ts +135 -0
- package/src/server/debug.ts +1 -1
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-boundary.ts +218 -0
- package/src/server/deny-renderer.ts +31 -50
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +3 -2
- 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-injector-core.ts +417 -0
- package/src/server/html-injectors.ts +235 -223
- package/src/server/index.ts +29 -183
- package/src/server/internal.ts +176 -0
- package/src/server/logger.ts +67 -36
- package/src/server/middleware-runner.ts +75 -4
- package/src/server/node-stream-transforms.ts +361 -0
- package/src/server/param-coercion.ts +206 -0
- package/src/server/pipeline-helpers.ts +204 -0
- package/src/server/pipeline-interception.ts +17 -16
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline-outcome.ts +176 -0
- package/src/server/pipeline-phases.ts +460 -0
- package/src/server/pipeline.ts +154 -394
- package/src/server/port-resolution.ts +215 -0
- package/src/server/primitives.ts +111 -28
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +168 -333
- package/src/server/route-element-builder.ts +309 -195
- package/src/server/route-handler.ts +24 -4
- package/src/server/route-matcher.ts +50 -231
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +16 -17
- package/src/server/rsc-entry/error-renderer.ts +305 -89
- package/src/server/rsc-entry/helpers.ts +137 -12
- package/src/server/rsc-entry/index.ts +316 -352
- package/src/server/rsc-entry/render-route.ts +307 -0
- package/src/server/rsc-entry/rsc-payload.ts +65 -18
- package/src/server/rsc-entry/rsc-stream.ts +85 -13
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +187 -38
- package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
- 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 +228 -246
- package/src/server/ssr-entry.ts +229 -32
- package/src/server/ssr-render.ts +289 -67
- package/src/server/ssr-wrappers.tsx +139 -0
- package/src/server/state-tree-diff.ts +4 -1
- package/src/server/status-code-resolver.ts +112 -128
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +21 -10
- package/src/server/tree-builder.ts +202 -90
- package/src/server/tree-match.ts +198 -0
- package/src/server/types.ts +55 -6
- package/src/server/utils/escape-html.ts +20 -0
- 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 +4 -3
- package/src/shims/navigation.ts +14 -7
- package/src/utils/state-machine.ts +111 -0
- package/LICENSE +0 -8
- package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-gwlJkDuf.js +0 -108
- package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
- package/dist/_chunks/format-DviM89f0.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js +0 -676
- 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/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js +0 -187
- 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/client/use-params.d.ts.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/dev-error-overlay.d.ts +0 -60
- package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
- package/dist/plugins/dev-logs.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/plugins/server-action-exports.d.ts +0 -26
- package/dist/plugins/server-action-exports.d.ts.map +0 -1
- package/dist/routing/status-file-lint.d.ts +0 -33
- package/dist/routing/status-file-lint.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/dev-fetch-instrumentation.d.ts +0 -22
- package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
- package/dist/server/dev-logger.d.ts.map +0 -1
- package/dist/server/dev-span-processor.d.ts.map +0 -1
- package/dist/server/dev-warnings.d.ts.map +0 -1
- package/dist/server/manifest-status-resolver.d.ts +0 -58
- package/dist/server/manifest-status-resolver.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/dist/utils/directive-parser.d.ts +0 -70
- package/dist/utils/directive-parser.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/dev-error-overlay.ts +0 -230
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/plugins/server-action-exports.ts +0 -220
- package/src/routing/status-file-lint.ts +0 -112
- 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/dev-fetch-instrumentation.ts +0 -96
- package/src/server/dev-span-processor.ts +0 -78
- package/src/server/manifest-status-resolver.ts +0 -215
- package/src/server/prerender.ts +0 -139
- package/src/server/response-cache.ts +0 -410
- package/src/utils/directive-parser.ts +0 -529
- /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config validation — validates timber.config.ts at startup.
|
|
3
|
+
*
|
|
4
|
+
* Runs in the plugin's configResolved hook (once, at startup/build).
|
|
5
|
+
* Each check produces a clear error message with the invalid value,
|
|
6
|
+
* what's expected, and how to fix it.
|
|
7
|
+
*
|
|
8
|
+
* Design doc: 18-build-system.md
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { createRequire } from 'node:module';
|
|
12
|
+
import type { TimberUserConfig } from './config-types.js';
|
|
13
|
+
|
|
14
|
+
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
export interface ConfigError {
|
|
17
|
+
field: string;
|
|
18
|
+
message: string;
|
|
19
|
+
value?: unknown;
|
|
20
|
+
suggestion?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ─── Validation ─────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Validate a TimberUserConfig object.
|
|
27
|
+
*
|
|
28
|
+
* Returns an array of errors. Empty array means the config is valid.
|
|
29
|
+
* Does not throw — the caller decides how to surface errors.
|
|
30
|
+
*/
|
|
31
|
+
export function validateConfig(config: TimberUserConfig): ConfigError[] {
|
|
32
|
+
const errors: ConfigError[] = [];
|
|
33
|
+
|
|
34
|
+
// output
|
|
35
|
+
if (config.output !== undefined && config.output !== 'server' && config.output !== 'static') {
|
|
36
|
+
errors.push({
|
|
37
|
+
field: 'output',
|
|
38
|
+
message: `Invalid output mode: "${String(config.output)}". Must be "server" or "static".`,
|
|
39
|
+
value: config.output,
|
|
40
|
+
suggestion: 'Use output: "server" (default) or output: "static" for static site generation.',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// pageExtensions
|
|
45
|
+
if (config.pageExtensions !== undefined) {
|
|
46
|
+
if (!Array.isArray(config.pageExtensions)) {
|
|
47
|
+
errors.push({
|
|
48
|
+
field: 'pageExtensions',
|
|
49
|
+
message: 'pageExtensions must be an array of strings.',
|
|
50
|
+
value: config.pageExtensions,
|
|
51
|
+
suggestion: 'Example: pageExtensions: ["tsx", "ts", "jsx", "js", "mdx"]',
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
for (const ext of config.pageExtensions) {
|
|
55
|
+
if (typeof ext !== 'string') {
|
|
56
|
+
errors.push({
|
|
57
|
+
field: 'pageExtensions',
|
|
58
|
+
message: `pageExtensions contains a non-string value: ${JSON.stringify(ext)}`,
|
|
59
|
+
value: ext,
|
|
60
|
+
});
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (ext.startsWith('.')) {
|
|
64
|
+
errors.push({
|
|
65
|
+
field: 'pageExtensions',
|
|
66
|
+
message: `pageExtensions should not include the leading dot: "${ext}"`,
|
|
67
|
+
value: ext,
|
|
68
|
+
suggestion: `Use "${ext.slice(1)}" instead of "${ext}".`,
|
|
69
|
+
});
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// slowRequestMs
|
|
77
|
+
if (config.slowRequestMs !== undefined) {
|
|
78
|
+
if (typeof config.slowRequestMs !== 'number' || config.slowRequestMs < 0) {
|
|
79
|
+
errors.push({
|
|
80
|
+
field: 'slowRequestMs',
|
|
81
|
+
message: `slowRequestMs must be a non-negative number (got ${JSON.stringify(config.slowRequestMs)}).`,
|
|
82
|
+
value: config.slowRequestMs,
|
|
83
|
+
suggestion: 'Use slowRequestMs: 3000 (default) or slowRequestMs: 0 to disable.',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// renderTimeoutMs
|
|
89
|
+
if (config.renderTimeoutMs !== undefined) {
|
|
90
|
+
if (typeof config.renderTimeoutMs !== 'number' || config.renderTimeoutMs < 0) {
|
|
91
|
+
errors.push({
|
|
92
|
+
field: 'renderTimeoutMs',
|
|
93
|
+
message: `renderTimeoutMs must be a non-negative number (got ${JSON.stringify(config.renderTimeoutMs)}).`,
|
|
94
|
+
value: config.renderTimeoutMs,
|
|
95
|
+
suggestion: 'Use renderTimeoutMs: 30000 (default) or renderTimeoutMs: 0 to disable.',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// serverTiming
|
|
101
|
+
if (config.serverTiming !== undefined) {
|
|
102
|
+
if (
|
|
103
|
+
config.serverTiming !== 'detailed' &&
|
|
104
|
+
config.serverTiming !== 'total' &&
|
|
105
|
+
config.serverTiming !== false
|
|
106
|
+
) {
|
|
107
|
+
errors.push({
|
|
108
|
+
field: 'serverTiming',
|
|
109
|
+
message: `Invalid serverTiming value: ${JSON.stringify(config.serverTiming)}.`,
|
|
110
|
+
value: config.serverTiming,
|
|
111
|
+
suggestion: 'Use "detailed", "total", or false.',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// devBrowserLogs
|
|
117
|
+
if (config.devBrowserLogs !== undefined) {
|
|
118
|
+
const valid = ['error', 'warn', 'info', 'none'];
|
|
119
|
+
if (!valid.includes(config.devBrowserLogs)) {
|
|
120
|
+
errors.push({
|
|
121
|
+
field: 'devBrowserLogs',
|
|
122
|
+
message: `Invalid devBrowserLogs value: ${JSON.stringify(config.devBrowserLogs)}.`,
|
|
123
|
+
value: config.devBrowserLogs,
|
|
124
|
+
suggestion: `Use one of: ${valid.map((v) => `"${v}"`).join(', ')}.`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// sitemap
|
|
130
|
+
if (config.sitemap != null && typeof config.sitemap === 'object') {
|
|
131
|
+
if (config.sitemap.enabled && !config.sitemap.baseUrl) {
|
|
132
|
+
errors.push({
|
|
133
|
+
field: 'sitemap.baseUrl',
|
|
134
|
+
message: 'sitemap.baseUrl is required when sitemap is enabled.',
|
|
135
|
+
suggestion: 'Add sitemap: { enabled: true, baseUrl: "https://example.com" }.',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if (
|
|
139
|
+
config.sitemap.defaultPriority !== undefined &&
|
|
140
|
+
(config.sitemap.defaultPriority < 0 || config.sitemap.defaultPriority > 1)
|
|
141
|
+
) {
|
|
142
|
+
errors.push({
|
|
143
|
+
field: 'sitemap.defaultPriority',
|
|
144
|
+
message: `sitemap.defaultPriority must be between 0.0 and 1.0 (got ${config.sitemap.defaultPriority}).`,
|
|
145
|
+
value: config.sitemap.defaultPriority,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Unknown top-level keys
|
|
151
|
+
const knownKeys = new Set([
|
|
152
|
+
'output',
|
|
153
|
+
'debug',
|
|
154
|
+
'clientJavascript',
|
|
155
|
+
'adapter',
|
|
156
|
+
'cacheHandler',
|
|
157
|
+
'allowedOrigins',
|
|
158
|
+
'csrf',
|
|
159
|
+
'limits',
|
|
160
|
+
'pageExtensions',
|
|
161
|
+
'slowRequestMs',
|
|
162
|
+
'renderTimeoutMs',
|
|
163
|
+
'devBrowserLogs',
|
|
164
|
+
'dev',
|
|
165
|
+
'serverTiming',
|
|
166
|
+
'appDir',
|
|
167
|
+
'mdx',
|
|
168
|
+
'actionEncryption',
|
|
169
|
+
'reactCompiler',
|
|
170
|
+
'sitemap',
|
|
171
|
+
'buildDir',
|
|
172
|
+
'topLoader',
|
|
173
|
+
]);
|
|
174
|
+
|
|
175
|
+
for (const key of Object.keys(config)) {
|
|
176
|
+
if (!knownKeys.has(key)) {
|
|
177
|
+
errors.push({
|
|
178
|
+
field: key,
|
|
179
|
+
message: `Unknown config option: "${key}".`,
|
|
180
|
+
suggestion: `Check for typos. Known options: ${[...knownKeys].sort().join(', ')}.`,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return errors;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ─── Formatting ─────────────────────────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
const RED = '\x1b[31m';
|
|
191
|
+
const BOLD = '\x1b[1m';
|
|
192
|
+
const DIM = '\x1b[2m';
|
|
193
|
+
const RESET = '\x1b[0m';
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Format config errors for terminal output.
|
|
197
|
+
*/
|
|
198
|
+
export function formatConfigErrors(errors: ConfigError[]): string {
|
|
199
|
+
if (errors.length === 0) return '';
|
|
200
|
+
|
|
201
|
+
const lines: string[] = [];
|
|
202
|
+
lines.push(
|
|
203
|
+
`${RED}${BOLD}[timber]${RESET} ${RED}${errors.length} config error${errors.length !== 1 ? 's' : ''} in timber.config.ts:${RESET}`
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
for (const err of errors) {
|
|
207
|
+
lines.push('');
|
|
208
|
+
lines.push(` ${RED}✗${RESET} ${BOLD}${err.field}${RESET}: ${err.message}`);
|
|
209
|
+
if (err.suggestion) {
|
|
210
|
+
lines.push(` ${DIM}${err.suggestion}${RESET}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return lines.join('\n');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ─── Virtual Module Name Mapping ────────────────────────────────────────────
|
|
218
|
+
|
|
219
|
+
const VIRTUAL_MODULE_NAMES: Record<string, string> = {
|
|
220
|
+
'virtual:timber-rsc-entry': 'RSC entry (server component handler)',
|
|
221
|
+
'virtual:timber-ssr-entry': 'SSR entry (HTML renderer)',
|
|
222
|
+
'virtual:timber-browser-entry': 'Browser entry (client hydration)',
|
|
223
|
+
'virtual:timber-config': 'Runtime config (timber.config.ts)',
|
|
224
|
+
'virtual:timber-route-manifest': 'Route manifest (app/ file tree)',
|
|
225
|
+
'virtual:timber-instrumentation': 'Instrumentation (instrumentation.ts)',
|
|
226
|
+
'virtual:timber-cache-handler': 'Cache handler (cacheHandler config)',
|
|
227
|
+
'virtual:timber-build-manifest': 'Build manifest (asset mapping)',
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Add timber-specific context to an error message that references virtual modules.
|
|
232
|
+
*
|
|
233
|
+
* If the error message contains a `virtual:timber-*` ID, appends a
|
|
234
|
+
* human-readable explanation. Does not replace the original message.
|
|
235
|
+
*/
|
|
236
|
+
export function addVirtualModuleContext(errorMessage: string): string {
|
|
237
|
+
for (const [id, name] of Object.entries(VIRTUAL_MODULE_NAMES)) {
|
|
238
|
+
if (errorMessage.includes(id)) {
|
|
239
|
+
return `${errorMessage}\n\n [timber] This error references "${id}" — timber's ${name}.\n This is an internal module. The issue is likely in your app code or timber configuration.`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return errorMessage;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ─── Peer Dependency Check ──────────────────────────────────────────────────
|
|
246
|
+
|
|
247
|
+
interface PeerDepResult {
|
|
248
|
+
name: string;
|
|
249
|
+
status: 'ok' | 'missing';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Required (non-optional) peer dependencies that must be installed.
|
|
254
|
+
*/
|
|
255
|
+
const REQUIRED_PEERS = ['react', 'react-dom', '@vitejs/plugin-react', '@vitejs/plugin-rsc'];
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Check that required peer dependencies are installed.
|
|
259
|
+
*
|
|
260
|
+
* Uses require.resolve with a try/catch — no fs scanning.
|
|
261
|
+
* Returns only the missing packages.
|
|
262
|
+
*/
|
|
263
|
+
export function checkPeerDependencies(projectRoot: string): PeerDepResult[] {
|
|
264
|
+
const results: PeerDepResult[] = [];
|
|
265
|
+
|
|
266
|
+
// Use createRequire from the project root to resolve as the user would.
|
|
267
|
+
// `createRequire` MUST be a top-level ESM import — inline `require('node:module')`
|
|
268
|
+
// throws "Dynamic require not supported" in ESM and the catch below would
|
|
269
|
+
// mark every peer as missing. Same class of bug as TIM-796.
|
|
270
|
+
const userRequire = createRequire(`${projectRoot}/package.json`);
|
|
271
|
+
|
|
272
|
+
for (const name of REQUIRED_PEERS) {
|
|
273
|
+
try {
|
|
274
|
+
userRequire.resolve(name);
|
|
275
|
+
results.push({ name, status: 'ok' });
|
|
276
|
+
} catch {
|
|
277
|
+
results.push({ name, status: 'missing' });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return results;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Format missing peer dependencies as an actionable warning.
|
|
286
|
+
*/
|
|
287
|
+
export function formatMissingPeers(results: PeerDepResult[]): string {
|
|
288
|
+
const missing = results.filter((r) => r.status === 'missing');
|
|
289
|
+
if (missing.length === 0) return '';
|
|
290
|
+
|
|
291
|
+
const names = missing.map((r) => r.name);
|
|
292
|
+
const lines: string[] = [];
|
|
293
|
+
lines.push(`${RED}${BOLD}[timber]${RESET} ${RED}Missing required dependencies:${RESET}`);
|
|
294
|
+
lines.push('');
|
|
295
|
+
for (const name of names) {
|
|
296
|
+
lines.push(` ${RED}✗${RESET} ${name}`);
|
|
297
|
+
}
|
|
298
|
+
lines.push('');
|
|
299
|
+
lines.push(` ${DIM}Install with:${RESET}`);
|
|
300
|
+
lines.push(` ${BOLD}pnpm add ${names.join(' ')}${RESET}`);
|
|
301
|
+
|
|
302
|
+
return lines.join('\n');
|
|
303
|
+
}
|
package/src/content/index.ts
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* or use this module for the re-exports.
|
|
7
|
-
*
|
|
8
|
-
* Design doc: 20-content-collections.md §"Querying Collections"
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
// Re-export defineCollection and defineConfig for convenience.
|
|
12
|
-
// Users can also import these directly from @content-collections/core.
|
|
13
|
-
export { defineCollection, defineConfig } from '@content-collections/core';
|
|
1
|
+
// @timber-js/app/content entry point removed per TIM-722.
|
|
2
|
+
//
|
|
3
|
+
// Import defineCollection and defineConfig directly from @content-collections/core.
|
|
4
|
+
// This file is kept for the content plugin which uses other files in this directory.
|
|
5
|
+
export {};
|
|
@@ -2,58 +2,170 @@
|
|
|
2
2
|
* defineCookie — typed cookie definitions.
|
|
3
3
|
*
|
|
4
4
|
* Bundles name + codec + options into a reusable CookieDefinition<T>
|
|
5
|
-
* with .get(), .set(), .delete()
|
|
5
|
+
* with sync .get(), .set(), .delete() isomorphic methods (server + client)
|
|
6
|
+
* and a .useCookie() client hook.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* Environment detection is call-time: on the server, getCookieJar() is
|
|
9
|
+
* used directly (ALS-backed). On the client, document.cookie helpers
|
|
10
|
+
* and the useCookie hook are used. No registration pattern — imports
|
|
11
|
+
* resolve via the shims plugin (client bundle gets a stub for
|
|
12
|
+
* @timber-js/app/server).
|
|
13
|
+
*
|
|
14
|
+
* Standard Schema objects (Zod, Valibot, ArkType) are auto-detected in
|
|
15
|
+
* the codec option — no explicit fromSchema() wrapper needed.
|
|
9
16
|
*
|
|
10
17
|
* See design/29-cookies.md §"Typed Cookies with Schema Validation"
|
|
11
18
|
*/
|
|
12
19
|
|
|
13
|
-
import {
|
|
14
|
-
import type {
|
|
15
|
-
import { useCookie as useRawCookie } from '#/client/use-cookie.js';
|
|
16
|
-
import type { ClientCookieOptions } from '#/client/use-cookie.js';
|
|
20
|
+
import type { CookieOptions } from '../server/cookie-context.js';
|
|
21
|
+
import type { ClientCookieOptions } from '../client/use-cookie.js';
|
|
17
22
|
|
|
18
23
|
// ─── Types ────────────────────────────────────────────────────────────────
|
|
19
24
|
|
|
25
|
+
import type { Codec } from '../codec.js';
|
|
26
|
+
import type { StandardSchemaV1 } from '../schema-bridge.js';
|
|
27
|
+
|
|
20
28
|
/**
|
|
21
29
|
* A codec that converts between string cookie values and typed values.
|
|
22
|
-
*
|
|
30
|
+
* Type alias for the shared Codec<T> protocol.
|
|
23
31
|
*/
|
|
24
|
-
export
|
|
25
|
-
parse(value: string | string[] | undefined): T;
|
|
26
|
-
serialize(value: T): string | null;
|
|
27
|
-
}
|
|
32
|
+
export type CookieCodec<T> = Codec<T>;
|
|
28
33
|
|
|
29
34
|
/** Options for defineCookie: codec + CookieOptions merged. */
|
|
30
|
-
export interface DefineCookieOptions<T> extends
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
export interface DefineCookieOptions<T, HttpOnly extends boolean = boolean> extends CookieOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Codec for parsing/serializing the cookie value.
|
|
38
|
+
* Accepts a Codec<T> or a Standard Schema object (Zod, Valibot, ArkType)
|
|
39
|
+
* which is auto-wrapped via fromSchema.
|
|
40
|
+
*/
|
|
41
|
+
codec: CookieCodec<T> | StandardSchemaV1<T>;
|
|
42
|
+
/**
|
|
43
|
+
* Prevent client-side JS access. Default: true.
|
|
44
|
+
* When true (or omitted), client methods (useCookie, get/set/delete on
|
|
45
|
+
* client) are omitted from the return type and throw at runtime.
|
|
46
|
+
*/
|
|
47
|
+
httpOnly?: HttpOnly;
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Server-only cookie definition. Returned when httpOnly is true or omitted.
|
|
52
|
+
* Client methods are absent from the type — accessing them is a TS error.
|
|
53
|
+
*/
|
|
54
|
+
export interface ServerOnlyCookieDefinition<T> {
|
|
40
55
|
readonly name: string;
|
|
41
|
-
/** The resolved cookie options (without codec). */
|
|
42
56
|
readonly options: CookieOptions;
|
|
43
|
-
/** The codec used for parsing/serializing. */
|
|
44
57
|
readonly codec: CookieCodec<T>;
|
|
45
58
|
|
|
46
|
-
/**
|
|
59
|
+
/** Read the typed value. Sync, isomorphic (server + client). */
|
|
47
60
|
get(): T;
|
|
48
|
-
/**
|
|
61
|
+
/** Set the typed value. Sync, isomorphic (server + client). */
|
|
49
62
|
set(value: T): void;
|
|
50
|
-
/**
|
|
63
|
+
/** Delete the cookie. Sync, isomorphic (server + client). */
|
|
51
64
|
delete(): void;
|
|
65
|
+
}
|
|
52
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Full cookie definition with client methods. Returned when httpOnly: false.
|
|
69
|
+
*/
|
|
70
|
+
export interface CookieDefinition<T> extends ServerOnlyCookieDefinition<T> {
|
|
53
71
|
/** Client: React hook for reading/writing this cookie. Returns [value, setter, deleter]. */
|
|
54
72
|
useCookie(): [T, (value: T) => void, () => void];
|
|
55
73
|
}
|
|
56
74
|
|
|
75
|
+
// ─── Direct Imports (no registration) ─────────────────────────────────────
|
|
76
|
+
//
|
|
77
|
+
// Server: getCookieJar is imported from @timber-js/app/server. In the client
|
|
78
|
+
// bundle, the shims plugin replaces @timber-js/app/server with a stub module
|
|
79
|
+
// where getCookieJar throws on call. We detect the environment at call time
|
|
80
|
+
// by trying getCookieJar() — if it throws the stub error, we fall through
|
|
81
|
+
// to the client path.
|
|
82
|
+
//
|
|
83
|
+
// Client: useCookie, getCookieValue, notifyCookieChange
|
|
84
|
+
// are imported from use-cookie.ts. These are safe in all environments (no
|
|
85
|
+
// node:async_hooks dependency).
|
|
86
|
+
//
|
|
87
|
+
// Schema: fromSchema is a pure function — safe in all environments.
|
|
88
|
+
|
|
89
|
+
import { getCookieJar } from '@timber-js/app/server';
|
|
90
|
+
import { fromSchema } from '../schema-bridge.js';
|
|
91
|
+
import {
|
|
92
|
+
useCookie as useRawCookie,
|
|
93
|
+
notifyCookieChange,
|
|
94
|
+
getCookieValue,
|
|
95
|
+
} from '../client/use-cookie.js';
|
|
96
|
+
|
|
97
|
+
// ─── Environment Detection ────────────────────────────────────────────────
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Try to get the server cookie jar. Returns null if we're in the client
|
|
101
|
+
* environment (stub throws) or if there's no request context.
|
|
102
|
+
*
|
|
103
|
+
* On the server, getCookieJar() throws "outside of a request context" if
|
|
104
|
+
* called without an ALS store — this is a real error and is re-thrown.
|
|
105
|
+
* The client stub throws a different message — that's caught and returns null.
|
|
106
|
+
*/
|
|
107
|
+
function tryGetServerCookieJar(): ReturnType<typeof getCookieJar> | null {
|
|
108
|
+
try {
|
|
109
|
+
return getCookieJar();
|
|
110
|
+
} catch (e) {
|
|
111
|
+
// Server-side "no request context" error — re-throw as a real bug.
|
|
112
|
+
if (e instanceof Error && e.message.includes('outside of a request context')) {
|
|
113
|
+
throw e;
|
|
114
|
+
}
|
|
115
|
+
// Client stub error or other — fall through to client path.
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ─── Client Cookie Helpers ────────────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
/** Write a cookie via document.cookie and notify useCookie subscribers. */
|
|
123
|
+
function setClientCookie(name: string, value: string, options?: ClientCookieOptions): void {
|
|
124
|
+
const parts: string[] = [`${name}=${encodeURIComponent(value)}`];
|
|
125
|
+
const path = options?.path ?? '/';
|
|
126
|
+
parts.push(`Path=${path}`);
|
|
127
|
+
if (options?.domain) parts.push(`Domain=${options.domain}`);
|
|
128
|
+
if (options?.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);
|
|
129
|
+
if (options?.expires) parts.push(`Expires=${options.expires.toUTCString()}`);
|
|
130
|
+
const sameSite = options?.sameSite ?? 'lax';
|
|
131
|
+
parts.push(`SameSite=${sameSite.charAt(0).toUpperCase()}${sameSite.slice(1)}`);
|
|
132
|
+
if (options?.secure) parts.push('Secure');
|
|
133
|
+
document.cookie = parts.join('; ');
|
|
134
|
+
notifyCookieChange(name);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Delete a cookie via document.cookie and notify useCookie subscribers. */
|
|
138
|
+
function deleteClientCookie(name: string, options?: ClientCookieOptions): void {
|
|
139
|
+
const path = options?.path ?? '/';
|
|
140
|
+
const domain = options?.domain;
|
|
141
|
+
let cookieStr = `${name}=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=${path}`;
|
|
142
|
+
if (domain) cookieStr += `; Domain=${domain}`;
|
|
143
|
+
document.cookie = cookieStr;
|
|
144
|
+
notifyCookieChange(name);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ─── Standard Schema Auto-Detection ───────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
function resolveCodec<T>(codecOrSchema: CookieCodec<T> | StandardSchemaV1<T>): CookieCodec<T> {
|
|
150
|
+
// If it has parse + serialize, it's already a Codec
|
|
151
|
+
if (
|
|
152
|
+
typeof (codecOrSchema as Codec<T>).parse === 'function' &&
|
|
153
|
+
typeof (codecOrSchema as Codec<T>).serialize === 'function'
|
|
154
|
+
) {
|
|
155
|
+
return codecOrSchema as CookieCodec<T>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Auto-detect Standard Schema
|
|
159
|
+
if (typeof codecOrSchema === 'object' && codecOrSchema !== null && '~standard' in codecOrSchema) {
|
|
160
|
+
return fromSchema(codecOrSchema as StandardSchemaV1<unknown>) as CookieCodec<T>;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw new Error(
|
|
164
|
+
'[timber] defineCookie: codec must be a Codec<T> (with parse/serialize methods) ' +
|
|
165
|
+
'or a Standard Schema object (Zod, Valibot, ArkType).'
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
57
169
|
// ─── Factory ──────────────────────────────────────────────────────────────
|
|
58
170
|
|
|
59
171
|
/**
|
|
@@ -61,64 +173,130 @@ export interface CookieDefinition<T> {
|
|
|
61
173
|
*
|
|
62
174
|
* ```ts
|
|
63
175
|
* import { defineCookie } from '@timber-js/app/cookies';
|
|
64
|
-
* import { fromSchema } from '@timber-js/app/search-params';
|
|
65
176
|
* import { z } from 'zod/v4';
|
|
66
177
|
*
|
|
178
|
+
* // httpOnly: false — client methods available
|
|
67
179
|
* export const themeCookie = defineCookie('theme', {
|
|
68
|
-
* codec:
|
|
180
|
+
* codec: z.enum(['light', 'dark', 'system']).default('system'),
|
|
69
181
|
* httpOnly: false,
|
|
70
182
|
* maxAge: 60 * 60 * 24 * 365,
|
|
71
183
|
* });
|
|
184
|
+
*
|
|
185
|
+
* // Server or client
|
|
186
|
+
* const theme = themeCookie.get();
|
|
187
|
+
* themeCookie.set('dark');
|
|
188
|
+
*
|
|
189
|
+
* // Client hook
|
|
190
|
+
* const [theme, setTheme] = themeCookie.useCookie();
|
|
191
|
+
*
|
|
192
|
+
* // httpOnly: true (default) — server-only, no client methods
|
|
193
|
+
* export const sessionCookie = defineCookie('session', {
|
|
194
|
+
* codec: z.string(),
|
|
195
|
+
* });
|
|
196
|
+
* sessionCookie.get(); // works on server
|
|
197
|
+
* sessionCookie.useCookie(); // TS error — httpOnly cookie
|
|
72
198
|
* ```
|
|
73
199
|
*/
|
|
74
|
-
export function defineCookie<T>(
|
|
200
|
+
export function defineCookie<T, HttpOnly extends boolean = true>(
|
|
75
201
|
name: string,
|
|
76
|
-
options: DefineCookieOptions<T>
|
|
77
|
-
): CookieDefinition<T> {
|
|
78
|
-
const { codec, ...cookieOpts } = options;
|
|
202
|
+
options: DefineCookieOptions<T, HttpOnly>
|
|
203
|
+
): HttpOnly extends false ? CookieDefinition<T> : ServerOnlyCookieDefinition<T> {
|
|
204
|
+
const { codec: codecOrSchema, ...cookieOpts } = options;
|
|
205
|
+
const codec = resolveCodec(codecOrSchema);
|
|
79
206
|
const resolvedOptions: CookieOptions = { ...cookieOpts };
|
|
207
|
+
const isHttpOnly = options.httpOnly !== false; // default true
|
|
208
|
+
|
|
209
|
+
function getClientOpts(): ClientCookieOptions {
|
|
210
|
+
return {
|
|
211
|
+
path: resolvedOptions.path,
|
|
212
|
+
domain: resolvedOptions.domain,
|
|
213
|
+
maxAge: resolvedOptions.maxAge,
|
|
214
|
+
expires: resolvedOptions.expires,
|
|
215
|
+
sameSite: resolvedOptions.sameSite,
|
|
216
|
+
secure: resolvedOptions.secure,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
80
219
|
|
|
81
|
-
|
|
220
|
+
const base: ServerOnlyCookieDefinition<T> = {
|
|
82
221
|
name,
|
|
83
222
|
options: resolvedOptions,
|
|
84
223
|
codec,
|
|
85
224
|
|
|
86
225
|
get(): T {
|
|
87
|
-
const
|
|
88
|
-
|
|
226
|
+
const serverJar = tryGetServerCookieJar();
|
|
227
|
+
if (serverJar) {
|
|
228
|
+
return codec.parse(serverJar.get(name));
|
|
229
|
+
}
|
|
230
|
+
// Client path
|
|
231
|
+
if (isHttpOnly) {
|
|
232
|
+
throw new Error(
|
|
233
|
+
`[timber] defineCookie('${name}').get() cannot be used with httpOnly cookies — ` +
|
|
234
|
+
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
const raw = getCookieValue(name);
|
|
89
238
|
return codec.parse(raw);
|
|
90
239
|
},
|
|
91
240
|
|
|
92
241
|
set(value: T): void {
|
|
242
|
+
const serverJar = tryGetServerCookieJar();
|
|
243
|
+
if (serverJar) {
|
|
244
|
+
const serialized = codec.serialize(value);
|
|
245
|
+
if (serialized === null) {
|
|
246
|
+
serverJar.delete(name, {
|
|
247
|
+
path: resolvedOptions.path,
|
|
248
|
+
domain: resolvedOptions.domain,
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
serverJar.set(name, serialized, resolvedOptions);
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
// Client path
|
|
256
|
+
if (isHttpOnly) {
|
|
257
|
+
throw new Error(
|
|
258
|
+
`[timber] defineCookie('${name}').set() cannot be used with httpOnly cookies — ` +
|
|
259
|
+
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
93
262
|
const serialized = codec.serialize(value);
|
|
94
263
|
if (serialized === null) {
|
|
95
|
-
|
|
96
|
-
path: resolvedOptions.path,
|
|
97
|
-
domain: resolvedOptions.domain,
|
|
98
|
-
});
|
|
264
|
+
deleteClientCookie(name, getClientOpts());
|
|
99
265
|
} else {
|
|
100
|
-
|
|
266
|
+
setClientCookie(name, serialized, getClientOpts());
|
|
101
267
|
}
|
|
102
268
|
},
|
|
103
269
|
|
|
104
270
|
delete(): void {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
271
|
+
const serverJar = tryGetServerCookieJar();
|
|
272
|
+
if (serverJar) {
|
|
273
|
+
serverJar.delete(name, {
|
|
274
|
+
path: resolvedOptions.path,
|
|
275
|
+
domain: resolvedOptions.domain,
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
// Client path
|
|
280
|
+
if (isHttpOnly) {
|
|
281
|
+
throw new Error(
|
|
282
|
+
`[timber] defineCookie('${name}').delete() cannot be used with httpOnly cookies — ` +
|
|
283
|
+
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
deleteClientCookie(name, getClientOpts());
|
|
109
287
|
},
|
|
288
|
+
};
|
|
110
289
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
path: resolvedOptions.path,
|
|
115
|
-
domain: resolvedOptions.domain,
|
|
116
|
-
maxAge: resolvedOptions.maxAge,
|
|
117
|
-
expires: resolvedOptions.expires,
|
|
118
|
-
sameSite: resolvedOptions.sameSite,
|
|
119
|
-
secure: resolvedOptions.secure,
|
|
120
|
-
};
|
|
290
|
+
if (isHttpOnly) {
|
|
291
|
+
return base as HttpOnly extends false ? CookieDefinition<T> : ServerOnlyCookieDefinition<T>;
|
|
292
|
+
}
|
|
121
293
|
|
|
294
|
+
// httpOnly: false — add useCookie client hook
|
|
295
|
+
const full: CookieDefinition<T> = {
|
|
296
|
+
...base,
|
|
297
|
+
|
|
298
|
+
useCookie(): [T, (value: T) => void, () => void] {
|
|
299
|
+
const clientOpts = getClientOpts();
|
|
122
300
|
const [raw, setRaw, deleteRaw] = useRawCookie(name, clientOpts);
|
|
123
301
|
const parsed = codec.parse(raw);
|
|
124
302
|
|
|
@@ -134,4 +312,6 @@ export function defineCookie<T>(
|
|
|
134
312
|
return [parsed, setTyped, deleteRaw];
|
|
135
313
|
},
|
|
136
314
|
};
|
|
315
|
+
|
|
316
|
+
return full as HttpOnly extends false ? CookieDefinition<T> : ServerOnlyCookieDefinition<T>;
|
|
137
317
|
}
|