@wular/pnext 0.0.3 → 0.0.6
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 +11 -11
- package/bin/pnext +1 -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 +1 -1
- package/reference/config.md +2 -2
- package/reference/css.md +13 -9
- package/reference/dev.md +1 -1
- package/reference/metadata.md +7 -7
- package/reference/navigation.md +35 -28
- package/reference/performance.md +70 -70
- package/reference/rendering.md +17 -17
- package/reference/routing.md +17 -17
- package/reference/typegen.md +12 -8
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +113 -109
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +49 -52
- 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 +71 -63
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +88 -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 +794 -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 +17 -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 +1988 -1961
- package/src/{api → client}/router/types.ts +93 -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 -1887
- 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 +69 -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 +2076 -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} +152 -143
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +442 -186
- 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 +69 -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 +833 -848
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +952 -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 +425 -404
- package/src/styles.d.ts +9 -0
- package/src/types.ts +320 -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/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
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
// `.message`, and the Next e2e suite substring-matches it verbatim off cliOutput. Runs as a build step
|
|
10
10
|
// gated on cacheComponents, ordered before the prerender pass so the build aborts before any shell work.
|
|
11
11
|
|
|
12
|
-
import type { ResolvedConfig } from '../../config'
|
|
13
|
-
import type { RouteManifestEntry } from '../../types'
|
|
14
|
-
import { staticParamsFor } from '../../render'
|
|
15
|
-
import { PnextBuildValidationError } from '../validation'
|
|
16
|
-
import { scanRootParams } from './root-params-scan'
|
|
12
|
+
import type { ResolvedConfig } from '../../config'
|
|
13
|
+
import type { RouteManifestEntry } from '../../types'
|
|
14
|
+
import { staticParamsFor } from '../../render/renderer'
|
|
15
|
+
import { PnextBuildValidationError } from '../validation/validate'
|
|
16
|
+
import { scanRootParams } from './root-params-scan'
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Convert a colon route pattern (`/:lang/blog/:slug`) to the bracket form Next
|
|
@@ -25,35 +25,33 @@ function toBracketPattern(pattern: string): string {
|
|
|
25
25
|
return pattern
|
|
26
26
|
.split('/')
|
|
27
27
|
.map(segment => {
|
|
28
|
-
if (!segment.startsWith(':')) return segment
|
|
29
|
-
let name = segment.slice(1)
|
|
30
|
-
let optional = false
|
|
31
|
-
let catchAll = false
|
|
28
|
+
if (!segment.startsWith(':')) return segment
|
|
29
|
+
let name = segment.slice(1)
|
|
30
|
+
let optional = false
|
|
31
|
+
let catchAll = false
|
|
32
32
|
if (name.endsWith('?')) {
|
|
33
|
-
optional = true
|
|
34
|
-
name = name.slice(0, -1)
|
|
33
|
+
optional = true
|
|
34
|
+
name = name.slice(0, -1)
|
|
35
35
|
}
|
|
36
36
|
if (name.endsWith('*') || name.endsWith('+')) {
|
|
37
|
-
catchAll = true
|
|
38
|
-
name = name.slice(0, -1)
|
|
37
|
+
catchAll = true
|
|
38
|
+
name = name.slice(0, -1)
|
|
39
39
|
}
|
|
40
|
-
if (catchAll) return optional ? `[[...${name}]]` : `[...${name}]
|
|
41
|
-
return `[${name}]
|
|
40
|
+
if (catchAll) return optional ? `[[...${name}]]` : `[...${name}]`
|
|
41
|
+
return `[${name}]`
|
|
42
42
|
})
|
|
43
|
-
.join('/')
|
|
43
|
+
.join('/')
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/** The keys generateStaticParams actually enumerated for this route. */
|
|
47
|
-
function providedParamKeys(
|
|
48
|
-
|
|
49
|
-
): Set<string> {
|
|
50
|
-
const provided = new Set<string>();
|
|
47
|
+
function providedParamKeys(allSets: Record<string, unknown>[]): Set<string> {
|
|
48
|
+
const provided = new Set<string>()
|
|
51
49
|
for (const set of allSets) {
|
|
52
50
|
for (const [key, value] of Object.entries(set)) {
|
|
53
|
-
if (value !== undefined) provided.add(key)
|
|
51
|
+
if (value !== undefined) provided.add(key)
|
|
54
52
|
}
|
|
55
53
|
}
|
|
56
|
-
return provided
|
|
54
|
+
return provided
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
/**
|
|
@@ -66,40 +64,38 @@ export async function validateRootParamsProvided(
|
|
|
66
64
|
config: ResolvedConfig,
|
|
67
65
|
routes: RouteManifestEntry[],
|
|
68
66
|
): Promise<void> {
|
|
69
|
-
const rootParams = scanRootParams(config.appPath)
|
|
70
|
-
if (rootParams.size === 0) return
|
|
67
|
+
const rootParams = scanRootParams(config.appPath)
|
|
68
|
+
if (rootParams.size === 0) return
|
|
71
69
|
|
|
72
|
-
const pageRoutes = routes.filter(
|
|
73
|
-
route => route.kind === 'page' && !route.interception,
|
|
74
|
-
);
|
|
70
|
+
const pageRoutes = routes.filter(route => route.kind === 'page' && !route.interception)
|
|
75
71
|
|
|
76
72
|
for (const route of pageRoutes) {
|
|
77
|
-
const routeRootParams = route.params.filter(name => rootParams.has(name))
|
|
78
|
-
if (routeRootParams.length === 0) continue
|
|
73
|
+
const routeRootParams = route.params.filter(name => rootParams.has(name))
|
|
74
|
+
if (routeRootParams.length === 0) continue
|
|
79
75
|
|
|
80
|
-
let provided: Set<string
|
|
76
|
+
let provided: Set<string>
|
|
81
77
|
try {
|
|
82
|
-
const staticParams = await staticParamsFor(config, route)
|
|
83
|
-
provided = providedParamKeys(staticParams.allSets)
|
|
78
|
+
const staticParams = await staticParamsFor(config, route)
|
|
79
|
+
provided = providedParamKeys(staticParams.allSets)
|
|
84
80
|
} catch {
|
|
85
81
|
// A generateStaticParams that throws provides nothing — treat every root
|
|
86
82
|
// param as missing rather than masking the (more relevant) config error.
|
|
87
|
-
provided = new Set<string>()
|
|
83
|
+
provided = new Set<string>()
|
|
88
84
|
}
|
|
89
85
|
|
|
90
|
-
const missing = routeRootParams.filter(name => !provided.has(name))
|
|
91
|
-
if (missing.length === 0) continue
|
|
86
|
+
const missing = routeRootParams.filter(name => !provided.has(name))
|
|
87
|
+
if (missing.length === 0) continue
|
|
92
88
|
|
|
93
|
-
const routePattern = toBracketPattern(route.route || '/')
|
|
89
|
+
const routePattern = toBracketPattern(route.route || '/')
|
|
94
90
|
if (missing.length === 1) {
|
|
95
91
|
throw new PnextBuildValidationError(
|
|
96
92
|
`Error: A required root parameter (${missing[0]}) was not provided in ` +
|
|
97
93
|
`generateStaticParams for ${routePattern}, please provide at least one value.`,
|
|
98
|
-
)
|
|
94
|
+
)
|
|
99
95
|
}
|
|
100
96
|
throw new PnextBuildValidationError(
|
|
101
97
|
`Error: Required root params (${missing.join(', ')}) were not provided in ` +
|
|
102
98
|
`generateStaticParams for ${routePattern}, please provide at least one value for each.`,
|
|
103
|
-
)
|
|
99
|
+
)
|
|
104
100
|
}
|
|
105
101
|
}
|
|
@@ -8,34 +8,34 @@
|
|
|
8
8
|
// The scan drives which names `next/root-params` legitimately exports (import validation) and typegen.
|
|
9
9
|
// Route-group and slot dirs never contribute params; catch-all segments contribute their param name.
|
|
10
10
|
|
|
11
|
-
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'
|
|
12
|
-
import path from 'node:path'
|
|
11
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'
|
|
12
|
+
import path from 'node:path'
|
|
13
13
|
|
|
14
|
-
const LAYOUT_BASENAMES = ['layout.tsx', 'layout.ts', 'layout.jsx', 'layout.js']
|
|
14
|
+
const LAYOUT_BASENAMES = ['layout.tsx', 'layout.ts', 'layout.jsx', 'layout.js']
|
|
15
15
|
|
|
16
16
|
/** True when a layout source renders `<html>` (i.e. it is a root/document layout). */
|
|
17
17
|
function isRootLayoutSource(source: string): boolean {
|
|
18
|
-
return /<html[\s>]/.test(source)
|
|
18
|
+
return /<html[\s>]/.test(source)
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** Extract the param name from a segment dir name, or undefined for a static one. */
|
|
22
22
|
function paramNameOfSegment(segment: string): string | undefined {
|
|
23
23
|
// [[...slug]] optional catch-all, [...slug] catch-all, [slug] dynamic.
|
|
24
|
-
const optional = /^\[\[\.\.\.(.+)\]\]$/.exec(segment)
|
|
25
|
-
if (optional) return optional[1]
|
|
26
|
-
const catchAll = /^\[\.\.\.(.+)\]$/.exec(segment)
|
|
27
|
-
if (catchAll) return catchAll[1]
|
|
28
|
-
const dynamic = /^\[(.+)\]$/.exec(segment)
|
|
29
|
-
if (dynamic) return dynamic[1]
|
|
30
|
-
return undefined
|
|
24
|
+
const optional = /^\[\[\.\.\.(.+)\]\]$/.exec(segment)
|
|
25
|
+
if (optional) return optional[1]
|
|
26
|
+
const catchAll = /^\[\.\.\.(.+)\]$/.exec(segment)
|
|
27
|
+
if (catchAll) return catchAll[1]
|
|
28
|
+
const dynamic = /^\[(.+)\]$/.exec(segment)
|
|
29
|
+
if (dynamic) return dynamic[1]
|
|
30
|
+
return undefined
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function findLayoutFile(dir: string): string | undefined {
|
|
34
34
|
for (const base of LAYOUT_BASENAMES) {
|
|
35
|
-
const candidate = path.join(dir, base)
|
|
36
|
-
if (existsSync(candidate)) return candidate
|
|
35
|
+
const candidate = path.join(dir, base)
|
|
36
|
+
if (existsSync(candidate)) return candidate
|
|
37
37
|
}
|
|
38
|
-
return undefined
|
|
38
|
+
return undefined
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -44,52 +44,52 @@ function findLayoutFile(dir: string): string | undefined {
|
|
|
44
44
|
* the app's root-param set.
|
|
45
45
|
*/
|
|
46
46
|
export function scanRootParams(appPath: string): Set<string> {
|
|
47
|
-
const rootParams = new Set<string>()
|
|
48
|
-
if (!existsSync(appPath)) return rootParams
|
|
47
|
+
const rootParams = new Set<string>()
|
|
48
|
+
if (!existsSync(appPath)) return rootParams
|
|
49
49
|
|
|
50
50
|
const walk = (dir: string, paramsAbove: string[]): void => {
|
|
51
|
-
const layoutFile = findLayoutFile(dir)
|
|
51
|
+
const layoutFile = findLayoutFile(dir)
|
|
52
52
|
if (layoutFile) {
|
|
53
|
-
let source = ''
|
|
53
|
+
let source = ''
|
|
54
54
|
try {
|
|
55
|
-
source = readFileSync(layoutFile, 'utf8')
|
|
55
|
+
source = readFileSync(layoutFile, 'utf8')
|
|
56
56
|
} catch {
|
|
57
|
-
source = ''
|
|
57
|
+
source = ''
|
|
58
58
|
}
|
|
59
59
|
if (isRootLayoutSource(source)) {
|
|
60
|
-
for (const name of paramsAbove) rootParams.add(name)
|
|
60
|
+
for (const name of paramsAbove) rootParams.add(name)
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
let children: string[] = []
|
|
63
|
+
let children: string[] = []
|
|
64
64
|
try {
|
|
65
|
-
children = readdirSync(dir)
|
|
65
|
+
children = readdirSync(dir)
|
|
66
66
|
} catch {
|
|
67
|
-
return
|
|
67
|
+
return
|
|
68
68
|
}
|
|
69
69
|
for (const child of children) {
|
|
70
|
-
const childPath = path.join(dir, child)
|
|
71
|
-
let isDir = false
|
|
70
|
+
const childPath = path.join(dir, child)
|
|
71
|
+
let isDir = false
|
|
72
72
|
try {
|
|
73
|
-
isDir = statSync(childPath).isDirectory()
|
|
73
|
+
isDir = statSync(childPath).isDirectory()
|
|
74
74
|
} catch {
|
|
75
|
-
isDir = false
|
|
75
|
+
isDir = false
|
|
76
76
|
}
|
|
77
|
-
if (!isDir) continue
|
|
78
|
-
if (child.startsWith('@')) continue
|
|
79
|
-
const param = paramNameOfSegment(child)
|
|
80
|
-
walk(childPath, param ? [...paramsAbove, param] : paramsAbove)
|
|
77
|
+
if (!isDir) continue
|
|
78
|
+
if (child.startsWith('@')) continue // parallel-route slot dir
|
|
79
|
+
const param = paramNameOfSegment(child)
|
|
80
|
+
walk(childPath, param ? [...paramsAbove, param] : paramsAbove)
|
|
81
81
|
}
|
|
82
|
-
}
|
|
82
|
+
}
|
|
83
83
|
|
|
84
|
-
walk(appPath, [])
|
|
85
|
-
return rootParams
|
|
84
|
+
walk(appPath, [])
|
|
85
|
+
return rootParams
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
export type RootParamValueType = 'string' | 'string[]' | 'undefined'
|
|
88
|
+
export type RootParamValueType = 'string' | 'string[]' | 'undefined'
|
|
89
89
|
|
|
90
90
|
interface ScannedParam {
|
|
91
|
-
name: string
|
|
92
|
-
segment: string
|
|
91
|
+
name: string
|
|
92
|
+
segment: string
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
/**
|
|
@@ -99,20 +99,20 @@ interface ScannedParam {
|
|
|
99
99
|
* layouts, a param absent from some root also gains `undefined`.
|
|
100
100
|
*/
|
|
101
101
|
export function scanRootParamTypes(appPath: string): Map<string, Set<RootParamValueType>> {
|
|
102
|
-
const roots: Map<string, RootParamValueType[]>[] = []
|
|
103
|
-
if (!existsSync(appPath)) return new Map()
|
|
102
|
+
const roots: Map<string, RootParamValueType[]>[] = []
|
|
103
|
+
if (!existsSync(appPath)) return new Map()
|
|
104
104
|
|
|
105
105
|
const walk = (dir: string, paramsAbove: ScannedParam[]): void => {
|
|
106
|
-
const layoutFile = findLayoutFile(dir)
|
|
106
|
+
const layoutFile = findLayoutFile(dir)
|
|
107
107
|
if (layoutFile) {
|
|
108
|
-
let source = ''
|
|
108
|
+
let source = ''
|
|
109
109
|
try {
|
|
110
|
-
source = readFileSync(layoutFile, 'utf8')
|
|
110
|
+
source = readFileSync(layoutFile, 'utf8')
|
|
111
111
|
} catch {
|
|
112
|
-
source = ''
|
|
112
|
+
source = ''
|
|
113
113
|
}
|
|
114
114
|
if (isRootLayoutSource(source)) {
|
|
115
|
-
const params = new Map<string, RootParamValueType[]>()
|
|
115
|
+
const params = new Map<string, RootParamValueType[]>()
|
|
116
116
|
for (const { name, segment } of paramsAbove) {
|
|
117
117
|
params.set(
|
|
118
118
|
name,
|
|
@@ -121,44 +121,44 @@ export function scanRootParamTypes(appPath: string): Map<string, Set<RootParamVa
|
|
|
121
121
|
: segment.startsWith('[...')
|
|
122
122
|
? ['string[]']
|
|
123
123
|
: ['string'],
|
|
124
|
-
)
|
|
124
|
+
)
|
|
125
125
|
}
|
|
126
|
-
roots.push(params)
|
|
126
|
+
roots.push(params)
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
-
let children: string[] = []
|
|
129
|
+
let children: string[] = []
|
|
130
130
|
try {
|
|
131
|
-
children = readdirSync(dir)
|
|
131
|
+
children = readdirSync(dir)
|
|
132
132
|
} catch {
|
|
133
|
-
return
|
|
133
|
+
return
|
|
134
134
|
}
|
|
135
135
|
for (const child of children) {
|
|
136
|
-
const childPath = path.join(dir, child)
|
|
137
|
-
let isDir = false
|
|
136
|
+
const childPath = path.join(dir, child)
|
|
137
|
+
let isDir = false
|
|
138
138
|
try {
|
|
139
|
-
isDir = statSync(childPath).isDirectory()
|
|
139
|
+
isDir = statSync(childPath).isDirectory()
|
|
140
140
|
} catch {
|
|
141
|
-
isDir = false
|
|
141
|
+
isDir = false
|
|
142
142
|
}
|
|
143
|
-
if (!isDir) continue
|
|
144
|
-
if (child.startsWith('@')) continue
|
|
145
|
-
const param = paramNameOfSegment(child)
|
|
146
|
-
walk(childPath, param ? [...paramsAbove, { name: param, segment: child }] : paramsAbove)
|
|
143
|
+
if (!isDir) continue
|
|
144
|
+
if (child.startsWith('@')) continue // parallel-route slot dir
|
|
145
|
+
const param = paramNameOfSegment(child)
|
|
146
|
+
walk(childPath, param ? [...paramsAbove, { name: param, segment: child }] : paramsAbove)
|
|
147
147
|
}
|
|
148
|
-
}
|
|
148
|
+
}
|
|
149
149
|
|
|
150
|
-
walk(appPath, [])
|
|
150
|
+
walk(appPath, [])
|
|
151
151
|
|
|
152
|
-
const combined = new Map<string, Set<RootParamValueType>>()
|
|
152
|
+
const combined = new Map<string, Set<RootParamValueType>>()
|
|
153
153
|
for (const params of roots) {
|
|
154
154
|
for (const [name, types] of params) {
|
|
155
|
-
const set = combined.get(name) ?? new Set<RootParamValueType>()
|
|
156
|
-
for (const type of types) set.add(type)
|
|
157
|
-
combined.set(name, set)
|
|
155
|
+
const set = combined.get(name) ?? new Set<RootParamValueType>()
|
|
156
|
+
for (const type of types) set.add(type)
|
|
157
|
+
combined.set(name, set)
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
for (const [name, set] of combined) {
|
|
161
|
-
if (roots.some(params => !params.has(name))) set.add('undefined')
|
|
161
|
+
if (roots.some(params => !params.has(name))) set.add('undefined')
|
|
162
162
|
}
|
|
163
|
-
return combined
|
|
163
|
+
return combined
|
|
164
164
|
}
|
|
@@ -14,18 +14,18 @@
|
|
|
14
14
|
// the Proxy. Build-time validation that a name is actually a root param lives in root-params-scan.ts;
|
|
15
15
|
// this transform stays permissive.
|
|
16
16
|
|
|
17
|
-
import { isIdentifier, uniqueIdentifier } from '../../utils/
|
|
17
|
+
import { isIdentifier, uniqueIdentifier } from '../../utils/code'
|
|
18
18
|
|
|
19
|
-
const ROOT_PARAMS_SPECIFIER = /['"]next\/root-params['"]
|
|
19
|
+
const ROOT_PARAMS_SPECIFIER = /['"]next\/root-params['"]/
|
|
20
20
|
|
|
21
21
|
// `[^}]` for the clause, never a lazy `[\s\S]*?`: the latter backtracks across
|
|
22
22
|
// an earlier `import { X } from 'react'` and swallows that line too.
|
|
23
23
|
const IMPORT_RE =
|
|
24
|
-
/^[ \t]*import\s+\{([^}]*)\}\s+from\s+['"]next\/root-params['"]\s*;?[ \t]*(?:\r?\n)?/gm
|
|
24
|
+
/^[ \t]*import\s+\{([^}]*)\}\s+from\s+['"]next\/root-params['"]\s*;?[ \t]*(?:\r?\n)?/gm
|
|
25
25
|
|
|
26
26
|
interface Binding {
|
|
27
|
-
imported: string
|
|
28
|
-
local: string
|
|
27
|
+
imported: string
|
|
28
|
+
local: string
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function parseBindings(clause: string): Binding[] {
|
|
@@ -34,13 +34,13 @@ function parseBindings(clause: string): Binding[] {
|
|
|
34
34
|
.map(part => part.trim())
|
|
35
35
|
.filter(Boolean)
|
|
36
36
|
.flatMap(part => {
|
|
37
|
-
if (part.startsWith('type ')) return []
|
|
38
|
-
const [importedRaw, localRaw] = part.split(/\s+as\s+/)
|
|
39
|
-
const imported = importedRaw?.trim()
|
|
40
|
-
const local = (localRaw ?? importedRaw)?.trim()
|
|
41
|
-
if (!imported || !local || !isIdentifier(imported) || !isIdentifier(local)) return []
|
|
42
|
-
return [{ imported, local }]
|
|
43
|
-
})
|
|
37
|
+
if (part.startsWith('type ')) return []
|
|
38
|
+
const [importedRaw, localRaw] = part.split(/\s+as\s+/)
|
|
39
|
+
const imported = importedRaw?.trim()
|
|
40
|
+
const local = (localRaw ?? importedRaw)?.trim()
|
|
41
|
+
if (!imported || !local || !isIdentifier(imported) || !isIdentifier(local)) return []
|
|
42
|
+
return [{ imported, local }]
|
|
43
|
+
})
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -49,27 +49,25 @@ function parseBindings(clause: string): Binding[] {
|
|
|
49
49
|
* source transform and applied in the client bundler plugin.
|
|
50
50
|
*/
|
|
51
51
|
export function rewriteRootParamsSource(source: string): string {
|
|
52
|
-
if (!ROOT_PARAMS_SPECIFIER.test(source)) return source
|
|
53
|
-
const proxyName = uniqueIdentifier(source, '__pnextRootParams')
|
|
54
|
-
const declarations: string[] = []
|
|
55
|
-
let importedProxy = false
|
|
52
|
+
if (!ROOT_PARAMS_SPECIFIER.test(source)) return source
|
|
53
|
+
const proxyName = uniqueIdentifier(source, '__pnextRootParams')
|
|
54
|
+
const declarations: string[] = []
|
|
55
|
+
let importedProxy = false
|
|
56
56
|
|
|
57
57
|
const rewritten = source.replace(IMPORT_RE, (_statement, clause: string) => {
|
|
58
|
-
const bindings = parseBindings(clause)
|
|
59
|
-
if (bindings.length === 0) return ''
|
|
60
|
-
importedProxy = true
|
|
58
|
+
const bindings = parseBindings(clause)
|
|
59
|
+
if (bindings.length === 0) return ''
|
|
60
|
+
importedProxy = true
|
|
61
61
|
for (const { imported, local } of bindings) {
|
|
62
|
-
declarations.push(
|
|
63
|
-
`const ${local} = ${proxyName}[${JSON.stringify(imported)}];`,
|
|
64
|
-
);
|
|
62
|
+
declarations.push(`const ${local} = ${proxyName}[${JSON.stringify(imported)}];`)
|
|
65
63
|
}
|
|
66
|
-
return ''
|
|
67
|
-
})
|
|
64
|
+
return ''
|
|
65
|
+
})
|
|
68
66
|
|
|
69
|
-
if (!importedProxy) return source
|
|
67
|
+
if (!importedProxy) return source
|
|
70
68
|
return [
|
|
71
69
|
`import ${proxyName} from ${JSON.stringify('next/root-params')};`,
|
|
72
70
|
...declarations,
|
|
73
71
|
rewritten,
|
|
74
|
-
].join('\n')
|
|
72
|
+
].join('\n')
|
|
75
73
|
}
|
|
@@ -8,23 +8,23 @@
|
|
|
8
8
|
// a build/dev error there - so this runtime is intentionally permissive and a valid getter always works.
|
|
9
9
|
// Context errors (server action / route handler / unstable_cache) match Next's messages exactly.
|
|
10
10
|
|
|
11
|
-
import { currentParams, currentRequest, getWorkUnit } from '../../request/context'
|
|
11
|
+
import { currentParams, currentRequest, getWorkUnit } from '../../request/context'
|
|
12
12
|
import {
|
|
13
13
|
cacheComponents,
|
|
14
14
|
hangingPromise,
|
|
15
15
|
isPrerendering,
|
|
16
16
|
isRuntimePrefetchPrerender,
|
|
17
|
-
} from '../../ppr'
|
|
18
|
-
import { insideUnstableCacheProducer } from '../cache/revalidate'
|
|
19
|
-
import { insideUseCacheProducer, recordUseCacheRootParamRead } from '../cache/use-cache'
|
|
17
|
+
} from '../../render/ppr'
|
|
18
|
+
import { insideUnstableCacheProducer } from '../cache/revalidate'
|
|
19
|
+
import { insideUseCacheProducer, recordUseCacheRootParamRead } from '../cache/use-cache'
|
|
20
20
|
|
|
21
21
|
/** E-code errors Next throws for root-params used in an unsupported context. */
|
|
22
22
|
function rootParamContextError(name: string): Error | undefined {
|
|
23
|
-
const unit = getWorkUnit()
|
|
24
|
-
const call = `\`import('next/root-params').${name}()
|
|
23
|
+
const unit = getWorkUnit()
|
|
24
|
+
const call = `\`import('next/root-params').${name}()\``
|
|
25
25
|
|
|
26
|
-
const inUseCache = insideUseCacheProducer()
|
|
27
|
-
const inUnstableCache = insideUnstableCacheProducer()
|
|
26
|
+
const inUseCache = insideUseCacheProducer()
|
|
27
|
+
const inUnstableCache = insideUnstableCacheProducer()
|
|
28
28
|
|
|
29
29
|
// Root params inside a `use cache` NESTED within `unstable_cache`: E1140.
|
|
30
30
|
// (The `use cache` scope sits inside the unstable_cache producer, so both
|
|
@@ -35,15 +35,15 @@ function rootParamContextError(name: string): Error | undefined {
|
|
|
35
35
|
`Root params (${call}) were used inside a cache scope nested within \`unstable_cache\`. Root params are not available in this context.`,
|
|
36
36
|
),
|
|
37
37
|
{ digest: 'E1140' },
|
|
38
|
-
)
|
|
38
|
+
)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
// Inside a plain `use cache` (not under unstable_cache): legal. Record the
|
|
42
42
|
// read so the entry's cache key participates in this root param (Stage B-3),
|
|
43
43
|
// then let the getter resolve the value below (no error).
|
|
44
44
|
if (inUseCache) {
|
|
45
|
-
recordUseCacheRootParamRead(name)
|
|
46
|
-
return undefined
|
|
45
|
+
recordUseCacheRootParamRead(name)
|
|
46
|
+
return undefined
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Inside `unstable_cache` (a data-cache producer that is NOT a `use cache`
|
|
@@ -54,34 +54,34 @@ function rootParamContextError(name: string): Error | undefined {
|
|
|
54
54
|
`Root params (${call}) were used inside \`unstable_cache\`. This is not supported. Use \`"use cache"\` instead.`,
|
|
55
55
|
),
|
|
56
56
|
{ digest: 'E1141' },
|
|
57
|
-
)
|
|
57
|
+
)
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
if (!unit) return undefined
|
|
60
|
+
if (!unit) return undefined
|
|
61
61
|
|
|
62
62
|
if (unit.phase === 'action') {
|
|
63
63
|
return new Error(
|
|
64
64
|
`${call} was used inside a Server Action. This is not supported. ` +
|
|
65
65
|
`Functions from 'next/root-params' can only be called in the context of a route.`,
|
|
66
|
-
)
|
|
66
|
+
)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// Route handlers are detected via routeKind (core sets no 'handler' phase).
|
|
70
70
|
if (unit.phase !== 'after' && unit.routeKind === 'route-handler') {
|
|
71
71
|
const route = (() => {
|
|
72
72
|
try {
|
|
73
|
-
return new URL(currentRequest()?.url ?? '').pathname
|
|
73
|
+
return new URL(currentRequest()?.url ?? '').pathname
|
|
74
74
|
} catch {
|
|
75
|
-
return ''
|
|
75
|
+
return ''
|
|
76
76
|
}
|
|
77
|
-
})()
|
|
77
|
+
})()
|
|
78
78
|
return new Error(
|
|
79
79
|
`Route ${route} used ${call} inside a Route Handler. ` +
|
|
80
80
|
`Support for this API in Route Handlers is planned for a future version of Next.js.`,
|
|
81
|
-
)
|
|
81
|
+
)
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
return undefined
|
|
84
|
+
return undefined
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
@@ -90,8 +90,8 @@ function rootParamContextError(name: string): Error | undefined {
|
|
|
90
90
|
* resolves to undefined.
|
|
91
91
|
*/
|
|
92
92
|
export function rootParam<T = string | string[] | undefined>(name: string): Promise<T> {
|
|
93
|
-
const error = rootParamContextError(name)
|
|
94
|
-
if (error) return Promise.reject(error)
|
|
93
|
+
const error = rootParamContextError(name)
|
|
94
|
+
if (error) return Promise.reject(error)
|
|
95
95
|
// A runtime-prefetch prerender renders against the REAL sampled request, so root params are concrete
|
|
96
96
|
// there (root params are always available in static prerenders, so a runtime prefetch has them too).
|
|
97
97
|
// Hanging them would postpone the root layout itself - the whole document, not a boundary - and the
|
|
@@ -102,10 +102,10 @@ export function rootParam<T = string | string[] | undefined>(name: string): Prom
|
|
|
102
102
|
isPrerendering() &&
|
|
103
103
|
!isRuntimePrefetchPrerender()
|
|
104
104
|
) {
|
|
105
|
-
return hangingPromise<T>(`rootParam(${name})`)
|
|
105
|
+
return hangingPromise<T>(`rootParam(${name})`)
|
|
106
106
|
}
|
|
107
|
-
const params = currentParams()
|
|
108
|
-
return Promise.resolve(params[name] as T)
|
|
107
|
+
const params = currentParams()
|
|
108
|
+
return Promise.resolve(params[name] as T)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
@@ -118,12 +118,12 @@ const rootParamsModule = new Proxy(
|
|
|
118
118
|
{},
|
|
119
119
|
{
|
|
120
120
|
get(_target, prop: string | symbol): unknown {
|
|
121
|
-
if (typeof prop !== 'string') return undefined
|
|
122
|
-
if (prop === '__esModule') return true
|
|
123
|
-
if (prop === 'default') return undefined
|
|
124
|
-
return () => rootParam(prop)
|
|
121
|
+
if (typeof prop !== 'string') return undefined
|
|
122
|
+
if (prop === '__esModule') return true
|
|
123
|
+
if (prop === 'default') return undefined
|
|
124
|
+
return () => rootParam(prop)
|
|
125
125
|
},
|
|
126
126
|
},
|
|
127
|
-
) as Record<string, () => Promise<unknown
|
|
127
|
+
) as Record<string, () => Promise<unknown>>
|
|
128
128
|
|
|
129
|
-
export default rootParamsModule
|
|
129
|
+
export default rootParamsModule
|
|
@@ -9,17 +9,16 @@ export const INCOMPATIBLE_SEGMENT_KEYS = [
|
|
|
9
9
|
'dynamicParams',
|
|
10
10
|
'dynamic',
|
|
11
11
|
'fetchCache',
|
|
12
|
-
] as const
|
|
12
|
+
] as const
|
|
13
13
|
|
|
14
|
-
export type IncompatibleSegmentKey = (typeof INCOMPATIBLE_SEGMENT_KEYS)[number]
|
|
14
|
+
export type IncompatibleSegmentKey = (typeof INCOMPATIBLE_SEGMENT_KEYS)[number]
|
|
15
15
|
|
|
16
16
|
/** Next's exact incompat message for an offending segment-config export. */
|
|
17
17
|
export function segmentConfigIncompatMessage(key: IncompatibleSegmentKey, file: string): string {
|
|
18
|
-
return `"${key}" is not compatible with \`nextConfig.cacheComponents\`. Please remove it. Used in ${file}
|
|
18
|
+
return `"${key}" is not compatible with \`nextConfig.cacheComponents\`. Please remove it. Used in ${file}`
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const EXPORT_RE = (key: string) =>
|
|
22
|
-
new RegExp(`\\bexport\\s+const\\s+${key}\\b`);
|
|
21
|
+
const EXPORT_RE = (key: string) => new RegExp(`\\bexport\\s+const\\s+${key}\\b`)
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* Scan a page/layout source for an incompatible segment-config export, returning
|
|
@@ -28,7 +27,7 @@ const EXPORT_RE = (key: string) =>
|
|
|
28
27
|
*/
|
|
29
28
|
export function findIncompatibleSegmentKey(source: string): IncompatibleSegmentKey | undefined {
|
|
30
29
|
for (const key of INCOMPATIBLE_SEGMENT_KEYS) {
|
|
31
|
-
if (EXPORT_RE(key).test(source)) return key
|
|
30
|
+
if (EXPORT_RE(key).test(source)) return key
|
|
32
31
|
}
|
|
33
|
-
return undefined
|
|
32
|
+
return undefined
|
|
34
33
|
}
|