@timber-js/app 0.2.0-alpha.97 → 0.2.0-alpha.99
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-CQ8Z8VGL.js +1061 -0
- package/dist/_chunks/actions-CQ8Z8VGL.js.map +1 -0
- package/dist/_chunks/build-output-helper-DXnW0qjz.js +61 -0
- package/dist/_chunks/build-output-helper-DXnW0qjz.js.map +1 -0
- package/dist/_chunks/{define-Itxvcd7F.js → define-B-Q_UMOD.js} +19 -23
- package/dist/_chunks/define-B-Q_UMOD.js.map +1 -0
- package/dist/_chunks/{define-C77ScO0m.js → define-CfBPoJb0.js} +24 -7
- package/dist/_chunks/define-CfBPoJb0.js.map +1 -0
- package/dist/_chunks/define-cookie-BjpIt4UC.js +194 -0
- package/dist/_chunks/define-cookie-BjpIt4UC.js.map +1 -0
- package/dist/_chunks/{format-CYBGxKtc.js → format-Bcn-Iv1x.js} +1 -1
- package/dist/_chunks/{format-CYBGxKtc.js.map → format-Bcn-Iv1x.js.map} +1 -1
- package/dist/_chunks/handler-store-B-lqaGyh.js +54 -0
- package/dist/_chunks/handler-store-B-lqaGyh.js.map +1 -0
- package/dist/_chunks/logger-0m8MsKdc.js +291 -0
- package/dist/_chunks/logger-0m8MsKdc.js.map +1 -0
- package/dist/_chunks/merge-search-params-BphMdht_.js +122 -0
- package/dist/_chunks/merge-search-params-BphMdht_.js.map +1 -0
- package/dist/_chunks/{metadata-routes-DS3eKNmf.js → metadata-routes-BU684ls2.js} +1 -1
- package/dist/_chunks/{metadata-routes-DS3eKNmf.js.map → metadata-routes-BU684ls2.js.map} +1 -1
- package/dist/_chunks/navigation-root-BCYczjml.js +96 -0
- package/dist/_chunks/navigation-root-BCYczjml.js.map +1 -0
- package/dist/_chunks/registry-I2ss-lvy.js +20 -0
- package/dist/_chunks/registry-I2ss-lvy.js.map +1 -0
- package/dist/_chunks/router-ref-h3-UaCQv.js +28 -0
- package/dist/_chunks/router-ref-h3-UaCQv.js.map +1 -0
- package/dist/_chunks/{schema-bridge-C3xl_vfb.js → schema-bridge-Cxu4l-7p.js} +1 -1
- package/dist/_chunks/{schema-bridge-C3xl_vfb.js.map → schema-bridge-Cxu4l-7p.js.map} +1 -1
- package/dist/_chunks/segment-classify-BjfuctV2.js +137 -0
- package/dist/_chunks/segment-classify-BjfuctV2.js.map +1 -0
- package/dist/_chunks/{segment-context-fHFLF1PE.js → segment-context-Dx_OizxD.js} +1 -1
- package/dist/_chunks/{segment-context-fHFLF1PE.js.map → segment-context-Dx_OizxD.js.map} +1 -1
- package/dist/_chunks/{router-ref-C8OCm7g7.js → ssr-data-B4CdH7rE.js} +2 -26
- package/dist/_chunks/ssr-data-B4CdH7rE.js.map +1 -0
- package/dist/_chunks/{stale-reload-BX5gL1r-.js → stale-reload-Bab885FO.js} +1 -1
- package/dist/_chunks/{stale-reload-BX5gL1r-.js.map → stale-reload-Bab885FO.js.map} +1 -1
- package/dist/_chunks/tracing-C8V-YGsP.js +329 -0
- package/dist/_chunks/tracing-C8V-YGsP.js.map +1 -0
- package/dist/_chunks/{use-query-states-BiV5GJgm.js → use-query-states-B2XTqxDR.js} +3 -19
- package/dist/_chunks/use-query-states-B2XTqxDR.js.map +1 -0
- package/dist/_chunks/{use-params-IOPu7E8t.js → use-segment-params-BkpKAQ7D.js} +9 -95
- package/dist/_chunks/use-segment-params-BkpKAQ7D.js.map +1 -0
- package/dist/_chunks/{interception-BbqMCVXa.js → walkers-Tg0Alwcg.js} +66 -87
- package/dist/_chunks/walkers-Tg0Alwcg.js.map +1 -0
- package/dist/_chunks/{dev-warnings-DpGRGoDi.js → warnings-Cg47l5sk.js} +3 -3
- package/dist/_chunks/warnings-Cg47l5sk.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.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +8 -28
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +63 -31
- 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/index.js +9 -2
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/client/error-boundary.js +2 -1
- package/dist/client/error-boundary.js.map +1 -1
- package/dist/client/form.d.ts +10 -24
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/index.d.ts +1 -5
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +41 -91
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +2 -1
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +81 -7
- package/dist/client/internal.js.map +1 -1
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/state.d.ts +1 -1
- package/dist/client/use-cookie.d.ts +8 -0
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +1 -1
- package/dist/client/use-segment-params.d.ts.map +1 -0
- package/dist/codec.d.ts +1 -1
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +2 -2
- package/dist/config-types.d.ts +28 -0
- package/dist/config-types.d.ts.map +1 -1
- package/dist/cookies/define-cookie.d.ts +87 -35
- 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 +48 -2
- package/dist/cookies/index.js.map +1 -0
- 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/{plugins/dev-404-page.d.ts → dev-tools/404-page.d.ts} +9 -19
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/{plugins/dev-browser-logs.d.ts → dev-tools/browser-logs.d.ts} +1 -1
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/{plugins/dev-error-page.d.ts → dev-tools/error-page.d.ts} +2 -2
- package/dist/dev-tools/error-page.d.ts.map +1 -0
- package/dist/{server/dev-holding-server.d.ts → dev-tools/holding-server.d.ts} +5 -3
- 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} +1 -1
- package/dist/dev-tools/logs.d.ts.map +1 -0
- package/dist/{plugins/dev-error-overlay.d.ts → dev-tools/overlay.d.ts} +3 -12
- 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/{plugins/dev-terminal-error.d.ts → dev-tools/terminal.d.ts} +2 -2
- package/dist/dev-tools/terminal.d.ts.map +1 -0
- package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +1 -1
- package/dist/dev-tools/warnings.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +285 -133
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +1 -1
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +6 -4
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/routing/convention-lint.d.ts.map +1 -1
- package/dist/routing/index.d.ts +5 -3
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +3 -3
- package/dist/routing/scanner.d.ts +1 -10
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/segment-classify.d.ts +37 -8
- package/dist/routing/segment-classify.d.ts.map +1 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- package/dist/routing/types.d.ts +63 -23
- 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/search-params/define.d.ts +25 -7
- package/dist/search-params/define.d.ts.map +1 -1
- package/dist/search-params/index.js +5 -3
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/wrappers.d.ts +2 -2
- package/dist/search-params/wrappers.d.ts.map +1 -1
- package/dist/segment-params/define.d.ts +23 -6
- package/dist/segment-params/define.d.ts.map +1 -1
- package/dist/segment-params/index.js +1 -1
- package/dist/server/access-gate.d.ts +4 -3
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +15 -6
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +5 -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/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/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/early-hints-sender.d.ts.map +1 -1
- package/dist/server/html-injector-core.d.ts +212 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +59 -59
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -4
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +4 -149
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +6 -4
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +852 -852
- package/dist/server/internal.js.map +1 -1
- package/dist/server/logger.d.ts +14 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +17 -0
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +46 -49
- package/dist/server/node-stream-transforms.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +26 -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-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 +51 -32
- 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/request-context.d.ts +22 -159
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +20 -47
- 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/helpers.d.ts +1 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- 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/wrap-action-dispatch.d.ts +119 -0
- package/dist/server/rsc-entry/wrap-action-dispatch.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/tracing.d.ts +1 -1
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +45 -16
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +48 -0
- 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/shims/headers.d.ts +2 -2
- 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 +9 -4
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/directive-parser.d.ts +0 -45
- package/dist/utils/directive-parser.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/adapters/build-output-helper.ts +77 -0
- package/src/adapters/cloudflare.ts +10 -50
- package/src/adapters/nitro.ts +66 -50
- package/src/adapters/shared.ts +40 -0
- package/src/cache/timber-cache.ts +3 -2
- package/src/client/form.tsx +17 -25
- package/src/client/index.ts +16 -9
- package/src/client/internal.ts +3 -2
- package/src/client/router.ts +1 -1
- package/src/client/rsc-fetch.ts +15 -0
- package/src/client/state.ts +2 -2
- package/src/client/use-cookie.ts +29 -0
- package/src/codec.ts +3 -7
- package/src/config-types.ts +28 -0
- package/src/cookies/define-cookie.ts +271 -78
- package/src/cookies/index.ts +11 -8
- package/src/cookies/json-cookie.ts +105 -0
- package/src/cookies/validation.ts +134 -0
- package/src/{plugins/dev-404-page.ts → dev-tools/404-page.ts} +17 -48
- package/src/{plugins/dev-error-page.ts → dev-tools/error-page.ts} +5 -32
- package/src/{server/dev-holding-server.ts → dev-tools/holding-server.ts} +4 -2
- 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} +2 -2
- package/src/{plugins/dev-error-overlay.ts → dev-tools/overlay.ts} +5 -23
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/{plugins/dev-terminal-error.ts → dev-tools/terminal.ts} +4 -38
- package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +1 -1
- package/src/index.ts +95 -34
- package/src/plugin-context.ts +1 -1
- package/src/plugins/adapter-build.ts +3 -1
- package/src/plugins/build-report.ts +13 -22
- package/src/plugins/dev-server.ts +3 -3
- package/src/plugins/routing.ts +14 -12
- package/src/plugins/shims.ts +1 -1
- package/src/plugins/static-build.ts +1 -1
- package/src/routing/codegen.ts +1 -1
- package/src/routing/convention-lint.ts +9 -8
- package/src/routing/index.ts +5 -3
- package/src/routing/interception.ts +1 -1
- package/src/routing/scanner.ts +22 -95
- package/src/routing/segment-classify.ts +107 -8
- package/src/routing/status-file-lint.ts +7 -5
- package/src/routing/types.ts +63 -23
- package/src/routing/walkers.ts +90 -0
- package/src/search-params/define.ts +71 -15
- package/src/search-params/wrappers.ts +9 -2
- package/src/segment-params/define.ts +66 -13
- package/src/server/access-gate.tsx +9 -8
- package/src/server/action-handler.ts +34 -38
- package/src/server/als-registry.ts +5 -5
- package/src/server/asset-headers.ts +8 -34
- package/src/server/cookie-context.ts +468 -0
- package/src/server/cookie-parsing.ts +135 -0
- package/src/server/{deny-page-resolver.ts → deny-boundary.ts} +78 -14
- package/src/server/deny-renderer.ts +7 -12
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/fallback-error.ts +2 -2
- package/src/server/html-injector-core.ts +403 -0
- package/src/server/html-injectors.ts +158 -297
- package/src/server/index.ts +13 -14
- package/src/server/internal.ts +10 -3
- package/src/server/logger.ts +23 -0
- package/src/server/middleware-runner.ts +44 -0
- package/src/server/node-stream-transforms.ts +108 -248
- package/src/server/param-coercion.ts +76 -0
- package/src/server/pipeline-helpers.ts +204 -0
- package/src/server/pipeline-outcome.ts +167 -0
- package/src/server/pipeline-phases.ts +409 -0
- package/src/server/pipeline.ts +70 -540
- package/src/server/port-resolution.ts +215 -0
- package/src/server/request-context.ts +46 -451
- package/src/server/route-element-builder.ts +8 -4
- package/src/server/route-matcher.ts +28 -60
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +2 -2
- package/src/server/rsc-entry/error-renderer.ts +2 -2
- package/src/server/rsc-entry/helpers.ts +2 -7
- package/src/server/rsc-entry/index.ts +81 -366
- package/src/server/rsc-entry/render-route.ts +304 -0
- package/src/server/rsc-entry/rsc-payload.ts +1 -1
- package/src/server/rsc-entry/ssr-renderer.ts +2 -2
- package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
- package/src/server/sitemap-generator.ts +1 -1
- package/src/server/slot-resolver.ts +1 -1
- package/src/server/ssr-entry.ts +1 -1
- package/src/server/state-tree-diff.ts +4 -1
- package/src/server/status-code-resolver.ts +112 -128
- package/src/server/tracing.ts +3 -3
- package/src/server/tree-builder.ts +134 -56
- package/src/server/types.ts +52 -0
- package/src/server/utils/escape-html.ts +20 -0
- package/src/shims/headers.ts +3 -3
- package/src/shims/navigation-client.ts +4 -3
- package/src/shims/navigation.ts +9 -7
- package/src/utils/directive-parser.ts +0 -392
- package/dist/_chunks/actions-DLnUaR65.js +0 -421
- package/dist/_chunks/actions-DLnUaR65.js.map +0 -1
- package/dist/_chunks/als-registry-HS0LGUl2.js +0 -41
- package/dist/_chunks/als-registry-HS0LGUl2.js.map +0 -1
- package/dist/_chunks/debug-ECi_61pb.js +0 -108
- package/dist/_chunks/debug-ECi_61pb.js.map +0 -1
- package/dist/_chunks/define-C77ScO0m.js.map +0 -1
- package/dist/_chunks/define-Itxvcd7F.js.map +0 -1
- package/dist/_chunks/define-cookie-BowvzoP0.js +0 -94
- package/dist/_chunks/define-cookie-BowvzoP0.js.map +0 -1
- package/dist/_chunks/dev-warnings-DpGRGoDi.js.map +0 -1
- package/dist/_chunks/interception-BbqMCVXa.js.map +0 -1
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js +0 -41
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +0 -1
- package/dist/_chunks/request-context-CK5tZqIP.js +0 -478
- package/dist/_chunks/request-context-CK5tZqIP.js.map +0 -1
- package/dist/_chunks/router-ref-C8OCm7g7.js.map +0 -1
- package/dist/_chunks/segment-classify-BDNn6EzD.js +0 -65
- package/dist/_chunks/segment-classify-BDNn6EzD.js.map +0 -1
- package/dist/_chunks/tracing-CCYbKn5n.js +0 -238
- package/dist/_chunks/tracing-CCYbKn5n.js.map +0 -1
- package/dist/_chunks/use-params-IOPu7E8t.js.map +0 -1
- package/dist/_chunks/use-query-states-BiV5GJgm.js.map +0 -1
- package/dist/client/use-params.d.ts.map +0 -1
- package/dist/plugins/dev-404-page.d.ts.map +0 -1
- package/dist/plugins/dev-browser-logs.d.ts.map +0 -1
- package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
- package/dist/plugins/dev-error-page.d.ts.map +0 -1
- package/dist/plugins/dev-logs.d.ts.map +0 -1
- package/dist/plugins/dev-terminal-error.d.ts.map +0 -1
- package/dist/server/deny-page-resolver.d.ts +0 -52
- package/dist/server/deny-page-resolver.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-holding-server.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/page-deny-boundary.d.ts +0 -31
- package/dist/server/page-deny-boundary.d.ts.map +0 -1
- 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/page-deny-boundary.tsx +0 -56
- /package/src/client/{use-params.ts → use-segment-params.ts} +0 -0
- /package/src/{plugins/dev-browser-logs.ts → dev-tools/browser-logs.ts} +0 -0
- /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline phase functions — module-level free functions that take their
|
|
3
|
+
* dependencies as explicit parameters. Each phase returns a `PhaseOutcome`
|
|
4
|
+
* (a discriminated union over response / redirect / deny / error) defined
|
|
5
|
+
* in `pipeline-outcome.ts`. The terminal `outcomeToResponse` (also in
|
|
6
|
+
* `pipeline-outcome.ts`) translates outcomes into Responses.
|
|
7
|
+
*
|
|
8
|
+
* Lifted out of `createPipeline` so each phase can be unit-tested in
|
|
9
|
+
* isolation. The lift is mechanical — these functions used to be closures
|
|
10
|
+
* over `config`; they now take `config` as an explicit parameter.
|
|
11
|
+
*
|
|
12
|
+
* See design/07-routing.md §"Request Lifecycle", design/02-rendering-pipeline.md §"Request Flow".
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { canonicalize } from './canonicalize.js';
|
|
16
|
+
import { runProxy } from './proxy.js';
|
|
17
|
+
import { runMiddlewareChain, shouldBypassMiddleware } from './middleware-runner.js';
|
|
18
|
+
import { withTiming } from './server-timing.js';
|
|
19
|
+
import {
|
|
20
|
+
applyRequestHeaderOverlay,
|
|
21
|
+
setMutableCookieContext,
|
|
22
|
+
setSegmentParams,
|
|
23
|
+
} from './request-context.js';
|
|
24
|
+
import { withSpan } from './tracing.js';
|
|
25
|
+
import { logRenderError } from './logger.js';
|
|
26
|
+
import { RedirectSignal, DenySignal } from './primitives.js';
|
|
27
|
+
import { ParamCoercionError } from './route-element-builder.js';
|
|
28
|
+
import { checkVersionSkew, applyReloadHeaders } from './version-skew.js';
|
|
29
|
+
import { serveStaticMetadataFile, serializeSitemap } from './pipeline-metadata.js';
|
|
30
|
+
import { loadModule } from './safe-load.js';
|
|
31
|
+
import { findInterceptionMatch } from './pipeline-interception.js';
|
|
32
|
+
import { applyCookieJar, cloneWithMutableHeaders, type ProxyResolver } from './pipeline-helpers.js';
|
|
33
|
+
import { coerceSegmentParams } from './param-coercion.js';
|
|
34
|
+
import { outcomeToResponse, type PhaseOutcome } from './pipeline-outcome.js';
|
|
35
|
+
import type { InterceptionContext, PipelineConfig, RouteMatch } from './pipeline.js';
|
|
36
|
+
import type { MetadataHandler, MetadataRoute, MiddlewareContext } from './types.js';
|
|
37
|
+
import { swallow } from './logger.js';
|
|
38
|
+
|
|
39
|
+
interface RenderContext {
|
|
40
|
+
canonicalPathname: string;
|
|
41
|
+
interception?: InterceptionContext;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ─── Phase: Proxy ──────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Run the proxy.ts phase. Calls user proxy code and uses `handleRequest` as
|
|
48
|
+
* the inner `next()` continuation. The proxy resolver was picked at pipeline
|
|
49
|
+
* construction time so the hot path sees no per-request branching on the
|
|
50
|
+
* `ProxyConfig` discriminant.
|
|
51
|
+
*/
|
|
52
|
+
export async function runProxyPhase(
|
|
53
|
+
config: PipelineConfig,
|
|
54
|
+
getProxy: ProxyResolver,
|
|
55
|
+
req: Request,
|
|
56
|
+
method: string,
|
|
57
|
+
path: string
|
|
58
|
+
): Promise<PhaseOutcome> {
|
|
59
|
+
const detailed = config.serverTiming === 'detailed';
|
|
60
|
+
try {
|
|
61
|
+
const proxyExport = await getProxy();
|
|
62
|
+
const proxyFn = () =>
|
|
63
|
+
runProxy(proxyExport, req, () => handleRequest(config, req, method, path));
|
|
64
|
+
const response = await withSpan('timber.proxy', {}, () =>
|
|
65
|
+
detailed ? withTiming('proxy', 'proxy.ts', proxyFn) : proxyFn()
|
|
66
|
+
);
|
|
67
|
+
return { kind: 'response', phase: 'proxy', response };
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return { kind: 'error', phase: 'proxy', error };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ─── Phase: Middleware ─────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Run the middleware chain phase. If the chain short-circuits with a Response,
|
|
77
|
+
* returns it as a 'response' outcome. Otherwise applies the request header
|
|
78
|
+
* overlay and falls through to the render phase.
|
|
79
|
+
*/
|
|
80
|
+
export async function runMiddlewarePhase(
|
|
81
|
+
config: PipelineConfig,
|
|
82
|
+
req: Request,
|
|
83
|
+
match: RouteMatch,
|
|
84
|
+
responseHeaders: Headers,
|
|
85
|
+
requestHeaderOverlay: Headers,
|
|
86
|
+
renderContext: RenderContext
|
|
87
|
+
): Promise<PhaseOutcome> {
|
|
88
|
+
const detailed = config.serverTiming === 'detailed';
|
|
89
|
+
const ctx: MiddlewareContext = {
|
|
90
|
+
req,
|
|
91
|
+
requestHeaders: requestHeaderOverlay,
|
|
92
|
+
headers: responseHeaders,
|
|
93
|
+
segmentParams: match.segmentParams,
|
|
94
|
+
earlyHints: (hints) => {
|
|
95
|
+
for (const hint of hints) {
|
|
96
|
+
// Match Cloudflare's cached Early Hints attribute order: `as` before `rel`.
|
|
97
|
+
// Cloudflare caches Link headers and re-emits them on subsequent 200s.
|
|
98
|
+
// If our order differs, the browser sees duplicate preloads and warns.
|
|
99
|
+
let value: string;
|
|
100
|
+
if (hint.as !== undefined) {
|
|
101
|
+
value = `<${hint.href}>; as=${hint.as}; rel=${hint.rel}`;
|
|
102
|
+
} else {
|
|
103
|
+
value = `<${hint.href}>; rel=${hint.rel}`;
|
|
104
|
+
}
|
|
105
|
+
if (hint.crossOrigin !== undefined) value += `; crossorigin=${hint.crossOrigin}`;
|
|
106
|
+
if (hint.fetchPriority !== undefined) value += `; fetchpriority=${hint.fetchPriority}`;
|
|
107
|
+
responseHeaders.append('Link', value);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const chainFn = () => runMiddlewareChain(match.middlewareChain, ctx);
|
|
114
|
+
// Enable cookie mutation during middleware (design/29-cookies.md §"Context Tracking")
|
|
115
|
+
const middlewareResponse = await (async () => {
|
|
116
|
+
setMutableCookieContext(true);
|
|
117
|
+
try {
|
|
118
|
+
return await withSpan('timber.middleware', {}, () =>
|
|
119
|
+
detailed ? withTiming('mw', 'middleware.ts', chainFn) : chainFn()
|
|
120
|
+
);
|
|
121
|
+
} finally {
|
|
122
|
+
setMutableCookieContext(false);
|
|
123
|
+
}
|
|
124
|
+
})();
|
|
125
|
+
if (middlewareResponse) {
|
|
126
|
+
return { kind: 'response', phase: 'middleware', response: middlewareResponse };
|
|
127
|
+
}
|
|
128
|
+
// Middleware chain completed without short-circuiting — apply any
|
|
129
|
+
// injected request headers so getHeaders() returns them downstream.
|
|
130
|
+
applyRequestHeaderOverlay(requestHeaderOverlay);
|
|
131
|
+
|
|
132
|
+
// Apply cookie jar to response headers before render commits them.
|
|
133
|
+
// This preserves the historical ordering where middleware cookie writes
|
|
134
|
+
// are visible to route-handler header merging, while handler Set-Cookie
|
|
135
|
+
// values still come after middleware cookies and therefore take precedence.
|
|
136
|
+
applyCookieJar(responseHeaders);
|
|
137
|
+
|
|
138
|
+
return runRenderPhase(config, req, match, responseHeaders, requestHeaderOverlay, renderContext);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
if (error instanceof RedirectSignal) {
|
|
141
|
+
return { kind: 'redirect', phase: 'middleware', signal: error };
|
|
142
|
+
}
|
|
143
|
+
if (error instanceof DenySignal) {
|
|
144
|
+
return { kind: 'deny', phase: 'middleware', signal: error };
|
|
145
|
+
}
|
|
146
|
+
return { kind: 'error', phase: 'middleware', error };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ─── Phase: Render ─────────────────────────────────────────────────────────
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Run the render phase. Wraps the configured renderer in a span and a
|
|
154
|
+
* timing scope, and translates thrown signals into outcome variants.
|
|
155
|
+
*/
|
|
156
|
+
export async function runRenderPhase(
|
|
157
|
+
config: PipelineConfig,
|
|
158
|
+
req: Request,
|
|
159
|
+
match: RouteMatch,
|
|
160
|
+
responseHeaders: Headers,
|
|
161
|
+
requestHeaderOverlay: Headers,
|
|
162
|
+
{ canonicalPathname, interception }: RenderContext
|
|
163
|
+
): Promise<PhaseOutcome> {
|
|
164
|
+
const detailed = config.serverTiming === 'detailed';
|
|
165
|
+
try {
|
|
166
|
+
const renderFn = () =>
|
|
167
|
+
config.render(req, match, responseHeaders, requestHeaderOverlay, interception);
|
|
168
|
+
const response = await withSpan('timber.render', { 'http.route': canonicalPathname }, () =>
|
|
169
|
+
detailed ? withTiming('render', 'RSC + SSR render', renderFn) : renderFn()
|
|
170
|
+
);
|
|
171
|
+
return { kind: 'response', phase: 'render', response };
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error instanceof DenySignal) {
|
|
174
|
+
return { kind: 'deny', phase: 'render', signal: error };
|
|
175
|
+
}
|
|
176
|
+
if (error instanceof RedirectSignal) {
|
|
177
|
+
return { kind: 'redirect', phase: 'render', signal: error };
|
|
178
|
+
}
|
|
179
|
+
return { kind: 'error', phase: 'render', error };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ─── Request Handler ───────────────────────────────────────────────────────
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Process a single request from canonicalization through phase dispatch.
|
|
187
|
+
*
|
|
188
|
+
* Stages: canonicalize → metadata routes → auto-sitemap → version skew →
|
|
189
|
+
* route match → interception → early hints → param coercion → middleware →
|
|
190
|
+
* render → outcome translation. Pre-routing short-circuits return Responses
|
|
191
|
+
* directly; post-match dispatch goes through `outcomeToResponse`.
|
|
192
|
+
*
|
|
193
|
+
* Used both as the top-level entry (when no proxy.ts is configured) and as
|
|
194
|
+
* the `next()` continuation passed to `runProxy()`.
|
|
195
|
+
*/
|
|
196
|
+
export async function handleRequest(
|
|
197
|
+
config: PipelineConfig,
|
|
198
|
+
req: Request,
|
|
199
|
+
method: string,
|
|
200
|
+
path: string
|
|
201
|
+
): Promise<Response> {
|
|
202
|
+
const stripTrailingSlash = config.stripTrailingSlash ?? true;
|
|
203
|
+
|
|
204
|
+
// Stage 1: URL canonicalization
|
|
205
|
+
const url = new URL(req.url);
|
|
206
|
+
const result = canonicalize(url.pathname, stripTrailingSlash);
|
|
207
|
+
if (!result.ok) {
|
|
208
|
+
return new Response(null, { status: result.status });
|
|
209
|
+
}
|
|
210
|
+
const canonicalPathname = result.pathname;
|
|
211
|
+
|
|
212
|
+
// Stage 1b: Metadata route matching — runs before regular route matching.
|
|
213
|
+
// Metadata routes skip middleware.ts and access.ts (public endpoints for crawlers).
|
|
214
|
+
// See design/16-metadata.md §"Pipeline Integration"
|
|
215
|
+
if (config.matchMetadataRoute) {
|
|
216
|
+
const metaMatch = config.matchMetadataRoute(canonicalPathname);
|
|
217
|
+
if (metaMatch) {
|
|
218
|
+
try {
|
|
219
|
+
// Static metadata files (.xml, .txt, .png, .ico, etc.) are served
|
|
220
|
+
// directly from disk. Dynamic metadata routes (.ts, .tsx) export a
|
|
221
|
+
// handler function that generates the response.
|
|
222
|
+
if (metaMatch.isStatic) {
|
|
223
|
+
return await serveStaticMetadataFile(metaMatch);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const mod = await loadModule<{ default?: MetadataHandler }>(metaMatch.file);
|
|
227
|
+
if (typeof mod.default !== 'function') {
|
|
228
|
+
return new Response('Metadata route must export a default function', { status: 500 });
|
|
229
|
+
}
|
|
230
|
+
const handlerResult = await mod.default();
|
|
231
|
+
// If the handler returns a Response, normalize headers so the
|
|
232
|
+
// outer Server-Timing writer can append without hitting an
|
|
233
|
+
// immutable header bag (e.g. user returns Response.redirect()).
|
|
234
|
+
if (handlerResult instanceof Response) {
|
|
235
|
+
return cloneWithMutableHeaders(handlerResult);
|
|
236
|
+
}
|
|
237
|
+
// Otherwise, serialize based on content type. The type discriminator
|
|
238
|
+
// here is the metadata route's declared content type (from the file
|
|
239
|
+
// convention), not the shape of `handlerResult` — TS can't narrow the
|
|
240
|
+
// `MetadataResult` union on that, so we assert against the expected
|
|
241
|
+
// shape at each branch.
|
|
242
|
+
const contentType = metaMatch.contentType;
|
|
243
|
+
let body: string;
|
|
244
|
+
if (typeof handlerResult === 'string') {
|
|
245
|
+
body = handlerResult;
|
|
246
|
+
} else if (contentType === 'application/xml') {
|
|
247
|
+
body = serializeSitemap(handlerResult as MetadataRoute.Sitemap);
|
|
248
|
+
} else if (contentType === 'application/manifest+json') {
|
|
249
|
+
body = JSON.stringify(handlerResult, null, 2);
|
|
250
|
+
} else {
|
|
251
|
+
body = String(handlerResult);
|
|
252
|
+
}
|
|
253
|
+
return new Response(body, {
|
|
254
|
+
status: 200,
|
|
255
|
+
headers: { 'Content-Type': `${contentType}; charset=utf-8` },
|
|
256
|
+
});
|
|
257
|
+
} catch (error) {
|
|
258
|
+
logRenderError({ method, path, error });
|
|
259
|
+
if (config.onPipelineError && error instanceof Error)
|
|
260
|
+
config.onPipelineError(error, 'metadata-route');
|
|
261
|
+
return new Response(null, { status: 500 });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Stage 1b.2: Auto-generated sitemap — serves /sitemap.xml and /sitemap/N.xml
|
|
267
|
+
// when sitemap generation is enabled and no user-authored sitemap exists.
|
|
268
|
+
// Runs after metadata route matching so user sitemaps always take precedence.
|
|
269
|
+
// See design/16-metadata.md §"Auto-generated Sitemap"
|
|
270
|
+
if (config.autoSitemapHandler) {
|
|
271
|
+
try {
|
|
272
|
+
const sitemapResponse = await config.autoSitemapHandler(canonicalPathname);
|
|
273
|
+
if (sitemapResponse) return cloneWithMutableHeaders(sitemapResponse);
|
|
274
|
+
} catch (error) {
|
|
275
|
+
logRenderError({ method, path, error });
|
|
276
|
+
if (config.onPipelineError && error instanceof Error)
|
|
277
|
+
config.onPipelineError(error, 'auto-sitemap');
|
|
278
|
+
return new Response(null, { status: 500 });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Stage 1c: Version skew detection (TIM-446).
|
|
283
|
+
// For RSC payload requests (client navigation), check if the client's
|
|
284
|
+
// deployment ID matches the current build. On mismatch, signal the
|
|
285
|
+
// client to do a full page reload instead of returning an RSC payload
|
|
286
|
+
// that references mismatched module IDs.
|
|
287
|
+
const isRscRequest = (req.headers.get('Accept') ?? '').includes('text/x-component');
|
|
288
|
+
if (isRscRequest) {
|
|
289
|
+
const skewCheck = checkVersionSkew(req);
|
|
290
|
+
if (!skewCheck.ok) {
|
|
291
|
+
const reloadHeaders = new Headers();
|
|
292
|
+
applyReloadHeaders(reloadHeaders);
|
|
293
|
+
return new Response(null, { status: 204, headers: reloadHeaders });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Stage 2: Route matching
|
|
298
|
+
let match = config.matchRoute(canonicalPathname);
|
|
299
|
+
let interception: InterceptionContext | undefined;
|
|
300
|
+
|
|
301
|
+
// Stage 2a: Intercepting route resolution (modal pattern).
|
|
302
|
+
// On soft navigation, check if an intercepting route should render instead.
|
|
303
|
+
// The client sends X-Timber-URL with the current pathname (where they're
|
|
304
|
+
// navigating FROM). If a rewrite matches, re-route to the source URL so
|
|
305
|
+
// the source layout renders with the intercepted content in the slot.
|
|
306
|
+
const sourceUrl = req.headers.get('X-Timber-URL');
|
|
307
|
+
if (sourceUrl && config.interceptionRewrites?.length) {
|
|
308
|
+
const intercepted = findInterceptionMatch(
|
|
309
|
+
canonicalPathname,
|
|
310
|
+
sourceUrl,
|
|
311
|
+
config.interceptionRewrites
|
|
312
|
+
);
|
|
313
|
+
if (intercepted) {
|
|
314
|
+
const sourceMatch = config.matchRoute(intercepted.sourcePathname);
|
|
315
|
+
if (sourceMatch) {
|
|
316
|
+
match = sourceMatch;
|
|
317
|
+
interception = { targetPathname: canonicalPathname };
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (!match) {
|
|
323
|
+
// No route matched — render 404.tsx in root layout if available,
|
|
324
|
+
// otherwise fall back to a bare 404 Response.
|
|
325
|
+
if (config.renderNoMatch) {
|
|
326
|
+
const responseHeaders = new Headers();
|
|
327
|
+
return cloneWithMutableHeaders(await config.renderNoMatch(req, responseHeaders));
|
|
328
|
+
}
|
|
329
|
+
return new Response(null, { status: 404 });
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Response and request header containers — created before early hints so
|
|
333
|
+
// the emitter can append Link headers (e.g. for Cloudflare CDN → 103).
|
|
334
|
+
const responseHeaders = new Headers();
|
|
335
|
+
const requestHeaderOverlay = new Headers();
|
|
336
|
+
|
|
337
|
+
// Set Cache-Control for dynamic HTML responses. Without this header,
|
|
338
|
+
// CDNs (particularly Cloudflare) may attempt to buffer/process the
|
|
339
|
+
// response differently, causing intermittent multi-second delays.
|
|
340
|
+
// This matches Next.js's default behavior.
|
|
341
|
+
responseHeaders.set('Cache-Control', 'private, no-cache, no-store, max-age=0, must-revalidate');
|
|
342
|
+
|
|
343
|
+
// Stage 2b: 103 Early Hints (before middleware, after match)
|
|
344
|
+
// Fires before middleware so the browser can begin fetching critical
|
|
345
|
+
// assets while middleware runs. Non-fatal — a failing emitter never
|
|
346
|
+
// blocks the request.
|
|
347
|
+
if (config.earlyHints) {
|
|
348
|
+
try {
|
|
349
|
+
await config.earlyHints(match, req, responseHeaders);
|
|
350
|
+
} catch (err) {
|
|
351
|
+
swallow(err, 'early hints hook threw');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Stage 2c: Param coercion (before middleware)
|
|
356
|
+
// Load params.ts modules from matched segments and coerce raw string
|
|
357
|
+
// params through defineSegmentParams codecs. Coercion failure → 404
|
|
358
|
+
// (middleware never runs). See design/07-routing.md §"Where Coercion Runs"
|
|
359
|
+
try {
|
|
360
|
+
await coerceSegmentParams(match);
|
|
361
|
+
} catch (error) {
|
|
362
|
+
if (error instanceof ParamCoercionError) {
|
|
363
|
+
// For API routes (route.ts), return a bare 404 — not an HTML page.
|
|
364
|
+
// API consumers expect JSON/empty responses, not rendered HTML.
|
|
365
|
+
const leafSegment = match.segments[match.segments.length - 1];
|
|
366
|
+
if ((leafSegment as { route?: unknown }).route && !(leafSegment as { page?: unknown }).page) {
|
|
367
|
+
return new Response(null, { status: 404 });
|
|
368
|
+
}
|
|
369
|
+
// Route through the app's 404 page (404.tsx in root layout) instead of
|
|
370
|
+
// returning a bare empty 404 Response. Falls back to bare 404 only if
|
|
371
|
+
// no renderNoMatch renderer is configured.
|
|
372
|
+
if (config.renderNoMatch) {
|
|
373
|
+
return cloneWithMutableHeaders(await config.renderNoMatch(req, responseHeaders));
|
|
374
|
+
}
|
|
375
|
+
return new Response(null, { status: 404 });
|
|
376
|
+
}
|
|
377
|
+
throw error;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Store coerced segment params in ALS so components can access them
|
|
381
|
+
// via getSegmentParams() instead of receiving them as a prop.
|
|
382
|
+
// See design/07-routing.md §"params.ts — Convention File for Typed Params"
|
|
383
|
+
setSegmentParams(match.segmentParams);
|
|
384
|
+
|
|
385
|
+
// Bypass middleware for synthetic re-render requests built by the
|
|
386
|
+
// action-dispatch wrapper after a no-JS form validation failure.
|
|
387
|
+
// The wrapper has already executed middleware once on the inbound POST;
|
|
388
|
+
// running it again on the rerender GET would double-execute auth, rate
|
|
389
|
+
// limiting, and request-header injection. See TIM-871.
|
|
390
|
+
const skipMiddleware = shouldBypassMiddleware(req);
|
|
391
|
+
const outcome =
|
|
392
|
+
!skipMiddleware && match.middlewareChain.length > 0
|
|
393
|
+
? await runMiddlewarePhase(config, req, match, responseHeaders, requestHeaderOverlay, {
|
|
394
|
+
canonicalPathname,
|
|
395
|
+
interception,
|
|
396
|
+
})
|
|
397
|
+
: await runRenderPhase(config, req, match, responseHeaders, requestHeaderOverlay, {
|
|
398
|
+
canonicalPathname,
|
|
399
|
+
interception,
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
return outcomeToResponse(config, outcome, {
|
|
403
|
+
req,
|
|
404
|
+
method,
|
|
405
|
+
path,
|
|
406
|
+
responseHeaders,
|
|
407
|
+
match,
|
|
408
|
+
});
|
|
409
|
+
}
|