@timber-js/app 0.2.0-alpha.98 → 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/LICENSE +8 -0
- 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/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-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/{walkers-VOXgavMF.js → walkers-Tg0Alwcg.js} +6 -3
- 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 +8 -26
- 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 +40 -90
- 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} +1 -1
- 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} +1 -1
- 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 +97 -72
- 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/routing/convention-lint.d.ts.map +1 -1
- package/dist/routing/index.js +1 -1
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- 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/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 +261 -408
- 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/param-coercion.d.ts +26 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +14 -7
- package/dist/server/pipeline-helpers.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 +4 -49
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +0 -2
- package/dist/server/pipeline.d.ts.map +1 -1
- 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/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 +59 -14
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/state-tree-diff.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/package.json +6 -7
- package/src/adapters/build-output-helper.ts +77 -0
- package/src/adapters/cloudflare.ts +10 -50
- package/src/adapters/nitro.ts +11 -45
- package/src/adapters/shared.ts +40 -0
- package/src/cache/timber-cache.ts +3 -2
- package/src/cli.ts +0 -0
- 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} +2 -7
- package/src/{plugins/dev-error-page.ts → dev-tools/error-page.ts} +5 -32
- 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 +11 -3
- package/src/plugin-context.ts +1 -1
- package/src/plugins/adapter-build.ts +3 -1
- package/src/plugins/dev-server.ts +3 -3
- package/src/plugins/shims.ts +1 -1
- package/src/plugins/static-build.ts +1 -1
- package/src/routing/convention-lint.ts +5 -4
- package/src/routing/scanner.ts +5 -2
- package/src/routing/status-file-lint.ts +4 -2
- 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 +28 -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 +2 -7
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/fallback-error.ts +1 -1
- 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/param-coercion.ts +76 -0
- package/src/server/pipeline-helpers.ts +37 -13
- package/src/server/pipeline-outcome.ts +167 -0
- package/src/server/pipeline-phases.ts +27 -209
- package/src/server/pipeline.ts +2 -9
- package/src/server/request-context.ts +46 -451
- package/src/server/route-element-builder.ts +7 -3
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/error-renderer.ts +1 -1
- package/src/server/rsc-entry/helpers.ts +2 -7
- package/src/server/rsc-entry/index.ts +34 -273
- 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 +316 -23
- package/src/server/ssr-entry.ts +1 -1
- package/src/server/state-tree-diff.ts +4 -1
- package/src/server/tracing.ts +3 -3
- package/src/server/tree-builder.ts +128 -52
- 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/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/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/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/_chunks/walkers-VOXgavMF.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/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/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-holding-server.ts → dev-tools/holding-server.ts} +0 -0
- /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-logs.d.ts","sourceRoot":"","sources":["../../src/plugins/dev-logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,iDAAiD;AACjD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAIzE,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AA2ID;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAsBnD;AAoDD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAiBzD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-terminal-error.d.ts","sourceRoot":"","sources":["../../src/plugins/dev-terminal-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAKL,KAAK,UAAU,EAEhB,MAAM,wBAAwB,CAAC;AA4GhC;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAkEhG"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deny Page Resolver — resolves status-code file components for in-tree deny handling.
|
|
3
|
-
*
|
|
4
|
-
* When AccessGate or PageDenyBoundary catches a DenySignal, they need to
|
|
5
|
-
* render the matching deny page (403.tsx, 4xx.tsx, error.tsx) as a normal
|
|
6
|
-
* element in the React tree. This module resolves the deny page chain from
|
|
7
|
-
* the segment chain — a list of fallback components ordered by specificity.
|
|
8
|
-
*
|
|
9
|
-
* The chain is built during buildRouteElement and passed as a prop to
|
|
10
|
-
* AccessGate and PageDenyBoundary. At catch time, the first matching
|
|
11
|
-
* component is rendered.
|
|
12
|
-
*
|
|
13
|
-
* See design/10-error-handling.md §"Status-Code Files", TIM-666.
|
|
14
|
-
*/
|
|
15
|
-
import type { ManifestSegmentNode } from './route-matcher.js';
|
|
16
|
-
/** A single entry in the deny page fallback chain. */
|
|
17
|
-
export interface DenyPageEntry {
|
|
18
|
-
/** Status code filter: specific (403), category (400 = any 4xx), or null (catch-all). */
|
|
19
|
-
status: number | null;
|
|
20
|
-
/** The component to render (server or client — both work). */
|
|
21
|
-
component: (...args: unknown[]) => unknown;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Build the deny page fallback chain from the segment chain.
|
|
25
|
-
*
|
|
26
|
-
* Walks segments from `startIndex` outward (toward root) and collects
|
|
27
|
-
* status-code file components in fallback order:
|
|
28
|
-
* 1. Specific status files (403.tsx, 404.tsx) — exact match
|
|
29
|
-
* 2. Category catch-alls (4xx.tsx) — matches any 4xx
|
|
30
|
-
* 3. error.tsx — catches everything
|
|
31
|
-
*
|
|
32
|
-
* Each segment is checked in this order. The chain is ordered so the
|
|
33
|
-
* FIRST match wins at catch time.
|
|
34
|
-
*/
|
|
35
|
-
export declare function buildDenyPageChain(segments: ManifestSegmentNode[], startIndex: number): Promise<DenyPageEntry[]>;
|
|
36
|
-
/**
|
|
37
|
-
* Find the first deny page in the chain that matches the given status code.
|
|
38
|
-
* Returns a React element for the matching component, or null if no match.
|
|
39
|
-
*/
|
|
40
|
-
export declare function renderMatchingDenyPage(chain: DenyPageEntry[], status: number, data: unknown): React.ReactElement | null;
|
|
41
|
-
/**
|
|
42
|
-
* Set the deny status in the request context ALS.
|
|
43
|
-
* Called from AccessGate / PageDenyBoundary when a DenySignal is caught.
|
|
44
|
-
* The pipeline reads this after render to set the HTTP status code.
|
|
45
|
-
*/
|
|
46
|
-
export declare function setDenyStatus(status: number): void;
|
|
47
|
-
/**
|
|
48
|
-
* Read the deny status from the request context ALS.
|
|
49
|
-
* Returns undefined if no deny was caught during render.
|
|
50
|
-
*/
|
|
51
|
-
export declare function getDenyStatus(): number | undefined;
|
|
52
|
-
//# sourceMappingURL=deny-page-resolver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deny-page-resolver.d.ts","sourceRoot":"","sources":["../../src/server/deny-page-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAM9D,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,yFAAyF;IACzF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,8DAA8D;IAC9D,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;CAC5C;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,EAAE,CAAC,CAqD1B;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,EAAE,EACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACZ,KAAK,CAAC,YAAY,GAAG,IAAI,CAkB3B;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,SAAS,CAElD"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dev-mode fetch instrumentation — patches globalThis.fetch to create OTEL
|
|
3
|
-
* spans for every fetch call, giving visibility into async data fetching
|
|
4
|
-
* in the dev request log tree.
|
|
5
|
-
*
|
|
6
|
-
* Only activated in dev mode — zero overhead in production.
|
|
7
|
-
*
|
|
8
|
-
* The spans are automatically children of the active OTEL context (e.g. a
|
|
9
|
-
* timber.page or timber.layout span), so they appear nested under the
|
|
10
|
-
* component that initiated the fetch in the dev log tree.
|
|
11
|
-
*
|
|
12
|
-
* Design ref: 17-logging.md §"Dev Logging", LOCAL-289
|
|
13
|
-
*/
|
|
14
|
-
export type DevFetchCleanup = () => void;
|
|
15
|
-
/**
|
|
16
|
-
* Patch globalThis.fetch to wrap every call in an OTEL span.
|
|
17
|
-
*
|
|
18
|
-
* Returns a cleanup function that restores the original fetch.
|
|
19
|
-
* Only call this in dev mode.
|
|
20
|
-
*/
|
|
21
|
-
export declare function instrumentDevFetch(): DevFetchCleanup;
|
|
22
|
-
//# sourceMappingURL=dev-fetch-instrumentation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-fetch-instrumentation.d.ts","sourceRoot":"","sources":["../../src/server/dev-fetch-instrumentation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CA+CpD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-holding-server.d.ts","sourceRoot":"","sources":["../../src/server/dev-holding-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtC,kEAAkE;IAClE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AA8ED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CAmDnD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-logger.d.ts","sourceRoot":"","sources":["../../src/server/dev-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAIlE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAmMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,UAAU,CAMnE;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,CAgDtF;AAyGD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAc1F;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CA6BxD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-span-processor.d.ts","sourceRoot":"","sources":["../../src/server/dev-span-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB,qBAAa,gBAAiB,YAAW,aAAa;IACpD,OAAO,CAAC,YAAY,CAAqC;IACzD,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,eAAe;IAKnC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAI7C,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAqB/B,OAAO,CAAC,MAAM;IAUR,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGlC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-warnings.d.ts","sourceRoot":"","sources":["../../src/server/dev-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAK1C,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAInE,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AASD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEhE;AA0CD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CASrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAUpE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CASxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAU5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAQnF;AAKD;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAQtF;AAID;;;GAGG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC,CAEjD"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PageDenyBoundary — catches DenySignal from page components server-side.
|
|
3
|
-
*
|
|
4
|
-
* Wraps a server component page by calling it as an async function (the same
|
|
5
|
-
* thing React Flight does internally). If the page throws DenySignal, the
|
|
6
|
-
* boundary catches it and renders the matching deny page as a normal element.
|
|
7
|
-
* No error reaches React Flight — the Flight stream is clean, SSR succeeds,
|
|
8
|
-
* and the entire request uses a single renderToReadableStream call.
|
|
9
|
-
*
|
|
10
|
-
* Client component pages ('use client') are NOT wrapped — they can't call
|
|
11
|
-
* deny() (server-only API) and must go through createElement normally.
|
|
12
|
-
*
|
|
13
|
-
* See design/04-authorization.md, design/10-error-handling.md, TIM-666.
|
|
14
|
-
*/
|
|
15
|
-
import type { DenyPageEntry } from './deny-page-resolver.js';
|
|
16
|
-
/**
|
|
17
|
-
* Async server component that wraps a page call with DenySignal catching.
|
|
18
|
-
*
|
|
19
|
-
* Calls the page component as an async function, awaits it, and catches
|
|
20
|
-
* DenySignal. On catch, renders the deny page in-tree. On success, returns
|
|
21
|
-
* the page's rendered output normally.
|
|
22
|
-
*/
|
|
23
|
-
export declare function PageDenyBoundary({ Page, route, denyPages, }: {
|
|
24
|
-
/** The page server component function. */
|
|
25
|
-
Page: (...args: unknown[]) => unknown;
|
|
26
|
-
/** Route path for OTEL tracing. */
|
|
27
|
-
route: string;
|
|
28
|
-
/** Deny page fallback chain from the segment chain. */
|
|
29
|
-
denyPages: DenyPageEntry[];
|
|
30
|
-
}): Promise<React.ReactElement>;
|
|
31
|
-
//# sourceMappingURL=page-deny-boundary.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"page-deny-boundary.d.ts","sourceRoot":"","sources":["../../src/server/page-deny-boundary.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAI7D;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,KAAK,EACL,SAAS,GACV,EAAE;IACD,0CAA0C;IAC1C,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IACtC,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAiB9B"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dev-mode fetch instrumentation — patches globalThis.fetch to create OTEL
|
|
3
|
-
* spans for every fetch call, giving visibility into async data fetching
|
|
4
|
-
* in the dev request log tree.
|
|
5
|
-
*
|
|
6
|
-
* Only activated in dev mode — zero overhead in production.
|
|
7
|
-
*
|
|
8
|
-
* The spans are automatically children of the active OTEL context (e.g. a
|
|
9
|
-
* timber.page or timber.layout span), so they appear nested under the
|
|
10
|
-
* component that initiated the fetch in the dev log tree.
|
|
11
|
-
*
|
|
12
|
-
* Design ref: 17-logging.md §"Dev Logging", LOCAL-289
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import * as api from '@opentelemetry/api';
|
|
16
|
-
|
|
17
|
-
export type DevFetchCleanup = () => void;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Patch globalThis.fetch to wrap every call in an OTEL span.
|
|
21
|
-
*
|
|
22
|
-
* Returns a cleanup function that restores the original fetch.
|
|
23
|
-
* Only call this in dev mode.
|
|
24
|
-
*/
|
|
25
|
-
export function instrumentDevFetch(): DevFetchCleanup {
|
|
26
|
-
const originalFetch = globalThis.fetch;
|
|
27
|
-
const tracer = api.trace.getTracer('timber.js');
|
|
28
|
-
|
|
29
|
-
globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
|
|
30
|
-
const { method, url } = extractFetchInfo(input, init);
|
|
31
|
-
|
|
32
|
-
return tracer.startActiveSpan(
|
|
33
|
-
'timber.fetch',
|
|
34
|
-
{
|
|
35
|
-
attributes: {
|
|
36
|
-
'http.request.method': method,
|
|
37
|
-
'http.url': url,
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
async (span) => {
|
|
41
|
-
try {
|
|
42
|
-
const response = await originalFetch(input, init);
|
|
43
|
-
|
|
44
|
-
span.setAttribute('http.response.status_code', response.status);
|
|
45
|
-
|
|
46
|
-
// Surface cache status from standard headers
|
|
47
|
-
const cacheStatus =
|
|
48
|
-
response.headers.get('X-Cache') ?? response.headers.get('CF-Cache-Status');
|
|
49
|
-
if (cacheStatus) {
|
|
50
|
-
span.setAttribute('timber.cache_status', cacheStatus);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
span.setStatus({ code: api.SpanStatusCode.OK });
|
|
54
|
-
span.end();
|
|
55
|
-
return response;
|
|
56
|
-
} catch (error) {
|
|
57
|
-
span.setStatus({ code: api.SpanStatusCode.ERROR });
|
|
58
|
-
if (error instanceof Error) {
|
|
59
|
-
span.setAttribute('timber.fetch_error', error.message);
|
|
60
|
-
span.recordException(error);
|
|
61
|
-
}
|
|
62
|
-
span.end();
|
|
63
|
-
throw error;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
return () => {
|
|
70
|
-
globalThis.fetch = originalFetch;
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Extract method and URL from the various fetch() call signatures.
|
|
76
|
-
*/
|
|
77
|
-
function extractFetchInfo(
|
|
78
|
-
input: RequestInfo | URL,
|
|
79
|
-
init?: RequestInit
|
|
80
|
-
): { method: string; url: string } {
|
|
81
|
-
let method = init?.method ?? 'GET';
|
|
82
|
-
let url: string;
|
|
83
|
-
|
|
84
|
-
if (input instanceof Request) {
|
|
85
|
-
url = input.url;
|
|
86
|
-
if (!init?.method) {
|
|
87
|
-
method = input.method;
|
|
88
|
-
}
|
|
89
|
-
} else if (input instanceof URL) {
|
|
90
|
-
url = input.toString();
|
|
91
|
-
} else {
|
|
92
|
-
url = input;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return { method: method.toUpperCase(), url };
|
|
96
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DevSpanProcessor — Custom OTEL SpanProcessor that drives dev log output.
|
|
3
|
-
*
|
|
4
|
-
* Collects completed spans per-request (correlated by trace ID). When the
|
|
5
|
-
* root span (http.server.request) ends, all child spans are already collected
|
|
6
|
-
* (child spans end before parent in OTEL). The processor formats the span
|
|
7
|
-
* tree and writes it to stderr.
|
|
8
|
-
*
|
|
9
|
-
* This replaces the old DevLogEmitter/DevLogEvents system. OTEL spans are
|
|
10
|
-
* now the single source of truth for dev logging — no more parallel event
|
|
11
|
-
* systems that can drift.
|
|
12
|
-
*
|
|
13
|
-
* Design doc: 17-logging.md §"Dev Logging", 21-dev-server.md §"Dev Logging"
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import type { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
|
|
17
|
-
import type { Span, Context } from '@opentelemetry/api';
|
|
18
|
-
import {
|
|
19
|
-
formatSpanTree,
|
|
20
|
-
formatSpanSummary,
|
|
21
|
-
formatJson,
|
|
22
|
-
type DevLogMode,
|
|
23
|
-
type DevLoggerConfig,
|
|
24
|
-
} from './dev-logger.js';
|
|
25
|
-
|
|
26
|
-
export class DevSpanProcessor implements SpanProcessor {
|
|
27
|
-
private spansByTrace = new Map<string, ReadableSpan[]>();
|
|
28
|
-
private mode: DevLogMode;
|
|
29
|
-
private config: DevLoggerConfig;
|
|
30
|
-
|
|
31
|
-
constructor(config: DevLoggerConfig) {
|
|
32
|
-
this.config = config;
|
|
33
|
-
this.mode = config.mode ?? 'tree';
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
onStart(_span: Span, _context: Context): void {
|
|
37
|
-
// No action needed on span start — we collect on end.
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
onEnd(span: ReadableSpan): void {
|
|
41
|
-
const traceId = span.spanContext().traceId;
|
|
42
|
-
|
|
43
|
-
let spans = this.spansByTrace.get(traceId);
|
|
44
|
-
if (!spans) {
|
|
45
|
-
spans = [];
|
|
46
|
-
this.spansByTrace.set(traceId, spans);
|
|
47
|
-
}
|
|
48
|
-
spans.push(span);
|
|
49
|
-
|
|
50
|
-
// Root span signals request completion — all child spans are already
|
|
51
|
-
// collected because OTEL ends child spans before parent spans.
|
|
52
|
-
if (span.name === 'http.server.request') {
|
|
53
|
-
const output = this.format(spans);
|
|
54
|
-
if (output) {
|
|
55
|
-
process.stderr.write(output);
|
|
56
|
-
}
|
|
57
|
-
this.spansByTrace.delete(traceId);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private format(spans: ReadableSpan[]): string {
|
|
62
|
-
if (this.mode === 'quiet') return '';
|
|
63
|
-
if (this.mode === 'json') return formatJson(spans);
|
|
64
|
-
if (this.mode === 'summary') return formatSpanSummary(spans, this.config);
|
|
65
|
-
// Both 'tree' and 'verbose' use the tree formatter.
|
|
66
|
-
// verbose will show additional detail (every component render) once
|
|
67
|
-
// component-level spans are wired.
|
|
68
|
-
return formatSpanTree(spans, this.config);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async shutdown(): Promise<void> {
|
|
72
|
-
this.spansByTrace.clear();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async forceFlush(): Promise<void> {
|
|
76
|
-
// Nothing to flush — output happens synchronously in onEnd.
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PageDenyBoundary — catches DenySignal from page components server-side.
|
|
3
|
-
*
|
|
4
|
-
* Wraps a server component page by calling it as an async function (the same
|
|
5
|
-
* thing React Flight does internally). If the page throws DenySignal, the
|
|
6
|
-
* boundary catches it and renders the matching deny page as a normal element.
|
|
7
|
-
* No error reaches React Flight — the Flight stream is clean, SSR succeeds,
|
|
8
|
-
* and the entire request uses a single renderToReadableStream call.
|
|
9
|
-
*
|
|
10
|
-
* Client component pages ('use client') are NOT wrapped — they can't call
|
|
11
|
-
* deny() (server-only API) and must go through createElement normally.
|
|
12
|
-
*
|
|
13
|
-
* See design/04-authorization.md, design/10-error-handling.md, TIM-666.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { DenySignal } from './primitives.js';
|
|
17
|
-
import type { DenyPageEntry } from './deny-page-resolver.js';
|
|
18
|
-
import { renderMatchingDenyPage, setDenyStatus } from './deny-page-resolver.js';
|
|
19
|
-
import { withSpan } from './tracing.js';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Async server component that wraps a page call with DenySignal catching.
|
|
23
|
-
*
|
|
24
|
-
* Calls the page component as an async function, awaits it, and catches
|
|
25
|
-
* DenySignal. On catch, renders the deny page in-tree. On success, returns
|
|
26
|
-
* the page's rendered output normally.
|
|
27
|
-
*/
|
|
28
|
-
export async function PageDenyBoundary({
|
|
29
|
-
Page,
|
|
30
|
-
route,
|
|
31
|
-
denyPages,
|
|
32
|
-
}: {
|
|
33
|
-
/** The page server component function. */
|
|
34
|
-
Page: (...args: unknown[]) => unknown;
|
|
35
|
-
/** Route path for OTEL tracing. */
|
|
36
|
-
route: string;
|
|
37
|
-
/** Deny page fallback chain from the segment chain. */
|
|
38
|
-
denyPages: DenyPageEntry[];
|
|
39
|
-
}): Promise<React.ReactElement> {
|
|
40
|
-
try {
|
|
41
|
-
// Call the page as an async function — same as React Flight does.
|
|
42
|
-
// Wrap in OTEL span for tracing (replaces the TracedPage wrapper).
|
|
43
|
-
const result = await withSpan('timber.page', { 'timber.route': route }, () => Page({}));
|
|
44
|
-
return result as React.ReactElement;
|
|
45
|
-
} catch (error: unknown) {
|
|
46
|
-
if (error instanceof DenySignal) {
|
|
47
|
-
const denyElement = renderMatchingDenyPage(denyPages, error.status, error.data);
|
|
48
|
-
if (denyElement) {
|
|
49
|
-
setDenyStatus(error.status);
|
|
50
|
-
return denyElement;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
// Non-deny errors (RedirectSignal, runtime errors) propagate normally.
|
|
54
|
-
throw error;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|