@wular/pnext 0.0.4 → 0.0.7
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/README.md +22 -16
- package/bin/pnext +6 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +87 -22
- package/reference/config.md +40 -93
- package/reference/css.md +42 -33
- package/reference/dev.md +26 -33
- package/reference/env.md +18 -20
- package/reference/getting-started.md +132 -0
- package/reference/metadata.md +31 -46
- package/reference/navigation.md +65 -105
- package/reference/performance.md +21 -142
- package/reference/rendering.md +78 -75
- package/reference/routing.md +97 -107
- package/reference/typegen.md +27 -29
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +121 -114
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +52 -53
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +72 -64
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +94 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +802 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +32 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +2022 -1995
- package/src/{api → client}/router/types.ts +98 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +86 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2087 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +87 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +954 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +428 -406
- package/src/styles.d.ts +9 -0
- package/src/types.ts +324 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/reference/overview.md +0 -35
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
|
@@ -8,19 +8,19 @@
|
|
|
8
8
|
// released when it ends and nothing outside a build is cached at all. That is what keeps the dev
|
|
9
9
|
// watcher out of it - dev reads go straight to the filesystem, so a save is never served a stale
|
|
10
10
|
// string, and content-keyed invalidation downstream is untouched.
|
|
11
|
-
import { readFileSync } from 'node:fs'
|
|
12
|
-
import { readFile } from 'node:fs/promises'
|
|
11
|
+
import { readFileSync } from 'node:fs'
|
|
12
|
+
import { readFile } from 'node:fs/promises'
|
|
13
13
|
|
|
14
14
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
15
|
-
const disabled = process.env.PNEXT_SRC_CACHE === '0'
|
|
15
|
+
const disabled = process.env.PNEXT_SRC_CACHE === '0'
|
|
16
16
|
|
|
17
|
-
const contents = new Map<string, string>()
|
|
17
|
+
const contents = new Map<string, string>()
|
|
18
18
|
// Reads still in flight: two async consumers asking at once share one read
|
|
19
19
|
// rather than racing two. Resolved entries move to `contents`.
|
|
20
|
-
const inflight = new Map<string, Promise<string>>()
|
|
21
|
-
let scoped = false
|
|
22
|
-
let reads = 0
|
|
23
|
-
let hits = 0
|
|
20
|
+
const inflight = new Map<string, Promise<string>>()
|
|
21
|
+
let scoped = false
|
|
22
|
+
let reads = 0
|
|
23
|
+
let hits = 0
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Start caching source reads. Two builds in one process (the test runner) share the map - keyed by absolute
|
|
@@ -28,59 +28,59 @@ let hits = 0;
|
|
|
28
28
|
* uncached.
|
|
29
29
|
*/
|
|
30
30
|
export function beginSourceScope() {
|
|
31
|
-
if (disabled) return
|
|
32
|
-
scoped = true
|
|
31
|
+
if (disabled) return
|
|
32
|
+
scoped = true
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/** End the scope and drop everything it held. */
|
|
36
36
|
export function endSourceScope() {
|
|
37
|
-
scoped = false
|
|
38
|
-
contents.clear()
|
|
39
|
-
inflight.clear()
|
|
37
|
+
scoped = false
|
|
38
|
+
contents.clear()
|
|
39
|
+
inflight.clear()
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export function readSourceSync(file: string): string {
|
|
43
|
-
if (!scoped) return readFileSync(file, 'utf8')
|
|
44
|
-
const cached = contents.get(file)
|
|
43
|
+
if (!scoped) return readFileSync(file, 'utf8')
|
|
44
|
+
const cached = contents.get(file)
|
|
45
45
|
if (cached !== undefined) {
|
|
46
|
-
hits += 1
|
|
47
|
-
return cached
|
|
46
|
+
hits += 1
|
|
47
|
+
return cached
|
|
48
48
|
}
|
|
49
|
-
reads += 1
|
|
50
|
-
const source = readFileSync(file, 'utf8')
|
|
51
|
-
contents.set(file, source)
|
|
52
|
-
return source
|
|
49
|
+
reads += 1
|
|
50
|
+
const source = readFileSync(file, 'utf8')
|
|
51
|
+
contents.set(file, source)
|
|
52
|
+
return source
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export async function readSourceText(file: string): Promise<string> {
|
|
56
|
-
if (!scoped) return readFile(file, 'utf8')
|
|
57
|
-
const cached = contents.get(file)
|
|
56
|
+
if (!scoped) return readFile(file, 'utf8')
|
|
57
|
+
const cached = contents.get(file)
|
|
58
58
|
if (cached !== undefined) {
|
|
59
|
-
hits += 1
|
|
60
|
-
return cached
|
|
59
|
+
hits += 1
|
|
60
|
+
return cached
|
|
61
61
|
}
|
|
62
|
-
const pending = inflight.get(file)
|
|
62
|
+
const pending = inflight.get(file)
|
|
63
63
|
if (pending) {
|
|
64
|
-
hits += 1
|
|
65
|
-
return pending
|
|
64
|
+
hits += 1
|
|
65
|
+
return pending
|
|
66
66
|
}
|
|
67
|
-
reads += 1
|
|
67
|
+
reads += 1
|
|
68
68
|
// A read that fails is dropped from `inflight` too: the next asker retries and
|
|
69
69
|
// sees the error at its own call site, as it would without the cache.
|
|
70
70
|
const read = (async () => {
|
|
71
71
|
try {
|
|
72
|
-
const source = await readFile(file, 'utf8')
|
|
73
|
-
contents.set(file, source)
|
|
74
|
-
return source
|
|
72
|
+
const source = await readFile(file, 'utf8')
|
|
73
|
+
contents.set(file, source)
|
|
74
|
+
return source
|
|
75
75
|
} finally {
|
|
76
|
-
inflight.delete(file)
|
|
76
|
+
inflight.delete(file)
|
|
77
77
|
}
|
|
78
|
-
})()
|
|
79
|
-
inflight.set(file, read)
|
|
80
|
-
return read
|
|
78
|
+
})()
|
|
79
|
+
inflight.set(file, read)
|
|
80
|
+
return read
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/** Read effectiveness, for the build benches. */
|
|
84
84
|
export function sourceCacheStats() {
|
|
85
|
-
return { reads, hits, files: contents.size }
|
|
85
|
+
return { reads, hits, files: contents.size }
|
|
86
86
|
}
|
|
@@ -18,245 +18,249 @@
|
|
|
18
18
|
|
|
19
19
|
export interface ShakeableDynamicImport {
|
|
20
20
|
/** Absolute index (inclusive) of the specifier string literal, quote included. */
|
|
21
|
-
literalStart: number
|
|
21
|
+
literalStart: number
|
|
22
22
|
/** Absolute index (exclusive) just past the closing quote. */
|
|
23
|
-
literalEnd: number
|
|
23
|
+
literalEnd: number
|
|
24
24
|
/** The import specifier (without quotes). */
|
|
25
|
-
specifier: string
|
|
25
|
+
specifier: string
|
|
26
26
|
/**
|
|
27
27
|
* Export names the destructuring keeps. An empty array means the module is
|
|
28
28
|
* imported purely for side effects (`const {} = ...`): drop every export.
|
|
29
29
|
*/
|
|
30
|
-
usedExports: string[]
|
|
30
|
+
usedExports: string[]
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const declStart = /\b(?:const|let|var)\s+\{/g
|
|
33
|
+
const declStart = /\b(?:const|let|var)\s+\{/g
|
|
34
34
|
|
|
35
35
|
export function findShakeableDynamicImports(source: string): ShakeableDynamicImport[] {
|
|
36
|
-
const results: ShakeableDynamicImport[] = []
|
|
37
|
-
let match: RegExpExecArray | null
|
|
36
|
+
const results: ShakeableDynamicImport[] = []
|
|
37
|
+
let match: RegExpExecArray | null
|
|
38
38
|
|
|
39
39
|
while ((match = declStart.exec(source))) {
|
|
40
|
-
const braceOpen = match.index + match[0].length - 1
|
|
41
|
-
const braceClose = matchDelimiter(source, braceOpen, '{', '}')
|
|
42
|
-
if (braceClose < 0) continue
|
|
40
|
+
const braceOpen = match.index + match[0].length - 1
|
|
41
|
+
const braceClose = matchDelimiter(source, braceOpen, '{', '}')
|
|
42
|
+
if (braceClose < 0) continue
|
|
43
43
|
|
|
44
|
-
let index = skipTrivia(source, braceClose + 1)
|
|
45
|
-
if (source[index] !== '=') continue
|
|
46
|
-
index = skipTrivia(source, index + 1)
|
|
47
|
-
if (!matchesWord(source, index, 'await')) continue
|
|
48
|
-
index = skipTrivia(source, index + 'await'.length)
|
|
49
|
-
if (!matchesWord(source, index, 'import')) continue
|
|
50
|
-
index = skipTrivia(source, index + 'import'.length)
|
|
51
|
-
if (source[index] !== '(') continue
|
|
44
|
+
let index = skipTrivia(source, braceClose + 1)
|
|
45
|
+
if (source[index] !== '=') continue
|
|
46
|
+
index = skipTrivia(source, index + 1)
|
|
47
|
+
if (!matchesWord(source, index, 'await')) continue
|
|
48
|
+
index = skipTrivia(source, index + 'await'.length)
|
|
49
|
+
if (!matchesWord(source, index, 'import')) continue
|
|
50
|
+
index = skipTrivia(source, index + 'import'.length)
|
|
51
|
+
if (source[index] !== '(') continue
|
|
52
52
|
|
|
53
|
-
const parenClose = matchDelimiter(source, index, '(', ')')
|
|
54
|
-
if (parenClose < 0) continue
|
|
55
|
-
const argStart = index + 1
|
|
56
|
-
const argText = source.slice(argStart, parenClose)
|
|
53
|
+
const parenClose = matchDelimiter(source, index, '(', ')')
|
|
54
|
+
if (parenClose < 0) continue
|
|
55
|
+
const argStart = index + 1
|
|
56
|
+
const argText = source.slice(argStart, parenClose)
|
|
57
57
|
|
|
58
|
-
const literal = firstStringLiteral(argText)
|
|
59
|
-
if (!literal || hasTrailingArgument(argText, literal.end)) continue
|
|
58
|
+
const literal = firstStringLiteral(argText)
|
|
59
|
+
if (!literal || hasTrailingArgument(argText, literal.end)) continue
|
|
60
60
|
|
|
61
|
-
const patternExports = usedExportsFromPattern(source.slice(braceOpen, braceClose + 1))
|
|
62
|
-
if (patternExports === null) continue
|
|
61
|
+
const patternExports = usedExportsFromPattern(source.slice(braceOpen, braceClose + 1))
|
|
62
|
+
if (patternExports === null) continue // rest element — not shakeable
|
|
63
63
|
|
|
64
|
-
const webpackExports = webpackExportsFromArg(argText)
|
|
64
|
+
const webpackExports = webpackExportsFromArg(argText)
|
|
65
65
|
results.push({
|
|
66
66
|
literalStart: argStart + literal.start,
|
|
67
67
|
literalEnd: argStart + literal.end,
|
|
68
68
|
specifier: literal.value,
|
|
69
69
|
usedExports: webpackExports ?? patternExports,
|
|
70
|
-
})
|
|
71
|
-
declStart.lastIndex = parenClose + 1
|
|
70
|
+
})
|
|
71
|
+
declStart.lastIndex = parenClose + 1
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
return results
|
|
74
|
+
return results
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
// Parse an object destructuring pattern (braces included) into the top-level
|
|
78
78
|
// export names it binds. Returns null when a rest element is present (webpack
|
|
79
79
|
// gives up on tree-shaking then).
|
|
80
80
|
function usedExportsFromPattern(pattern: string): string[] | null {
|
|
81
|
-
const inner = pattern.slice(1, -1)
|
|
82
|
-
const names: string[] = []
|
|
81
|
+
const inner = pattern.slice(1, -1)
|
|
82
|
+
const names: string[] = []
|
|
83
83
|
|
|
84
84
|
for (const rawPart of splitTopLevel(inner)) {
|
|
85
|
-
const part = rawPart.trim()
|
|
86
|
-
if (!part) continue
|
|
87
|
-
if (part.startsWith('...')) return null
|
|
85
|
+
const part = rawPart.trim()
|
|
86
|
+
if (!part) continue
|
|
87
|
+
if (part.startsWith('...')) return null
|
|
88
88
|
|
|
89
|
-
const colon = topLevelColonIndex(part)
|
|
90
|
-
const keyRegion = colon >= 0 ? part.slice(0, colon) : part
|
|
89
|
+
const colon = topLevelColonIndex(part)
|
|
90
|
+
const keyRegion = colon >= 0 ? part.slice(0, colon) : part
|
|
91
91
|
// `{ a = fallback }` shorthand with a default — the key is before `=`.
|
|
92
|
-
const eq = colon >= 0 ? -1 : keyRegion.indexOf('=')
|
|
93
|
-
const name = (eq >= 0 ? keyRegion.slice(0, eq) : keyRegion).trim()
|
|
94
|
-
if (!/^[A-Za-z_$][\w$]*$/.test(name)) return null
|
|
95
|
-
names.push(name)
|
|
92
|
+
const eq = colon >= 0 ? -1 : keyRegion.indexOf('=')
|
|
93
|
+
const name = (eq >= 0 ? keyRegion.slice(0, eq) : keyRegion).trim()
|
|
94
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(name)) return null // computed/string key — bail
|
|
95
|
+
names.push(name)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
return names
|
|
98
|
+
return names
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
function webpackExportsFromArg(argText: string): string[] | undefined {
|
|
102
|
-
const match = /webpackExports\s*:\s*\[([^\]]*)\]/.exec(argText)
|
|
103
|
-
if (!match) return undefined
|
|
104
|
-
const names: string[] = []
|
|
105
|
-
const namePattern = /['"]([^'"]+)['"]/g
|
|
106
|
-
let entry: RegExpExecArray | null
|
|
102
|
+
const match = /webpackExports\s*:\s*\[([^\]]*)\]/.exec(argText)
|
|
103
|
+
if (!match) return undefined
|
|
104
|
+
const names: string[] = []
|
|
105
|
+
const namePattern = /['"]([^'"]+)['"]/g
|
|
106
|
+
let entry: RegExpExecArray | null
|
|
107
107
|
while ((entry = namePattern.exec(match[1] ?? ''))) {
|
|
108
|
-
if (entry[1]) names.push(entry[1])
|
|
108
|
+
if (entry[1]) names.push(entry[1])
|
|
109
109
|
}
|
|
110
|
-
return names
|
|
110
|
+
return names
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
// Split a comma-separated list at top level, ignoring commas nested in braces,
|
|
114
114
|
// brackets, parens, strings, or comments.
|
|
115
115
|
function splitTopLevel(source: string): string[] {
|
|
116
|
-
const parts: string[] = []
|
|
117
|
-
let depth = 0
|
|
118
|
-
let start = 0
|
|
119
|
-
let index = 0
|
|
116
|
+
const parts: string[] = []
|
|
117
|
+
let depth = 0
|
|
118
|
+
let start = 0
|
|
119
|
+
let index = 0
|
|
120
120
|
|
|
121
121
|
while (index < source.length) {
|
|
122
|
-
const skipped = skipStringOrComment(source, index)
|
|
122
|
+
const skipped = skipStringOrComment(source, index)
|
|
123
123
|
if (skipped > index) {
|
|
124
|
-
index = skipped
|
|
125
|
-
continue
|
|
124
|
+
index = skipped
|
|
125
|
+
continue
|
|
126
126
|
}
|
|
127
|
-
const char = source[index]
|
|
128
|
-
if (char === '{' || char === '[' || char === '(') depth += 1
|
|
129
|
-
else if (char === '}' || char === ']' || char === ')') depth -= 1
|
|
127
|
+
const char = source[index]
|
|
128
|
+
if (char === '{' || char === '[' || char === '(') depth += 1
|
|
129
|
+
else if (char === '}' || char === ']' || char === ')') depth -= 1
|
|
130
130
|
else if (char === ',' && depth === 0) {
|
|
131
|
-
parts.push(source.slice(start, index))
|
|
132
|
-
start = index + 1
|
|
131
|
+
parts.push(source.slice(start, index))
|
|
132
|
+
start = index + 1
|
|
133
133
|
}
|
|
134
|
-
index += 1
|
|
134
|
+
index += 1
|
|
135
135
|
}
|
|
136
|
-
parts.push(source.slice(start))
|
|
137
|
-
return parts
|
|
136
|
+
parts.push(source.slice(start))
|
|
137
|
+
return parts
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
function topLevelColonIndex(source: string): number {
|
|
141
|
-
let depth = 0
|
|
142
|
-
let index = 0
|
|
141
|
+
let depth = 0
|
|
142
|
+
let index = 0
|
|
143
143
|
while (index < source.length) {
|
|
144
|
-
const skipped = skipStringOrComment(source, index)
|
|
144
|
+
const skipped = skipStringOrComment(source, index)
|
|
145
145
|
if (skipped > index) {
|
|
146
|
-
index = skipped
|
|
147
|
-
continue
|
|
146
|
+
index = skipped
|
|
147
|
+
continue
|
|
148
148
|
}
|
|
149
|
-
const char = source[index]
|
|
150
|
-
if (char === '{' || char === '[' || char === '(') depth += 1
|
|
151
|
-
else if (char === '}' || char === ']' || char === ')') depth -= 1
|
|
152
|
-
else if (char === ':' && depth === 0) return index
|
|
153
|
-
index += 1
|
|
149
|
+
const char = source[index]
|
|
150
|
+
if (char === '{' || char === '[' || char === '(') depth += 1
|
|
151
|
+
else if (char === '}' || char === ']' || char === ')') depth -= 1
|
|
152
|
+
else if (char === ':' && depth === 0) return index
|
|
153
|
+
index += 1
|
|
154
154
|
}
|
|
155
|
-
return -1
|
|
155
|
+
return -1
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// Index of the matching close delimiter for the open delimiter at `open`,
|
|
159
159
|
// respecting nested delimiters, strings, and comments. Returns -1 if unbalanced.
|
|
160
160
|
function matchDelimiter(source: string, open: number, openChar: string, closeChar: string): number {
|
|
161
|
-
let depth = 0
|
|
162
|
-
let index = open
|
|
161
|
+
let depth = 0
|
|
162
|
+
let index = open
|
|
163
163
|
while (index < source.length) {
|
|
164
|
-
const skipped = skipStringOrComment(source, index)
|
|
164
|
+
const skipped = skipStringOrComment(source, index)
|
|
165
165
|
if (skipped > index) {
|
|
166
|
-
index = skipped
|
|
167
|
-
continue
|
|
166
|
+
index = skipped
|
|
167
|
+
continue
|
|
168
168
|
}
|
|
169
|
-
const char = source[index]
|
|
170
|
-
if (char === openChar) depth += 1
|
|
169
|
+
const char = source[index]
|
|
170
|
+
if (char === openChar) depth += 1
|
|
171
171
|
else if (char === closeChar) {
|
|
172
|
-
depth -= 1
|
|
173
|
-
if (depth === 0) return index
|
|
172
|
+
depth -= 1
|
|
173
|
+
if (depth === 0) return index
|
|
174
174
|
}
|
|
175
|
-
index += 1
|
|
175
|
+
index += 1
|
|
176
176
|
}
|
|
177
|
-
return -1
|
|
177
|
+
return -1
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
// Locate the first string literal in `text`, skipping leading whitespace and
|
|
181
181
|
// comments. Returns its bounds (quotes included, `end` exclusive) and value.
|
|
182
|
-
function firstStringLiteral(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
function firstStringLiteral(
|
|
183
|
+
text: string,
|
|
184
|
+
): { start: number; end: number; value: string } | undefined {
|
|
185
|
+
let index = skipTrivia(text, 0)
|
|
186
|
+
const quote = text[index]
|
|
187
|
+
if (quote !== '"' && quote !== "'" && quote !== '`') return undefined
|
|
188
|
+
const start = index
|
|
189
|
+
index += 1
|
|
190
|
+
let value = ''
|
|
189
191
|
while (index < text.length) {
|
|
190
|
-
const char = text[index]
|
|
192
|
+
const char = text[index]
|
|
191
193
|
if (char === '\\') {
|
|
192
|
-
value += text[index + 1] ?? ''
|
|
193
|
-
index += 2
|
|
194
|
-
continue
|
|
194
|
+
value += text[index + 1] ?? ''
|
|
195
|
+
index += 2
|
|
196
|
+
continue
|
|
195
197
|
}
|
|
196
|
-
if (char === quote) return { start, end: index + 1, value }
|
|
197
|
-
value += char
|
|
198
|
-
index += 1
|
|
198
|
+
if (char === quote) return { start, end: index + 1, value }
|
|
199
|
+
value += char
|
|
200
|
+
index += 1
|
|
199
201
|
}
|
|
200
|
-
return undefined
|
|
202
|
+
return undefined
|
|
201
203
|
}
|
|
202
204
|
|
|
203
205
|
// True when a second top-level argument follows the specifier — `import('x', y)`
|
|
204
206
|
// is not a bare specifier import and is left untouched.
|
|
205
207
|
function hasTrailingArgument(argText: string, afterLiteral: number): boolean {
|
|
206
|
-
const index = skipTrivia(argText, afterLiteral)
|
|
207
|
-
return
|
|
208
|
+
const index = skipTrivia(argText, afterLiteral)
|
|
209
|
+
return (
|
|
210
|
+
index < argText.length && argText[index] === ',' && Boolean(argText.slice(index + 1).trim())
|
|
211
|
+
)
|
|
208
212
|
}
|
|
209
213
|
|
|
210
214
|
function matchesWord(source: string, index: number, word: string): boolean {
|
|
211
|
-
if (!source.startsWith(word, index)) return false
|
|
212
|
-
const after = source[index + word.length]
|
|
213
|
-
return after === undefined || !/[\w$]/.test(after)
|
|
215
|
+
if (!source.startsWith(word, index)) return false
|
|
216
|
+
const after = source[index + word.length]
|
|
217
|
+
return after === undefined || !/[\w$]/.test(after)
|
|
214
218
|
}
|
|
215
219
|
|
|
216
220
|
// Skip whitespace and `//`/`/* */` comments starting at `index`.
|
|
217
221
|
function skipTrivia(source: string, index: number): number {
|
|
218
|
-
let current = index
|
|
222
|
+
let current = index
|
|
219
223
|
for (;;) {
|
|
220
|
-
while (current < source.length && /\s/.test(source[current] ?? '')) current += 1
|
|
221
|
-
const skipped = skipComment(source, current)
|
|
222
|
-
if (skipped === current) return current
|
|
223
|
-
current = skipped
|
|
224
|
+
while (current < source.length && /\s/.test(source[current] ?? '')) current += 1
|
|
225
|
+
const skipped = skipComment(source, current)
|
|
226
|
+
if (skipped === current) return current
|
|
227
|
+
current = skipped
|
|
224
228
|
}
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
// If `index` starts a string or comment, return the index just past it;
|
|
228
232
|
// otherwise return `index` unchanged.
|
|
229
233
|
function skipStringOrComment(source: string, index: number): number {
|
|
230
|
-
const comment = skipComment(source, index)
|
|
231
|
-
if (comment > index) return comment
|
|
232
|
-
const char = source[index]
|
|
234
|
+
const comment = skipComment(source, index)
|
|
235
|
+
if (comment > index) return comment
|
|
236
|
+
const char = source[index]
|
|
233
237
|
if (char === '"' || char === "'" || char === '`') {
|
|
234
|
-
let current = index + 1
|
|
238
|
+
let current = index + 1
|
|
235
239
|
while (current < source.length) {
|
|
236
240
|
if (source[current] === '\\') {
|
|
237
|
-
current += 2
|
|
238
|
-
continue
|
|
241
|
+
current += 2
|
|
242
|
+
continue
|
|
239
243
|
}
|
|
240
|
-
if (source[current] === char) return current + 1
|
|
241
|
-
current += 1
|
|
244
|
+
if (source[current] === char) return current + 1
|
|
245
|
+
current += 1
|
|
242
246
|
}
|
|
243
|
-
return source.length
|
|
247
|
+
return source.length
|
|
244
248
|
}
|
|
245
|
-
return index
|
|
249
|
+
return index
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
function skipComment(source: string, index: number): number {
|
|
249
253
|
if (source[index] === '/' && source[index + 1] === '/') {
|
|
250
|
-
let current = index + 2
|
|
251
|
-
while (current < source.length && source[current] !== '\n') current += 1
|
|
252
|
-
return current
|
|
254
|
+
let current = index + 2
|
|
255
|
+
while (current < source.length && source[current] !== '\n') current += 1
|
|
256
|
+
return current
|
|
253
257
|
}
|
|
254
258
|
if (source[index] === '/' && source[index + 1] === '*') {
|
|
255
|
-
let current = index + 2
|
|
259
|
+
let current = index + 2
|
|
256
260
|
while (current < source.length && !(source[current] === '*' && source[current + 1] === '/')) {
|
|
257
|
-
current += 1
|
|
261
|
+
current += 1
|
|
258
262
|
}
|
|
259
|
-
return Math.min(source.length, current + 2)
|
|
263
|
+
return Math.min(source.length, current + 2)
|
|
260
264
|
}
|
|
261
|
-
return index
|
|
265
|
+
return index
|
|
262
266
|
}
|
package/src/routing/forwarded.ts
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
// x-forwarded-* values are never overridden (a trusted proxy already set them),
|
|
7
7
|
// including multi-value forms like "https, https".
|
|
8
8
|
|
|
9
|
-
const FORWARDED_HOST = 'x-forwarded-host'
|
|
10
|
-
const FORWARDED_PORT = 'x-forwarded-port'
|
|
11
|
-
const FORWARDED_PROTO = 'x-forwarded-proto'
|
|
9
|
+
const FORWARDED_HOST = 'x-forwarded-host'
|
|
10
|
+
const FORWARDED_PORT = 'x-forwarded-port'
|
|
11
|
+
const FORWARDED_PROTO = 'x-forwarded-proto'
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Return the request with x-forwarded-host/port/proto injected from the request
|
|
@@ -16,26 +16,26 @@ const FORWARDED_PROTO = 'x-forwarded-proto';
|
|
|
16
16
|
* request when every value was already present (no allocation on the hot path).
|
|
17
17
|
*/
|
|
18
18
|
export function withForwardedHeaders(request: Request): Request {
|
|
19
|
-
const headers = request.headers
|
|
20
|
-
const hasHost = headers.has(FORWARDED_HOST)
|
|
21
|
-
const hasPort = headers.has(FORWARDED_PORT)
|
|
22
|
-
const hasProto = headers.has(FORWARDED_PROTO)
|
|
23
|
-
if (hasHost && hasPort && hasProto) return request
|
|
19
|
+
const headers = request.headers
|
|
20
|
+
const hasHost = headers.has(FORWARDED_HOST)
|
|
21
|
+
const hasPort = headers.has(FORWARDED_PORT)
|
|
22
|
+
const hasProto = headers.has(FORWARDED_PROTO)
|
|
23
|
+
if (hasHost && hasPort && hasProto) return request
|
|
24
24
|
|
|
25
|
-
let url: URL
|
|
25
|
+
let url: URL
|
|
26
26
|
try {
|
|
27
|
-
url = new URL(request.url)
|
|
27
|
+
url = new URL(request.url)
|
|
28
28
|
} catch {
|
|
29
|
-
return request
|
|
29
|
+
return request
|
|
30
30
|
}
|
|
31
|
-
const host = headers.get('host') ?? url.host
|
|
32
|
-
const proto = url.protocol.replace(':', '')
|
|
31
|
+
const host = headers.get('host') ?? url.host
|
|
32
|
+
const proto = url.protocol.replace(':', '')
|
|
33
33
|
// The server's own listen port (reflected in the request URL by the runtime).
|
|
34
|
-
const port = url.port
|
|
34
|
+
const port = url.port
|
|
35
35
|
|
|
36
|
-
const next = new Headers(headers)
|
|
37
|
-
if (!hasHost) next.set(FORWARDED_HOST, host)
|
|
38
|
-
if (!hasPort) next.set(FORWARDED_PORT, port)
|
|
39
|
-
if (!hasProto) next.set(FORWARDED_PROTO, proto)
|
|
40
|
-
return new Request(request, { headers: next })
|
|
36
|
+
const next = new Headers(headers)
|
|
37
|
+
if (!hasHost) next.set(FORWARDED_HOST, host)
|
|
38
|
+
if (!hasPort) next.set(FORWARDED_PORT, port)
|
|
39
|
+
if (!hasProto) next.set(FORWARDED_PROTO, proto)
|
|
40
|
+
return new Request(request, { headers: next })
|
|
41
41
|
}
|