vinext 0.0.49 → 0.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/client-build-config.js.map +1 -1
- package/dist/build/google-fonts/build-url.js.map +1 -1
- package/dist/build/google-fonts/get-axes.js.map +1 -1
- package/dist/build/google-fonts/sort-variants.js.map +1 -1
- package/dist/build/google-fonts/validate.js.map +1 -1
- package/dist/build/layout-classification.js.map +1 -1
- package/dist/build/nitro-route-rules.js.map +1 -1
- package/dist/build/precompress.js.map +1 -1
- package/dist/build/prerender.d.ts +17 -1
- package/dist/build/prerender.js +77 -16
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.js.map +1 -1
- package/dist/build/route-classification-injector.js.map +1 -1
- package/dist/build/route-classification-manifest.js.map +1 -1
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/server-manifest.js.map +1 -1
- package/dist/build/ssr-manifest.js.map +1 -1
- package/dist/build/standalone.js.map +1 -1
- package/dist/build/static-export.js.map +1 -1
- package/dist/check.js +1 -1
- package/dist/check.js.map +1 -1
- package/dist/cli-args.js.map +1 -1
- package/dist/cli.js +8 -4
- package/dist/cli.js.map +1 -1
- package/dist/client/instrumentation-client-state.js.map +1 -1
- package/dist/client/validate-module-path.js.map +1 -1
- package/dist/client/vinext-next-data.d.ts +5 -1
- package/dist/client/window-next.d.ts +149 -0
- package/dist/client/window-next.js +48 -0
- package/dist/client/window-next.js.map +1 -0
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.js +2 -1
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +3 -1
- package/dist/config/config-matchers.js +5 -4
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +13 -2
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +13 -5
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +3 -1
- package/dist/entries/app-browser-entry.js +11 -2
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.js +11 -0
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.js +4 -0
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/app-ssr-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-entry-helpers.js.map +1 -1
- package/dist/entries/pages-server-entry.js +15 -0
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +76 -18
- package/dist/index.js.map +1 -1
- package/dist/init.js.map +1 -1
- package/dist/plugins/async-hooks-stub.js.map +1 -1
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/plugins/fonts.js.map +1 -1
- package/dist/plugins/instrumentation-client.js.map +1 -1
- package/dist/plugins/og-assets.js.map +1 -1
- package/dist/plugins/optimize-imports.js.map +1 -1
- package/dist/plugins/postcss.js.map +1 -1
- package/dist/plugins/rsc-client-reference-loaders.d.ts +7 -0
- package/dist/plugins/rsc-client-reference-loaders.js +48 -0
- package/dist/plugins/rsc-client-reference-loaders.js.map +1 -0
- package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
- package/dist/plugins/server-externals-manifest.js.map +1 -1
- package/dist/plugins/strip-server-exports.js.map +1 -1
- package/dist/routing/app-route-graph.d.ts +48 -5
- package/dist/routing/app-route-graph.js +159 -15
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-matching.js.map +1 -1
- package/dist/routing/route-pattern.js.map +1 -1
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/routing/route-validation.js.map +1 -1
- package/dist/routing/utils.js.map +1 -1
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-action-result.d.ts +19 -0
- package/dist/server/app-browser-action-result.js +18 -0
- package/dist/server/app-browser-action-result.js.map +1 -0
- package/dist/server/app-browser-entry.js +91 -48
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-error.js.map +1 -1
- package/dist/server/app-browser-hydration.d.ts +19 -0
- package/dist/server/app-browser-hydration.js +22 -0
- package/dist/server/app-browser-hydration.js.map +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +6 -3
- package/dist/server/app-browser-navigation-controller.js +67 -19
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-browser-state.d.ts +17 -17
- package/dist/server/app-browser-state.js +122 -36
- package/dist/server/app-browser-state.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +4 -0
- package/dist/server/app-browser-stream.js +24 -2
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +34 -19
- package/dist/server/app-browser-visible-commit.js.map +1 -1
- package/dist/server/app-client-reference-preloader.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +17 -1
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-hook-warning-suppression.js.map +1 -1
- package/dist/server/app-middleware.d.ts +1 -1
- package/dist/server/app-middleware.js +4 -9
- package/dist/server/app-middleware.js.map +1 -1
- package/dist/server/app-mounted-slots-header.js.map +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +14 -13
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +1 -0
- package/dist/server/app-page-boundary.js +7 -5
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +10 -3
- package/dist/server/app-page-cache.js +42 -23
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +6 -1
- package/dist/server/app-page-dispatch.js +21 -7
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.d.ts +3 -1
- package/dist/server/app-page-element-builder.js +6 -2
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-head.js +4 -0
- package/dist/server/app-page-head.js.map +1 -1
- package/dist/server/app-page-method.js.map +1 -1
- package/dist/server/app-page-params.js.map +1 -1
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +7 -1
- package/dist/server/app-page-render.js +11 -4
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +2 -0
- package/dist/server/app-page-response.js +15 -5
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +6 -2
- package/dist/server/app-page-route-wiring.js +50 -49
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-segment-state.d.ts +10 -0
- package/dist/server/app-page-segment-state.js +87 -0
- package/dist/server/app-page-segment-state.js.map +1 -0
- package/dist/server/app-page-stream.d.ts +7 -2
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-post-middleware-context.js.map +1 -1
- package/dist/server/app-prerender-endpoints.js.map +1 -1
- package/dist/server/app-prerender-static-params.js.map +1 -1
- package/dist/server/app-render-dependency.js.map +1 -1
- package/dist/server/app-request-context.js.map +1 -1
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-dispatch.js.map +1 -1
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-policy.js +1 -0
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.js +4 -3
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-router-entry.js +6 -2
- package/dist/server/app-router-entry.js.map +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +5 -2
- package/dist/server/app-rsc-cache-busting.js +40 -19
- package/dist/server/app-rsc-cache-busting.js.map +1 -1
- package/dist/server/app-rsc-error-handler.js.map +1 -1
- package/dist/server/app-rsc-errors.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +10 -1
- package/dist/server/app-rsc-handler.js +51 -17
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-render-mode.d.ts +11 -0
- package/dist/server/app-rsc-render-mode.js +21 -0
- package/dist/server/app-rsc-render-mode.js.map +1 -0
- package/dist/server/app-rsc-request-normalization.d.ts +4 -1
- package/dist/server/app-rsc-request-normalization.js +7 -2
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -1
- package/dist/server/app-rsc-response-finalizer.js +6 -1
- package/dist/server/app-rsc-response-finalizer.js.map +1 -1
- package/dist/server/app-rsc-route-matching.js.map +1 -1
- package/dist/server/app-segment-config.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +16 -2
- package/dist/server/app-server-action-execution.js +79 -23
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +10 -4
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/app-static-generation.js.map +1 -1
- package/dist/server/artifact-compatibility.js.map +1 -1
- package/dist/server/cache-control.js +1 -0
- package/dist/server/cache-control.js.map +1 -1
- package/dist/server/cache-proof.js.map +1 -1
- package/dist/server/csp.js.map +1 -1
- package/dist/server/dev-error-overlay-store.js.map +1 -1
- package/dist/server/dev-error-overlay.js +5 -0
- package/dist/server/dev-error-overlay.js.map +1 -1
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-origin-check.js.map +1 -1
- package/dist/server/dev-route-files.js.map +1 -1
- package/dist/server/dev-server.js +8 -5
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/file-based-metadata.js.map +1 -1
- package/dist/server/headers.d.ts +79 -0
- package/dist/server/headers.js +101 -0
- package/dist/server/headers.js.map +1 -0
- package/dist/server/html.js.map +1 -1
- package/dist/server/http-error-responses.js.map +1 -1
- package/dist/server/image-optimization.d.ts +11 -1
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/implicit-tags.js.map +1 -1
- package/dist/server/instrumentation-runtime.js.map +1 -1
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +10 -1
- package/dist/server/isr-cache.js +12 -3
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-route-build-data.js.map +1 -1
- package/dist/server/metadata-route-response.js.map +1 -1
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware-matcher.js.map +1 -1
- package/dist/server/middleware-request-headers.d.ts +4 -1
- package/dist/server/middleware-request-headers.js +15 -8
- package/dist/server/middleware-request-headers.js.map +1 -1
- package/dist/server/middleware-response-headers.d.ts +2 -1
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-response-headers.js.map +1 -1
- package/dist/server/middleware-runtime.d.ts +1 -0
- package/dist/server/middleware-runtime.js +6 -3
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/navigation-planner.d.ts +119 -0
- package/dist/server/navigation-planner.js +171 -0
- package/dist/server/navigation-planner.js.map +1 -0
- package/dist/server/navigation-trace.d.ts +12 -2
- package/dist/server/navigation-trace.js +13 -1
- package/dist/server/navigation-trace.js.map +1 -1
- package/dist/server/next-error-digest.d.ts +3 -2
- package/dist/server/next-error-digest.js +4 -2
- package/dist/server/next-error-digest.js.map +1 -1
- package/dist/server/normalize-path.js.map +1 -1
- package/dist/server/pages-api-route.js.map +1 -1
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-media-type.js.map +1 -1
- package/dist/server/pages-node-compat.js.map +1 -1
- package/dist/server/pages-page-data.js +5 -2
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.js +3 -2
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prerender-work-unit-setup.js +1 -1
- package/dist/server/prerender-work-unit-setup.js.map +1 -1
- package/dist/server/prod-server.js +35 -13
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/request-log.js.map +1 -1
- package/dist/server/request-pipeline.d.ts +1 -13
- package/dist/server/request-pipeline.js +3 -25
- package/dist/server/request-pipeline.js.map +1 -1
- package/dist/server/rsc-stream-hints.js.map +1 -1
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/server-action-not-found.js +3 -3
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/socket-error-backstop.js.map +1 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/server/worker-utils.d.ts +0 -7
- package/dist/server/worker-utils.js +3 -2
- package/dist/server/worker-utils.js.map +1 -1
- package/dist/shims/amp.js.map +1 -1
- package/dist/shims/app.d.ts +37 -4
- package/dist/shims/app.js +50 -1
- package/dist/shims/app.js.map +1 -0
- package/dist/shims/cache-for-request.js.map +1 -1
- package/dist/shims/cache-runtime.js +20 -8
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +15 -3
- package/dist/shims/cache.js +99 -15
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/client-hook-error.js.map +1 -1
- package/dist/shims/compat-router.js.map +1 -1
- package/dist/shims/config.js.map +1 -1
- package/dist/shims/constants.js.map +1 -1
- package/dist/shims/document.js.map +1 -1
- package/dist/shims/dynamic.d.ts +18 -10
- package/dist/shims/dynamic.js +107 -51
- package/dist/shims/dynamic.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +35 -6
- package/dist/shims/error-boundary.js +118 -33
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +22 -1
- package/dist/shims/fetch-cache.js +124 -13
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/form.js +3 -1
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/head.d.ts +3 -1
- package/dist/shims/head.js +28 -16
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +4 -2
- package/dist/shims/headers.js +24 -7
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-context.js.map +1 -1
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/image-config.d.ts +14 -1
- package/dist/shims/image-config.js +24 -1
- package/dist/shims/image-config.js.map +1 -1
- package/dist/shims/image.js +15 -2
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/als-registry.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +1 -0
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/internal/cookie-serialize.js.map +1 -1
- package/dist/shims/internal/make-hanging-promise.d.ts +1 -1
- package/dist/shims/internal/make-hanging-promise.js +1 -1
- package/dist/shims/internal/make-hanging-promise.js.map +1 -1
- package/dist/shims/internal/parse-cookie-header.js.map +1 -1
- package/dist/shims/internal/utils.js.map +1 -1
- package/dist/shims/internal/work-unit-async-storage.js +2 -2
- package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
- package/dist/shims/layout-segment-context.js.map +1 -1
- package/dist/shims/legacy-image.js.map +1 -1
- package/dist/shims/link-prefetch.d.ts +34 -0
- package/dist/shims/link-prefetch.js +40 -0
- package/dist/shims/link-prefetch.js.map +1 -0
- package/dist/shims/link.d.ts +27 -4
- package/dist/shims/link.js +91 -27
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +22 -1
- package/dist/shims/navigation.js +30 -15
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/navigation.react-server.js.map +1 -1
- package/dist/shims/offline.js.map +1 -1
- package/dist/shims/readonly-url-search-params.js.map +1 -1
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/root-params.js.map +1 -1
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +38 -2
- package/dist/shims/router.js +45 -17
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script-nonce-context.js.map +1 -1
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.js +10 -14
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/slot.d.ts +6 -1
- package/dist/shims/slot.js +20 -7
- package/dist/shims/slot.js.map +1 -1
- package/dist/shims/thenable-params.js.map +1 -1
- package/dist/shims/unified-request-context.js +3 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/url-safety.js.map +1 -1
- package/dist/shims/url-utils.d.ts +2 -1
- package/dist/shims/url-utils.js +10 -1
- package/dist/shims/url-utils.js.map +1 -1
- package/dist/shims/use-merged-ref.js.map +1 -1
- package/dist/shims/web-vitals.d.ts +4 -21
- package/dist/shims/web-vitals.js +19 -6
- package/dist/shims/web-vitals.js.map +1 -1
- package/dist/utils/base-path.js.map +1 -1
- package/dist/utils/cache-control-metadata.js.map +1 -1
- package/dist/utils/domain-locale.js.map +1 -1
- package/dist/utils/encode-cache-tag.d.ts +31 -0
- package/dist/utils/encode-cache-tag.js +38 -0
- package/dist/utils/encode-cache-tag.js.map +1 -0
- package/dist/utils/error-cause.js.map +1 -1
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/lazy-chunks.js.map +1 -1
- package/dist/utils/manifest-paths.js.map +1 -1
- package/dist/utils/mdx-scan.js.map +1 -1
- package/dist/utils/navigation-signal.d.ts +6 -0
- package/dist/utils/navigation-signal.js +14 -0
- package/dist/utils/navigation-signal.js.map +1 -0
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/public-routes.js.map +1 -1
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/safe-json-file.js.map +1 -1
- package/dist/utils/text-stream.js.map +1 -1
- package/dist/utils/vinext-root.js.map +1 -1
- package/package.json +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-serialize.js","names":[],"sources":["../../../src/shims/internal/cookie-serialize.ts"],"sourcesContent":["/**\n * Shared Set-Cookie serialization for the next/headers and next/server shims.\n *\n * Two call sites — `cookies().set()` in headers.ts and `ResponseCookies.set()`\n * in server.ts — produce identical Set-Cookie header strings. Keep the\n * encoding, attribute order, and validation in one place so subtle RFC 6265\n * details (escaping, attribute ordering, etc.) cannot drift between them.\n *\n * Note: this is a value-encoding helper for response cookies only. The\n * request `Cookie:` header serialization in `RequestCookies._serialize`\n * (server.ts) intentionally lives separately — it builds a different format\n * (no attributes, just `name=value; name=value`) and shouldn't share this\n * code.\n */\n\ntype SerializeSetCookieOptions = {\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n};\n\n/**\n * RFC 6265 §4.1.1: cookie-name is a token (RFC 2616 §2.2).\n * Allowed: any visible ASCII (0x21-0x7E) except separators: ()<>@,;:\\\"/[]?={}\n */\nconst VALID_COOKIE_NAME_RE =\n /^[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2E\\x30-\\x39\\x41-\\x5A\\x5E-\\x7A\\x7C\\x7E]+$/;\n\nexport function validateCookieName(name: string): void {\n if (!name || !VALID_COOKIE_NAME_RE.test(name)) {\n throw new Error(`Invalid cookie name: ${JSON.stringify(name)}`);\n }\n}\n\n/**\n * Validate cookie attribute values (path, domain) to prevent injection\n * via semicolons, newlines, or other control characters.\n */\nexport function validateCookieAttributeValue(value: string, attributeName: string): void {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code <= 0x1f || code === 0x7f || value[i] === \";\") {\n throw new Error(`Invalid cookie ${attributeName} value: ${JSON.stringify(value)}`);\n }\n }\n}\n\n/**\n * Build a Set-Cookie header string from a cookie name, value, and attributes.\n *\n * - Encodes the value with `encodeURIComponent`.\n * - Defaults `Path` to `/` (matching @edge-runtime/cookies and Next.js).\n * - Validates path/domain to reject control characters and semicolons.\n * - Emits attributes in the order: Path, Domain, Max-Age, Expires, HttpOnly,\n * Secure, SameSite.\n *\n * The caller is responsible for validating the cookie name (typically before\n * mutating any internal state) via `validateCookieName`.\n */\nexport function serializeSetCookie(\n name: string,\n value: string,\n options?: SerializeSetCookieOptions,\n): string {\n const parts = [`${name}=${encodeURIComponent(value)}`];\n const path = options?.path ?? \"/\";\n validateCookieAttributeValue(path, \"Path\");\n parts.push(`Path=${path}`);\n if (options?.domain) {\n validateCookieAttributeValue(options.domain, \"Domain\");\n parts.push(`Domain=${options.domain}`);\n }\n if (options?.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n if (options?.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n if (options?.httpOnly) parts.push(\"HttpOnly\");\n if (options?.secure) parts.push(\"Secure\");\n if (options?.sameSite) parts.push(`SameSite=${options.sameSite}`);\n return parts.join(\"; \");\n}\n"],"mappings":";;;;;AA6BA,MAAM,uBACJ;AAEF,SAAgB,mBAAmB,MAAoB;
|
|
1
|
+
{"version":3,"file":"cookie-serialize.js","names":[],"sources":["../../../src/shims/internal/cookie-serialize.ts"],"sourcesContent":["/**\n * Shared Set-Cookie serialization for the next/headers and next/server shims.\n *\n * Two call sites — `cookies().set()` in headers.ts and `ResponseCookies.set()`\n * in server.ts — produce identical Set-Cookie header strings. Keep the\n * encoding, attribute order, and validation in one place so subtle RFC 6265\n * details (escaping, attribute ordering, etc.) cannot drift between them.\n *\n * Note: this is a value-encoding helper for response cookies only. The\n * request `Cookie:` header serialization in `RequestCookies._serialize`\n * (server.ts) intentionally lives separately — it builds a different format\n * (no attributes, just `name=value; name=value`) and shouldn't share this\n * code.\n */\n\ntype SerializeSetCookieOptions = {\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n};\n\n/**\n * RFC 6265 §4.1.1: cookie-name is a token (RFC 2616 §2.2).\n * Allowed: any visible ASCII (0x21-0x7E) except separators: ()<>@,;:\\\"/[]?={}\n */\nconst VALID_COOKIE_NAME_RE =\n /^[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2E\\x30-\\x39\\x41-\\x5A\\x5E-\\x7A\\x7C\\x7E]+$/;\n\nexport function validateCookieName(name: string): void {\n if (!name || !VALID_COOKIE_NAME_RE.test(name)) {\n throw new Error(`Invalid cookie name: ${JSON.stringify(name)}`);\n }\n}\n\n/**\n * Validate cookie attribute values (path, domain) to prevent injection\n * via semicolons, newlines, or other control characters.\n */\nexport function validateCookieAttributeValue(value: string, attributeName: string): void {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (code <= 0x1f || code === 0x7f || value[i] === \";\") {\n throw new Error(`Invalid cookie ${attributeName} value: ${JSON.stringify(value)}`);\n }\n }\n}\n\n/**\n * Build a Set-Cookie header string from a cookie name, value, and attributes.\n *\n * - Encodes the value with `encodeURIComponent`.\n * - Defaults `Path` to `/` (matching @edge-runtime/cookies and Next.js).\n * - Validates path/domain to reject control characters and semicolons.\n * - Emits attributes in the order: Path, Domain, Max-Age, Expires, HttpOnly,\n * Secure, SameSite.\n *\n * The caller is responsible for validating the cookie name (typically before\n * mutating any internal state) via `validateCookieName`.\n */\nexport function serializeSetCookie(\n name: string,\n value: string,\n options?: SerializeSetCookieOptions,\n): string {\n const parts = [`${name}=${encodeURIComponent(value)}`];\n const path = options?.path ?? \"/\";\n validateCookieAttributeValue(path, \"Path\");\n parts.push(`Path=${path}`);\n if (options?.domain) {\n validateCookieAttributeValue(options.domain, \"Domain\");\n parts.push(`Domain=${options.domain}`);\n }\n if (options?.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);\n if (options?.expires) parts.push(`Expires=${options.expires.toUTCString()}`);\n if (options?.httpOnly) parts.push(\"HttpOnly\");\n if (options?.secure) parts.push(\"Secure\");\n if (options?.sameSite) parts.push(`SameSite=${options.sameSite}`);\n return parts.join(\"; \");\n}\n"],"mappings":";;;;;AA6BA,MAAM,uBACJ;AAEF,SAAgB,mBAAmB,MAAoB;CACrD,IAAI,CAAC,QAAQ,CAAC,qBAAqB,KAAK,KAAK,EAC3C,MAAM,IAAI,MAAM,wBAAwB,KAAK,UAAU,KAAK,GAAG;;;;;;AAQnE,SAAgB,6BAA6B,OAAe,eAA6B;CACvF,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,MAAM,OAAO,MAAM,WAAW,EAAE;EAChC,IAAI,QAAQ,MAAQ,SAAS,OAAQ,MAAM,OAAO,KAChD,MAAM,IAAI,MAAM,kBAAkB,cAAc,UAAU,KAAK,UAAU,MAAM,GAAG;;;;;;;;;;;;;;;AAiBxF,SAAgB,mBACd,MACA,OACA,SACQ;CACR,MAAM,QAAQ,CAAC,GAAG,KAAK,GAAG,mBAAmB,MAAM,GAAG;CACtD,MAAM,OAAO,SAAS,QAAQ;CAC9B,6BAA6B,MAAM,OAAO;CAC1C,MAAM,KAAK,QAAQ,OAAO;CAC1B,IAAI,SAAS,QAAQ;EACnB,6BAA6B,QAAQ,QAAQ,SAAS;EACtD,MAAM,KAAK,UAAU,QAAQ,SAAS;;CAExC,IAAI,SAAS,WAAW,KAAA,GAAW,MAAM,KAAK,WAAW,QAAQ,SAAS;CAC1E,IAAI,SAAS,SAAS,MAAM,KAAK,WAAW,QAAQ,QAAQ,aAAa,GAAG;CAC5E,IAAI,SAAS,UAAU,MAAM,KAAK,WAAW;CAC7C,IAAI,SAAS,QAAQ,MAAM,KAAK,SAAS;CACzC,IAAI,SAAS,UAAU,MAAM,KAAK,YAAY,QAAQ,WAAW;CACjE,OAAO,MAAM,KAAK,KAAK"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* makeHangingPromise — returns a promise that never resolves during prerendering.
|
|
4
4
|
*
|
|
5
|
-
* When prerendering, `
|
|
5
|
+
* When prerendering, `io()` must return a hanging promise to prevent
|
|
6
6
|
* React from executing past the IO boundary. The promise never resolves—it only
|
|
7
7
|
* rejects if the render signal is aborted (e.g., due to a dynamic error or
|
|
8
8
|
* cache-fill completion).
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* makeHangingPromise — returns a promise that never resolves during prerendering.
|
|
4
4
|
*
|
|
5
|
-
* When prerendering, `
|
|
5
|
+
* When prerendering, `io()` must return a hanging promise to prevent
|
|
6
6
|
* React from executing past the IO boundary. The promise never resolves—it only
|
|
7
7
|
* rejects if the render signal is aborted (e.g., due to a dynamic error or
|
|
8
8
|
* cache-fill completion).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-hanging-promise.js","names":[],"sources":["../../../src/shims/internal/make-hanging-promise.ts"],"sourcesContent":["/**\n * makeHangingPromise — returns a promise that never resolves during prerendering.\n *\n * When prerendering, `
|
|
1
|
+
{"version":3,"file":"make-hanging-promise.js","names":[],"sources":["../../../src/shims/internal/make-hanging-promise.ts"],"sourcesContent":["/**\n * makeHangingPromise — returns a promise that never resolves during prerendering.\n *\n * When prerendering, `io()` must return a hanging promise to prevent\n * React from executing past the IO boundary. The promise never resolves—it only\n * rejects if the render signal is aborted (e.g., due to a dynamic error or\n * cache-fill completion).\n *\n * Ported from Next.js: packages/next/src/server/dynamic-rendering-utils.ts\n * https://github.com/vercel/next.js/blob/canary/packages/next/src/server/dynamic-rendering-utils.ts\n */\n\nclass HangingPromiseRejectionError extends Error {\n constructor(route: string, expression: string) {\n super(\n `Route ${route} used ${expression} during prerendering but the render was aborted. ` +\n `This is expected when prerendering is cut short (e.g. due to a dynamic access).`,\n );\n this.name = \"HangingPromiseRejectionError\";\n }\n}\n\nconst abortListenersBySignal = new WeakMap<AbortSignal, (() => void)[]>();\n\nfunction suppressUnhandledRejection(): void {\n // intentionally empty — suppresses \"unhandled rejection\" warnings\n}\n\nexport function makeHangingPromise<T>(\n signal: AbortSignal,\n route: string,\n expression: string,\n): Promise<T> {\n if (signal.aborted) {\n const rejected = Promise.reject(new HangingPromiseRejectionError(route, expression));\n rejected.catch(suppressUnhandledRejection);\n return rejected;\n }\n const hangingPromise = new Promise<T>((_, reject) => {\n const boundRejection = reject.bind(null, new HangingPromiseRejectionError(route, expression));\n const currentListeners = abortListenersBySignal.get(signal);\n if (currentListeners) {\n currentListeners.push(boundRejection);\n } else {\n const listeners = [boundRejection];\n abortListenersBySignal.set(signal, listeners);\n signal.addEventListener(\n \"abort\",\n () => {\n for (let i = 0; i < listeners.length; i++) {\n listeners[i]();\n }\n listeners.length = 0;\n },\n { once: true },\n );\n }\n });\n // Suppress unhandled rejection — the promise is expected to be used with\n // React's use() which handles rejections. If never awaited, the abort\n // rejection is a no-op cleanup.\n hangingPromise.catch(suppressUnhandledRejection);\n return hangingPromise;\n}\n"],"mappings":";;;;;;;;;;;;AAYA,IAAM,+BAAN,cAA2C,MAAM;CAC/C,YAAY,OAAe,YAAoB;EAC7C,MACE,SAAS,MAAM,QAAQ,WAAW,kIAEnC;EACD,KAAK,OAAO;;;AAIhB,MAAM,yCAAyB,IAAI,SAAsC;AAEzE,SAAS,6BAAmC;AAI5C,SAAgB,mBACd,QACA,OACA,YACY;CACZ,IAAI,OAAO,SAAS;EAClB,MAAM,WAAW,QAAQ,OAAO,IAAI,6BAA6B,OAAO,WAAW,CAAC;EACpF,SAAS,MAAM,2BAA2B;EAC1C,OAAO;;CAET,MAAM,iBAAiB,IAAI,SAAY,GAAG,WAAW;EACnD,MAAM,iBAAiB,OAAO,KAAK,MAAM,IAAI,6BAA6B,OAAO,WAAW,CAAC;EAC7F,MAAM,mBAAmB,uBAAuB,IAAI,OAAO;EAC3D,IAAI,kBACF,iBAAiB,KAAK,eAAe;OAChC;GACL,MAAM,YAAY,CAAC,eAAe;GAClC,uBAAuB,IAAI,QAAQ,UAAU;GAC7C,OAAO,iBACL,eACM;IACJ,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KACpC,UAAU,IAAI;IAEhB,UAAU,SAAS;MAErB,EAAE,MAAM,MAAM,CACf;;GAEH;CAIF,eAAe,MAAM,2BAA2B;CAChD,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-cookie-header.js","names":[],"sources":["../../../src/shims/internal/parse-cookie-header.ts"],"sourcesContent":["/**\n * Port of the current Next.js/@edge-runtime request cookie parser semantics.\n *\n * Important details:\n * - split on a semicolon-plus-optional-spaces pattern\n * - preserve whitespace around names/values otherwise\n * - bare tokens become \"true\"\n * - malformed percent-encoded values are skipped\n * - duplicate names collapse to the last value via Map.set()\n */\nexport function parseCookieHeader(cookieHeader: string): Map<string, string> {\n const cookies = new Map<string, string>();\n for (const pair of cookieHeader.split(/; */)) {\n if (!pair) continue;\n\n const splitAt = pair.indexOf(\"=\");\n if (splitAt === -1) {\n cookies.set(pair, \"true\");\n continue;\n }\n\n const key = pair.slice(0, splitAt);\n const value = pair.slice(splitAt + 1);\n\n try {\n cookies.set(key, decodeURIComponent(value));\n } catch {\n // Match Next.js/@edge-runtime behavior: ignore malformed cookie values.\n }\n }\n return cookies;\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,kBAAkB,cAA2C;CAC3E,MAAM,0BAAU,IAAI,KAAqB;
|
|
1
|
+
{"version":3,"file":"parse-cookie-header.js","names":[],"sources":["../../../src/shims/internal/parse-cookie-header.ts"],"sourcesContent":["/**\n * Port of the current Next.js/@edge-runtime request cookie parser semantics.\n *\n * Important details:\n * - split on a semicolon-plus-optional-spaces pattern\n * - preserve whitespace around names/values otherwise\n * - bare tokens become \"true\"\n * - malformed percent-encoded values are skipped\n * - duplicate names collapse to the last value via Map.set()\n */\nexport function parseCookieHeader(cookieHeader: string): Map<string, string> {\n const cookies = new Map<string, string>();\n for (const pair of cookieHeader.split(/; */)) {\n if (!pair) continue;\n\n const splitAt = pair.indexOf(\"=\");\n if (splitAt === -1) {\n cookies.set(pair, \"true\");\n continue;\n }\n\n const key = pair.slice(0, splitAt);\n const value = pair.slice(splitAt + 1);\n\n try {\n cookies.set(key, decodeURIComponent(value));\n } catch {\n // Match Next.js/@edge-runtime behavior: ignore malformed cookie values.\n }\n }\n return cookies;\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,kBAAkB,cAA2C;CAC3E,MAAM,0BAAU,IAAI,KAAqB;CACzC,KAAK,MAAM,QAAQ,aAAa,MAAM,MAAM,EAAE;EAC5C,IAAI,CAAC,MAAM;EAEX,MAAM,UAAU,KAAK,QAAQ,IAAI;EACjC,IAAI,YAAY,IAAI;GAClB,QAAQ,IAAI,MAAM,OAAO;GACzB;;EAGF,MAAM,MAAM,KAAK,MAAM,GAAG,QAAQ;EAClC,MAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;EAErC,IAAI;GACF,QAAQ,IAAI,KAAK,mBAAmB,MAAM,CAAC;UACrC;;CAIV,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/shims/internal/utils.ts"],"sourcesContent":["/**\n * Shim for next/dist/shared/lib/utils\n *\n * Used by: @sentry/nextjs (type-only import of NEXT_DATA).\n * Provides the NEXT_DATA type that matches window.__NEXT_DATA__.\n */\n\nexport type NEXT_DATA = {\n props: Record<string, unknown>;\n page: string;\n query: Record<string, string | string[]>;\n buildId?: string;\n assetPrefix?: string;\n runtimeConfig?: Record<string, unknown>;\n nextExport?: boolean;\n autoExport?: boolean;\n isFallback?: boolean;\n dynamicIds?: (string | number)[];\n err?: { message: string; statusCode: number; name?: string };\n gsp?: boolean;\n gssp?: boolean;\n customServer?: boolean;\n gip?: boolean;\n appGip?: boolean;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n domainLocales?: Array<{\n domain: string;\n defaultLocale: string;\n locales?: string[];\n http?: boolean;\n }>;\n scriptLoader?: unknown[];\n isPreview?: boolean;\n notFoundSrcPage?: string;\n};\n\n/**\n * Standard Next.js error shape.\n */\nexport function execOnce<T extends (...args: unknown[]) => unknown>(fn: T): T {\n let used = false;\n let result: unknown;\n return ((...args: unknown[]) => {\n if (!used) {\n used = true;\n result = fn(...args);\n }\n return result;\n }) as T;\n}\n\nexport function getLocationOrigin(): string {\n if (typeof window !== \"undefined\") {\n return window.location.origin;\n }\n return \"http://localhost\";\n}\n\nexport function getURL(): string {\n if (typeof window !== \"undefined\") {\n return window.location.href;\n }\n return \"http://localhost/\";\n}\n\nexport const SP = typeof performance !== \"undefined\";\nexport const ST = SP && typeof performance.mark === \"function\";\n"],"mappings":";;;;AAyCA,SAAgB,SAAoD,IAAU;CAC5E,IAAI,OAAO;CACX,IAAI;
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/shims/internal/utils.ts"],"sourcesContent":["/**\n * Shim for next/dist/shared/lib/utils\n *\n * Used by: @sentry/nextjs (type-only import of NEXT_DATA).\n * Provides the NEXT_DATA type that matches window.__NEXT_DATA__.\n */\n\nexport type NEXT_DATA = {\n props: Record<string, unknown>;\n page: string;\n query: Record<string, string | string[]>;\n buildId?: string;\n assetPrefix?: string;\n runtimeConfig?: Record<string, unknown>;\n nextExport?: boolean;\n autoExport?: boolean;\n isFallback?: boolean;\n dynamicIds?: (string | number)[];\n err?: { message: string; statusCode: number; name?: string };\n gsp?: boolean;\n gssp?: boolean;\n customServer?: boolean;\n gip?: boolean;\n appGip?: boolean;\n locale?: string;\n locales?: string[];\n defaultLocale?: string;\n domainLocales?: Array<{\n domain: string;\n defaultLocale: string;\n locales?: string[];\n http?: boolean;\n }>;\n scriptLoader?: unknown[];\n isPreview?: boolean;\n notFoundSrcPage?: string;\n};\n\n/**\n * Standard Next.js error shape.\n */\nexport function execOnce<T extends (...args: unknown[]) => unknown>(fn: T): T {\n let used = false;\n let result: unknown;\n return ((...args: unknown[]) => {\n if (!used) {\n used = true;\n result = fn(...args);\n }\n return result;\n }) as T;\n}\n\nexport function getLocationOrigin(): string {\n if (typeof window !== \"undefined\") {\n return window.location.origin;\n }\n return \"http://localhost\";\n}\n\nexport function getURL(): string {\n if (typeof window !== \"undefined\") {\n return window.location.href;\n }\n return \"http://localhost/\";\n}\n\nexport const SP = typeof performance !== \"undefined\";\nexport const ST = SP && typeof performance.mark === \"function\";\n"],"mappings":";;;;AAyCA,SAAgB,SAAoD,IAAU;CAC5E,IAAI,OAAO;CACX,IAAI;CACJ,SAAS,GAAG,SAAoB;EAC9B,IAAI,CAAC,MAAM;GACT,OAAO;GACP,SAAS,GAAG,GAAG,KAAK;;EAEtB,OAAO;;;AAIX,SAAgB,oBAA4B;CAC1C,IAAI,OAAO,WAAW,aACpB,OAAO,OAAO,SAAS;CAEzB,OAAO;;AAGT,SAAgB,SAAiB;CAC/B,IAAI,OAAO,WAAW,aACpB,OAAO,OAAO,SAAS;CAEzB,OAAO;;AAGT,MAAa,KAAK,OAAO,gBAAgB;AACzC,MAAa,KAAK,MAAM,OAAO,YAAY,SAAS"}
|
|
@@ -5,11 +5,11 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
5
5
|
* and next/dist/client/components/request-async-storage.external
|
|
6
6
|
*
|
|
7
7
|
* Tracks the current rendering context type so that dynamic APIs
|
|
8
|
-
* (
|
|
8
|
+
* (io, headers, cookies, etc.) can branch on whether they're
|
|
9
9
|
* inside a request, prerender, cache scope, or other context.
|
|
10
10
|
*
|
|
11
11
|
* Used by: @sentry/nextjs (runtime resolve for request context injection),
|
|
12
|
-
*
|
|
12
|
+
* io() for hanging-promise behavior during prerendering.
|
|
13
13
|
*/
|
|
14
14
|
const workUnitAsyncStorage = new AsyncLocalStorage();
|
|
15
15
|
const requestAsyncStorage = workUnitAsyncStorage;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-unit-async-storage.js","names":[],"sources":["../../../src/shims/internal/work-unit-async-storage.ts"],"sourcesContent":["/**\n * Shim for next/dist/server/app-render/work-unit-async-storage.external\n * and next/dist/client/components/request-async-storage.external\n *\n * Tracks the current rendering context type so that dynamic APIs\n * (
|
|
1
|
+
{"version":3,"file":"work-unit-async-storage.js","names":[],"sources":["../../../src/shims/internal/work-unit-async-storage.ts"],"sourcesContent":["/**\n * Shim for next/dist/server/app-render/work-unit-async-storage.external\n * and next/dist/client/components/request-async-storage.external\n *\n * Tracks the current rendering context type so that dynamic APIs\n * (io, headers, cookies, etc.) can branch on whether they're\n * inside a request, prerender, cache scope, or other context.\n *\n * Used by: @sentry/nextjs (runtime resolve for request context injection),\n * io() for hanging-promise behavior during prerendering.\n */\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n// ── WorkUnitStore discriminated union ───────────────────────────────────\n\nexport type RequestStore = {\n readonly type: \"request\";\n};\n\nexport type PrerenderStore = {\n readonly type: \"prerender\" | \"prerender-client\" | \"prerender-runtime\";\n /** AbortSignal that fires when the prerender is cancelled or completed. */\n readonly renderSignal: AbortSignal;\n /** Optional route identifier for debugging and error messages. */\n readonly route?: string;\n};\n\nexport type CacheStore = {\n readonly type: \"cache\" | \"private-cache\" | \"unstable-cache\";\n};\n\nexport type GenerateStaticParamsStore = {\n readonly type: \"generate-static-params\";\n};\n\nexport type PrerenderLegacyStore = {\n readonly type: \"prerender-legacy\";\n};\n\n/**\n * Discriminated union of all known work unit types.\n * Matches Next.js's WorkUnitStore: packages/next/src/server/app-render/work-unit-async-storage.external.ts\n */\nexport type WorkUnitStore =\n | RequestStore\n | PrerenderStore\n | CacheStore\n | GenerateStaticParamsStore\n | PrerenderLegacyStore;\n\nexport type WorkUnitAsyncStorage = AsyncLocalStorage<WorkUnitStore>;\n\nexport const workUnitAsyncStorage: WorkUnitAsyncStorage = new AsyncLocalStorage();\n\n// Legacy name (Next 13.x–14.x)\nexport const requestAsyncStorage = workUnitAsyncStorage;\n"],"mappings":";;;;;;;;;;;;;AAoDA,MAAa,uBAA6C,IAAI,mBAAmB;AAGjF,MAAa,sBAAsB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-segment-context.js","names":[],"sources":["../../src/shims/layout-segment-context.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Layout segment context provider.\n *\n * Must be \"use client\" so that Vite's RSC bundler renders this component in\n * the SSR/browser environment where React.createContext is available. The RSC\n * entry imports and renders LayoutSegmentProvider directly, but because of the\n * \"use client\" boundary the actual execution happens on the SSR/client side\n * where the context can be created and consumed by useSelectedLayoutSegment(s).\n *\n * Without \"use client\", this runs in the RSC environment where\n * React.createContext is undefined, getLayoutSegmentContext() returns null,\n * the provider becomes a no-op, and useSelectedLayoutSegments always returns [].\n *\n * The context is shared with navigation.ts via getLayoutSegmentContext()\n * to avoid creating separate contexts in different modules.\n */\nimport { createElement, type ReactNode } from \"react\";\nimport { getLayoutSegmentContext, type SegmentMap } from \"./navigation.js\";\n\n/**\n * Wraps children with the layout segment context.\n *\n * Each layout in the App Router tree wraps its children with this provider,\n * passing a map of parallel route key to segment path. The \"children\" key is\n * always present (the default parallel route). Named parallel slots at this\n * layout level add their own keys.\n *\n * Components inside the provider call useSelectedLayoutSegments(parallelRoutesKey)\n * to read the segments for a specific parallel route.\n */\nexport function LayoutSegmentProvider({\n segmentMap,\n children,\n}: {\n segmentMap: SegmentMap;\n children: ReactNode;\n}) {\n const ctx = getLayoutSegmentContext();\n if (!ctx) {\n // No context available — expected only in RSC environment, not SSR/browser.\n return children;\n }\n return createElement(ctx.Provider, { value: segmentMap }, children);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,sBAAsB,EACpC,YACA,YAIC;CACD,MAAM,MAAM,yBAAyB;
|
|
1
|
+
{"version":3,"file":"layout-segment-context.js","names":[],"sources":["../../src/shims/layout-segment-context.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Layout segment context provider.\n *\n * Must be \"use client\" so that Vite's RSC bundler renders this component in\n * the SSR/browser environment where React.createContext is available. The RSC\n * entry imports and renders LayoutSegmentProvider directly, but because of the\n * \"use client\" boundary the actual execution happens on the SSR/client side\n * where the context can be created and consumed by useSelectedLayoutSegment(s).\n *\n * Without \"use client\", this runs in the RSC environment where\n * React.createContext is undefined, getLayoutSegmentContext() returns null,\n * the provider becomes a no-op, and useSelectedLayoutSegments always returns [].\n *\n * The context is shared with navigation.ts via getLayoutSegmentContext()\n * to avoid creating separate contexts in different modules.\n */\nimport { createElement, type ReactNode } from \"react\";\nimport { getLayoutSegmentContext, type SegmentMap } from \"./navigation.js\";\n\n/**\n * Wraps children with the layout segment context.\n *\n * Each layout in the App Router tree wraps its children with this provider,\n * passing a map of parallel route key to segment path. The \"children\" key is\n * always present (the default parallel route). Named parallel slots at this\n * layout level add their own keys.\n *\n * Components inside the provider call useSelectedLayoutSegments(parallelRoutesKey)\n * to read the segments for a specific parallel route.\n */\nexport function LayoutSegmentProvider({\n segmentMap,\n children,\n}: {\n segmentMap: SegmentMap;\n children: ReactNode;\n}) {\n const ctx = getLayoutSegmentContext();\n if (!ctx) {\n // No context available — expected only in RSC environment, not SSR/browser.\n return children;\n }\n return createElement(ctx.Provider, { value: segmentMap }, children);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,sBAAsB,EACpC,YACA,YAIC;CACD,MAAM,MAAM,yBAAyB;CACrC,IAAI,CAAC,KAEH,OAAO;CAET,OAAO,cAAc,IAAI,UAAU,EAAE,OAAO,YAAY,EAAE,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legacy-image.js","names":[],"sources":["../../src/shims/legacy-image.tsx"],"sourcesContent":["/**\n * next/legacy/image shim\n *\n * Provides the pre-Next.js 13 Image component API with layout prop.\n * Translates legacy props (layout, objectFit, objectPosition) to the\n * modern Image component's fill/style props.\n *\n * This module is used by apps that ran the `next-image-to-legacy-image`\n * codemod when upgrading from Next.js 12.\n */\nimport React, { forwardRef } from \"react\";\nimport Image from \"./image.js\";\n\ntype LegacyImageProps = {\n src: string | { src: string; width: number; height: number; blurDataURL?: string };\n alt: string;\n width?: number | string;\n height?: number | string;\n /** Legacy layout mode */\n layout?: \"fixed\" | \"intrinsic\" | \"responsive\" | \"fill\";\n /** CSS object-fit (used with layout=\"fill\") */\n objectFit?: React.CSSProperties[\"objectFit\"];\n /** CSS object-position (used with layout=\"fill\") */\n objectPosition?: string;\n priority?: boolean;\n quality?: number;\n placeholder?: \"blur\" | \"empty\";\n blurDataURL?: string;\n loader?: (params: { src: string; width: number; quality?: number }) => string;\n sizes?: string;\n className?: string;\n style?: React.CSSProperties;\n onLoad?: React.ReactEventHandler<HTMLImageElement>;\n onLoadingComplete?: (result: { naturalWidth: number; naturalHeight: number }) => void;\n onError?: React.ReactEventHandler<HTMLImageElement>;\n loading?: \"lazy\" | \"eager\";\n unoptimized?: boolean;\n id?: string;\n};\n\nconst LegacyImage = forwardRef<HTMLImageElement, LegacyImageProps>(\n function LegacyImage(props, ref) {\n const {\n layout = \"intrinsic\",\n objectFit,\n objectPosition,\n onLoadingComplete,\n onLoad,\n width,\n height,\n style,\n ...rest\n } = props;\n\n // Translate legacy props to modern Image props\n const modernStyle: React.CSSProperties = { ...style };\n\n if (objectFit) modernStyle.objectFit = objectFit;\n if (objectPosition) modernStyle.objectPosition = objectPosition;\n\n const handleLoad = onLoadingComplete\n ? (e: React.SyntheticEvent<HTMLImageElement>) => {\n const img = e.currentTarget;\n onLoadingComplete({\n naturalWidth: img.naturalWidth,\n naturalHeight: img.naturalHeight,\n });\n onLoad?.(e);\n }\n : onLoad;\n\n if (layout === \"fill\") {\n return <Image ref={ref} fill style={modernStyle} onLoad={handleLoad} {...rest} />;\n }\n\n if (layout === \"responsive\") {\n // Responsive: takes full width, maintains aspect ratio\n modernStyle.width = \"100%\";\n modernStyle.height = \"auto\";\n }\n\n // For \"fixed\" and \"intrinsic\", pass width/height directly\n const w = typeof width === \"string\" ? parseInt(width, 10) : width;\n const h = typeof height === \"string\" ? parseInt(height, 10) : height;\n\n return (\n <Image ref={ref} width={w} height={h} style={modernStyle} onLoad={handleLoad} {...rest} />\n );\n },\n);\n\nexport default LegacyImage;\n"],"mappings":";;;;;;;;;;;;;;AAwCA,MAAM,cAAc,WAClB,SAAS,YAAY,OAAO,KAAK;CAC/B,MAAM,EACJ,SAAS,aACT,WACA,gBACA,mBACA,QACA,OACA,QACA,OACA,GAAG,SACD;CAGJ,MAAM,cAAmC,EAAE,GAAG,OAAO;
|
|
1
|
+
{"version":3,"file":"legacy-image.js","names":[],"sources":["../../src/shims/legacy-image.tsx"],"sourcesContent":["/**\n * next/legacy/image shim\n *\n * Provides the pre-Next.js 13 Image component API with layout prop.\n * Translates legacy props (layout, objectFit, objectPosition) to the\n * modern Image component's fill/style props.\n *\n * This module is used by apps that ran the `next-image-to-legacy-image`\n * codemod when upgrading from Next.js 12.\n */\nimport React, { forwardRef } from \"react\";\nimport Image from \"./image.js\";\n\ntype LegacyImageProps = {\n src: string | { src: string; width: number; height: number; blurDataURL?: string };\n alt: string;\n width?: number | string;\n height?: number | string;\n /** Legacy layout mode */\n layout?: \"fixed\" | \"intrinsic\" | \"responsive\" | \"fill\";\n /** CSS object-fit (used with layout=\"fill\") */\n objectFit?: React.CSSProperties[\"objectFit\"];\n /** CSS object-position (used with layout=\"fill\") */\n objectPosition?: string;\n priority?: boolean;\n quality?: number;\n placeholder?: \"blur\" | \"empty\";\n blurDataURL?: string;\n loader?: (params: { src: string; width: number; quality?: number }) => string;\n sizes?: string;\n className?: string;\n style?: React.CSSProperties;\n onLoad?: React.ReactEventHandler<HTMLImageElement>;\n onLoadingComplete?: (result: { naturalWidth: number; naturalHeight: number }) => void;\n onError?: React.ReactEventHandler<HTMLImageElement>;\n loading?: \"lazy\" | \"eager\";\n unoptimized?: boolean;\n id?: string;\n};\n\nconst LegacyImage = forwardRef<HTMLImageElement, LegacyImageProps>(\n function LegacyImage(props, ref) {\n const {\n layout = \"intrinsic\",\n objectFit,\n objectPosition,\n onLoadingComplete,\n onLoad,\n width,\n height,\n style,\n ...rest\n } = props;\n\n // Translate legacy props to modern Image props\n const modernStyle: React.CSSProperties = { ...style };\n\n if (objectFit) modernStyle.objectFit = objectFit;\n if (objectPosition) modernStyle.objectPosition = objectPosition;\n\n const handleLoad = onLoadingComplete\n ? (e: React.SyntheticEvent<HTMLImageElement>) => {\n const img = e.currentTarget;\n onLoadingComplete({\n naturalWidth: img.naturalWidth,\n naturalHeight: img.naturalHeight,\n });\n onLoad?.(e);\n }\n : onLoad;\n\n if (layout === \"fill\") {\n return <Image ref={ref} fill style={modernStyle} onLoad={handleLoad} {...rest} />;\n }\n\n if (layout === \"responsive\") {\n // Responsive: takes full width, maintains aspect ratio\n modernStyle.width = \"100%\";\n modernStyle.height = \"auto\";\n }\n\n // For \"fixed\" and \"intrinsic\", pass width/height directly\n const w = typeof width === \"string\" ? parseInt(width, 10) : width;\n const h = typeof height === \"string\" ? parseInt(height, 10) : height;\n\n return (\n <Image ref={ref} width={w} height={h} style={modernStyle} onLoad={handleLoad} {...rest} />\n );\n },\n);\n\nexport default LegacyImage;\n"],"mappings":";;;;;;;;;;;;;;AAwCA,MAAM,cAAc,WAClB,SAAS,YAAY,OAAO,KAAK;CAC/B,MAAM,EACJ,SAAS,aACT,WACA,gBACA,mBACA,QACA,OACA,QACA,OACA,GAAG,SACD;CAGJ,MAAM,cAAmC,EAAE,GAAG,OAAO;CAErD,IAAI,WAAW,YAAY,YAAY;CACvC,IAAI,gBAAgB,YAAY,iBAAiB;CAEjD,MAAM,aAAa,qBACd,MAA8C;EAC7C,MAAM,MAAM,EAAE;EACd,kBAAkB;GAChB,cAAc,IAAI;GAClB,eAAe,IAAI;GACpB,CAAC;EACF,SAAS,EAAE;KAEb;CAEJ,IAAI,WAAW,QACb,OAAO,oBAAC,OAAD;EAAY;EAAK,MAAA;EAAK,OAAO;EAAa,QAAQ;EAAY,GAAI;EAAQ,CAAA;CAGnF,IAAI,WAAW,cAAc;EAE3B,YAAY,QAAQ;EACpB,YAAY,SAAS;;CAOvB,OACE,oBAAC,OAAD;EAAY;EAAK,OAJT,OAAO,UAAU,WAAW,SAAS,OAAO,GAAG,GAAG;EAI/B,QAHnB,OAAO,WAAW,WAAW,SAAS,QAAQ,GAAG,GAAG;EAGtB,OAAO;EAAa,QAAQ;EAAY,GAAI;EAAQ,CAAA;EAG/F"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/shims/link-prefetch.d.ts
|
|
2
|
+
type LinkPrefetchIntent = "viewport" | "intent";
|
|
3
|
+
type LinkPrefetchPriority = "low" | "high";
|
|
4
|
+
type LinkPrefetchDecision = {
|
|
5
|
+
shouldPrefetch: false;
|
|
6
|
+
} | {
|
|
7
|
+
shouldPrefetch: true;
|
|
8
|
+
priority: LinkPrefetchPriority;
|
|
9
|
+
};
|
|
10
|
+
declare function canLinkPrefetch(input: {
|
|
11
|
+
nodeEnv: string | undefined;
|
|
12
|
+
prefetch: boolean | "auto" | null | undefined;
|
|
13
|
+
isDangerous: boolean;
|
|
14
|
+
}): boolean;
|
|
15
|
+
declare function getLinkPrefetchDecision(input: {
|
|
16
|
+
nodeEnv: string | undefined;
|
|
17
|
+
prefetch: boolean | "auto" | null | undefined;
|
|
18
|
+
isDangerous: boolean;
|
|
19
|
+
intent: LinkPrefetchIntent;
|
|
20
|
+
}): LinkPrefetchDecision;
|
|
21
|
+
/**
|
|
22
|
+
* Normalize absolute and protocol-relative Link hrefs to app-relative paths
|
|
23
|
+
* that are eligible for prefetching. Non-absolute relative hrefs are returned
|
|
24
|
+
* unchanged; callers must resolve them against the current browser URL before
|
|
25
|
+
* constructing a concrete fetch target.
|
|
26
|
+
*/
|
|
27
|
+
declare function getLinkPrefetchHref(input: {
|
|
28
|
+
href: string;
|
|
29
|
+
basePath: string;
|
|
30
|
+
currentOrigin: string | undefined;
|
|
31
|
+
}): string | null;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { LinkPrefetchDecision, LinkPrefetchIntent, LinkPrefetchPriority, canLinkPrefetch, getLinkPrefetchDecision, getLinkPrefetchHref };
|
|
34
|
+
//# sourceMappingURL=link-prefetch.d.ts.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
//#region src/shims/link-prefetch.ts
|
|
3
|
+
function canLinkPrefetch(input) {
|
|
4
|
+
return input.nodeEnv === "production" && input.prefetch !== false && !input.isDangerous;
|
|
5
|
+
}
|
|
6
|
+
function getLinkPrefetchDecision(input) {
|
|
7
|
+
if (!canLinkPrefetch(input)) return { shouldPrefetch: false };
|
|
8
|
+
return {
|
|
9
|
+
shouldPrefetch: true,
|
|
10
|
+
priority: input.intent === "intent" ? "high" : "low"
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Normalize absolute and protocol-relative Link hrefs to app-relative paths
|
|
15
|
+
* that are eligible for prefetching. Non-absolute relative hrefs are returned
|
|
16
|
+
* unchanged; callers must resolve them against the current browser URL before
|
|
17
|
+
* constructing a concrete fetch target.
|
|
18
|
+
*/
|
|
19
|
+
function getLinkPrefetchHref(input) {
|
|
20
|
+
const { href, basePath, currentOrigin } = input;
|
|
21
|
+
if (!isAbsoluteOrProtocolRelative(href)) return href;
|
|
22
|
+
if (currentOrigin === void 0) return null;
|
|
23
|
+
try {
|
|
24
|
+
const current = new URL(currentOrigin);
|
|
25
|
+
const parsed = href.startsWith("//") ? new URL(href, current.origin) : new URL(href);
|
|
26
|
+
if (parsed.origin !== current.origin) return null;
|
|
27
|
+
if (!basePath) return parsed.pathname + parsed.search + parsed.hash;
|
|
28
|
+
if (!hasBasePath(parsed.pathname, basePath)) return null;
|
|
29
|
+
return stripBasePath(parsed.pathname, basePath) + parsed.search + parsed.hash;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function isAbsoluteOrProtocolRelative(href) {
|
|
35
|
+
return href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//");
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { canLinkPrefetch, getLinkPrefetchDecision, getLinkPrefetchHref };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=link-prefetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-prefetch.js","names":[],"sources":["../../src/shims/link-prefetch.ts"],"sourcesContent":["import { hasBasePath, stripBasePath } from \"../utils/base-path.js\";\n\nexport type LinkPrefetchIntent = \"viewport\" | \"intent\";\nexport type LinkPrefetchPriority = \"low\" | \"high\";\n\nexport type LinkPrefetchDecision =\n | {\n shouldPrefetch: false;\n }\n | {\n shouldPrefetch: true;\n priority: LinkPrefetchPriority;\n };\n\nexport function canLinkPrefetch(input: {\n nodeEnv: string | undefined;\n prefetch: boolean | \"auto\" | null | undefined;\n isDangerous: boolean;\n}): boolean {\n return input.nodeEnv === \"production\" && input.prefetch !== false && !input.isDangerous;\n}\n\nexport function getLinkPrefetchDecision(input: {\n nodeEnv: string | undefined;\n prefetch: boolean | \"auto\" | null | undefined;\n isDangerous: boolean;\n intent: LinkPrefetchIntent;\n}): LinkPrefetchDecision {\n if (!canLinkPrefetch(input)) return { shouldPrefetch: false };\n\n return {\n shouldPrefetch: true,\n priority: input.intent === \"intent\" ? \"high\" : \"low\",\n };\n}\n\n/**\n * Normalize absolute and protocol-relative Link hrefs to app-relative paths\n * that are eligible for prefetching. Non-absolute relative hrefs are returned\n * unchanged; callers must resolve them against the current browser URL before\n * constructing a concrete fetch target.\n */\nexport function getLinkPrefetchHref(input: {\n href: string;\n basePath: string;\n currentOrigin: string | undefined;\n}): string | null {\n const { href, basePath, currentOrigin } = input;\n if (!isAbsoluteOrProtocolRelative(href)) return href;\n if (currentOrigin === undefined) return null;\n\n try {\n const current = new URL(currentOrigin);\n const parsed = href.startsWith(\"//\") ? new URL(href, current.origin) : new URL(href);\n if (parsed.origin !== current.origin) return null;\n\n if (!basePath) {\n return parsed.pathname + parsed.search + parsed.hash;\n }\n\n if (!hasBasePath(parsed.pathname, basePath)) {\n return null;\n }\n\n return stripBasePath(parsed.pathname, basePath) + parsed.search + parsed.hash;\n } catch {\n return null;\n }\n}\n\nfunction isAbsoluteOrProtocolRelative(href: string): boolean {\n return href.startsWith(\"http://\") || href.startsWith(\"https://\") || href.startsWith(\"//\");\n}\n"],"mappings":";;AAcA,SAAgB,gBAAgB,OAIpB;CACV,OAAO,MAAM,YAAY,gBAAgB,MAAM,aAAa,SAAS,CAAC,MAAM;;AAG9E,SAAgB,wBAAwB,OAKf;CACvB,IAAI,CAAC,gBAAgB,MAAM,EAAE,OAAO,EAAE,gBAAgB,OAAO;CAE7D,OAAO;EACL,gBAAgB;EAChB,UAAU,MAAM,WAAW,WAAW,SAAS;EAChD;;;;;;;;AASH,SAAgB,oBAAoB,OAIlB;CAChB,MAAM,EAAE,MAAM,UAAU,kBAAkB;CAC1C,IAAI,CAAC,6BAA6B,KAAK,EAAE,OAAO;CAChD,IAAI,kBAAkB,KAAA,GAAW,OAAO;CAExC,IAAI;EACF,MAAM,UAAU,IAAI,IAAI,cAAc;EACtC,MAAM,SAAS,KAAK,WAAW,KAAK,GAAG,IAAI,IAAI,MAAM,QAAQ,OAAO,GAAG,IAAI,IAAI,KAAK;EACpF,IAAI,OAAO,WAAW,QAAQ,QAAQ,OAAO;EAE7C,IAAI,CAAC,UACH,OAAO,OAAO,WAAW,OAAO,SAAS,OAAO;EAGlD,IAAI,CAAC,YAAY,OAAO,UAAU,SAAS,EACzC,OAAO;EAGT,OAAO,cAAc,OAAO,UAAU,SAAS,GAAG,OAAO,SAAS,OAAO;SACnE;EACN,OAAO;;;AAIX,SAAS,6BAA6B,MAAuB;CAC3D,OAAO,KAAK,WAAW,UAAU,IAAI,KAAK,WAAW,WAAW,IAAI,KAAK,WAAW,KAAK"}
|
package/dist/shims/link.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { VinextLinkPrefetchRoute } from "../client/vinext-next-data.js";
|
|
1
2
|
import { UrlQuery } from "../utils/query.js";
|
|
2
|
-
import React from "react";
|
|
3
|
+
import React, { AnchorHTMLAttributes } from "react";
|
|
3
4
|
|
|
4
5
|
//#region src/shims/link.d.ts
|
|
5
6
|
type NavigateEvent = {
|
|
@@ -7,6 +8,26 @@ type NavigateEvent = {
|
|
|
7
8
|
preventDefault(): void; /** Whether preventDefault() has been called. */
|
|
8
9
|
defaultPrevented: boolean;
|
|
9
10
|
};
|
|
11
|
+
type LinkProps = {
|
|
12
|
+
href: string | {
|
|
13
|
+
pathname?: string;
|
|
14
|
+
query?: UrlQuery;
|
|
15
|
+
}; /** URL displayed in the browser (when href is a route pattern like /user/[id]) */
|
|
16
|
+
as?: string; /** Replace the current history entry instead of pushing */
|
|
17
|
+
replace?: boolean; /** Prefetch the page in the background (App Router default: auto, Pages Router default: true) */
|
|
18
|
+
prefetch?: boolean | "auto" | null; /** Whether to pass the href to the child element */
|
|
19
|
+
passHref?: boolean; /** Scroll to top on navigation (default: true) */
|
|
20
|
+
scroll?: boolean; /** Locale for i18n (used for locale-prefixed URLs) */
|
|
21
|
+
locale?: string | false; /** Called before navigation happens (Next.js 16). Return value is ignored. */
|
|
22
|
+
onNavigate?: (event: NavigateEvent) => void;
|
|
23
|
+
children?: React.ReactNode;
|
|
24
|
+
} & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href">;
|
|
25
|
+
type LinkPrefetchMode = "disabled" | "auto" | "full";
|
|
26
|
+
declare global {
|
|
27
|
+
interface Window {
|
|
28
|
+
__VINEXT_LINK_PREFETCH_ROUTES__?: VinextLinkPrefetchRoute[];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
10
31
|
type LinkStatusContextValue = {
|
|
11
32
|
pending: boolean;
|
|
12
33
|
};
|
|
@@ -16,14 +37,16 @@ type LinkStatusContextValue = {
|
|
|
16
37
|
* prefetch-triggered navigation is in progress.
|
|
17
38
|
*/
|
|
18
39
|
declare function useLinkStatus(): LinkStatusContextValue;
|
|
40
|
+
declare function resolveLinkPrefetchMode(prefetchProp: LinkProps["prefetch"], isDangerous: boolean): LinkPrefetchMode;
|
|
41
|
+
declare function canAutoPrefetchFullAppRoute(href: string): boolean;
|
|
19
42
|
declare const Link: React.ForwardRefExoticComponent<{
|
|
20
43
|
href: string | {
|
|
21
44
|
pathname?: string;
|
|
22
45
|
query?: UrlQuery;
|
|
23
46
|
}; /** URL displayed in the browser (when href is a route pattern like /user/[id]) */
|
|
24
47
|
as?: string; /** Replace the current history entry instead of pushing */
|
|
25
|
-
replace?: boolean; /** Prefetch the page in the background (default:
|
|
26
|
-
prefetch?: boolean; /** Whether to pass the href to the child element */
|
|
48
|
+
replace?: boolean; /** Prefetch the page in the background (App Router default: auto, Pages Router default: true) */
|
|
49
|
+
prefetch?: boolean | "auto" | null; /** Whether to pass the href to the child element */
|
|
27
50
|
passHref?: boolean; /** Scroll to top on navigation (default: true) */
|
|
28
51
|
scroll?: boolean; /** Locale for i18n (used for locale-prefixed URLs) */
|
|
29
52
|
locale?: string | false; /** Called before navigation happens (Next.js 16). Return value is ignored. */
|
|
@@ -31,5 +54,5 @@ declare const Link: React.ForwardRefExoticComponent<{
|
|
|
31
54
|
children?: React.ReactNode;
|
|
32
55
|
} & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href"> & React.RefAttributes<HTMLAnchorElement>>;
|
|
33
56
|
//#endregion
|
|
34
|
-
export { Link as default, useLinkStatus };
|
|
57
|
+
export { canAutoPrefetchFullAppRoute, Link as default, resolveLinkPrefetchMode, useLinkStatus };
|
|
35
58
|
//# sourceMappingURL=link.d.ts.map
|
package/dist/shims/link.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { stripBasePath } from "../utils/base-path.js";
|
|
3
|
+
import { createRouteTrieCache, matchRouteWithTrie } from "../routing/route-matching.js";
|
|
4
|
+
import { VINEXT_MOUNTED_SLOTS_HEADER } from "../server/headers.js";
|
|
2
5
|
import { isDangerousScheme } from "./url-safety.js";
|
|
3
6
|
import { resolveRelativeHref, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
4
7
|
import { addLocalePrefix, getDomainLocaleUrl } from "../utils/domain-locale.js";
|
|
5
8
|
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
6
9
|
import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
7
10
|
import "../server/app-elements.js";
|
|
8
|
-
import {
|
|
11
|
+
import { createRscRequestHeaders, createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
|
|
9
12
|
import { getCurrentInterceptionContext, getMountedSlotsHeader, getPrefetchedUrls, navigateClientSide, prefetchRscResponse } from "./navigation.js";
|
|
10
13
|
import { getI18nContext } from "./i18n-context.js";
|
|
14
|
+
import { canLinkPrefetch, getLinkPrefetchHref } from "./link-prefetch.js";
|
|
11
15
|
import React, { createContext, forwardRef, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
12
16
|
import { jsx } from "react/jsx-runtime";
|
|
13
17
|
//#region src/shims/link.tsx
|
|
@@ -29,6 +33,7 @@ function useLinkStatus() {
|
|
|
29
33
|
}
|
|
30
34
|
/** basePath from next.config.js, injected by the plugin at build time */
|
|
31
35
|
const __basePath = process.env.__NEXT_ROUTER_BASEPATH ?? "";
|
|
36
|
+
const linkPrefetchRouteTrieCache = createRouteTrieCache();
|
|
32
37
|
function resolveHref(href) {
|
|
33
38
|
if (typeof href === "string") return href;
|
|
34
39
|
let url = href.pathname ?? "/";
|
|
@@ -38,6 +43,32 @@ function resolveHref(href) {
|
|
|
38
43
|
}
|
|
39
44
|
return url;
|
|
40
45
|
}
|
|
46
|
+
function resolveLinkPrefetchMode(prefetchProp, isDangerous) {
|
|
47
|
+
if (isDangerous || prefetchProp === false) return "disabled";
|
|
48
|
+
if (prefetchProp === true) return "full";
|
|
49
|
+
return "auto";
|
|
50
|
+
}
|
|
51
|
+
function toSameOriginRouteHref(href) {
|
|
52
|
+
if (typeof window === "undefined") return null;
|
|
53
|
+
let url;
|
|
54
|
+
try {
|
|
55
|
+
url = new URL(href, window.location.href);
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
if (url.origin !== window.location.origin) return null;
|
|
60
|
+
return `${stripBasePath(url.pathname, __basePath)}${url.search}`;
|
|
61
|
+
}
|
|
62
|
+
function canAutoPrefetchFullAppRoute(href) {
|
|
63
|
+
if (typeof window === "undefined") return false;
|
|
64
|
+
const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
|
|
65
|
+
if (!routes) return false;
|
|
66
|
+
const routeHref = toSameOriginRouteHref(href);
|
|
67
|
+
if (routeHref === null) return false;
|
|
68
|
+
const match = matchRouteWithTrie(routeHref, routes, linkPrefetchRouteTrieCache);
|
|
69
|
+
if (!match) return false;
|
|
70
|
+
return !match.route.isDynamic;
|
|
71
|
+
}
|
|
41
72
|
/**
|
|
42
73
|
* Prefetch a URL for faster navigation.
|
|
43
74
|
*
|
|
@@ -48,22 +79,23 @@ function resolveHref(href) {
|
|
|
48
79
|
* Uses `requestIdleCallback` (or `setTimeout` fallback) to avoid blocking
|
|
49
80
|
* the main thread during initial page load.
|
|
50
81
|
*/
|
|
51
|
-
function prefetchUrl(href) {
|
|
82
|
+
function prefetchUrl(href, mode, priority = "low") {
|
|
52
83
|
if (typeof window === "undefined") return;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
84
|
+
const prefetchHref = getLinkPrefetchHref({
|
|
85
|
+
href,
|
|
86
|
+
basePath: __basePath,
|
|
87
|
+
currentOrigin: window.location.origin
|
|
88
|
+
});
|
|
89
|
+
if (prefetchHref == null) return;
|
|
59
90
|
const fullHref = toBrowserNavigationHref(prefetchHref, window.location.href, __basePath);
|
|
60
91
|
(window.requestIdleCallback ?? ((fn) => setTimeout(fn, 100)))(() => {
|
|
61
92
|
(async () => {
|
|
62
93
|
if (typeof window.__VINEXT_RSC_NAVIGATE__ === "function") {
|
|
94
|
+
if (mode === "auto" && !canAutoPrefetchFullAppRoute(prefetchHref)) return;
|
|
63
95
|
const interceptionContext = getCurrentInterceptionContext();
|
|
64
96
|
const mountedSlotsHeader = getMountedSlotsHeader();
|
|
65
97
|
const headers = createRscRequestHeaders({ interceptionContext });
|
|
66
|
-
if (mountedSlotsHeader) headers.set(
|
|
98
|
+
if (mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);
|
|
67
99
|
const rscUrl = await createRscRequestUrl(fullHref, headers);
|
|
68
100
|
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
69
101
|
const prefetched = getPrefetchedUrls();
|
|
@@ -72,7 +104,7 @@ function prefetchUrl(href) {
|
|
|
72
104
|
prefetchRscResponse(rscUrl, fetch(rscUrl, {
|
|
73
105
|
headers,
|
|
74
106
|
credentials: "include",
|
|
75
|
-
priority
|
|
107
|
+
priority,
|
|
76
108
|
purpose: "prefetch"
|
|
77
109
|
}), interceptionContext, mountedSlotsHeader);
|
|
78
110
|
} else if (window.__NEXT_DATA__?.__vinext?.pageModuleUrl) {
|
|
@@ -141,7 +173,7 @@ function applyLocaleToHref(href, locale) {
|
|
|
141
173
|
if (domainLocaleHref) return domainLocaleHref;
|
|
142
174
|
return addLocalePrefix(href, locale, getDefaultLocale() ?? "");
|
|
143
175
|
}
|
|
144
|
-
const Link = forwardRef(function Link({ href, as, replace = false, prefetch: prefetchProp, scroll = true, children, onClick, onNavigate, ...rest }, forwardedRef) {
|
|
176
|
+
const Link = forwardRef(function Link({ href, as, replace = false, prefetch: prefetchProp, scroll = true, children, onClick, onMouseEnter, onTouchStart, onNavigate, ...rest }, forwardedRef) {
|
|
145
177
|
const { locale, ...restWithoutLocale } = rest;
|
|
146
178
|
const resolvedHref = as ?? resolveHref(href);
|
|
147
179
|
const isDangerous = typeof resolvedHref === "string" && isDangerousScheme(resolvedHref);
|
|
@@ -156,7 +188,12 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
156
188
|
};
|
|
157
189
|
}, []);
|
|
158
190
|
const internalRef = useRef(null);
|
|
159
|
-
const
|
|
191
|
+
const prefetchMode = resolveLinkPrefetchMode(prefetchProp, isDangerous);
|
|
192
|
+
const shouldPrefetch = canLinkPrefetch({
|
|
193
|
+
nodeEnv: process.env.NODE_ENV,
|
|
194
|
+
prefetch: prefetchProp,
|
|
195
|
+
isDangerous
|
|
196
|
+
});
|
|
160
197
|
const setRefs = useCallback((node) => {
|
|
161
198
|
internalRef.current = node;
|
|
162
199
|
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
@@ -166,21 +203,41 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
166
203
|
if (!shouldPrefetch || typeof window === "undefined") return;
|
|
167
204
|
const node = internalRef.current;
|
|
168
205
|
if (!node) return;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
206
|
+
const hrefToPrefetch = getLinkPrefetchHref({
|
|
207
|
+
href: localizedHref,
|
|
208
|
+
basePath: __basePath,
|
|
209
|
+
currentOrigin: window.location.origin
|
|
210
|
+
});
|
|
211
|
+
if (hrefToPrefetch == null) return;
|
|
175
212
|
const observer = getSharedObserver();
|
|
176
213
|
if (!observer) return;
|
|
177
|
-
observerCallbacks.set(node, () => prefetchUrl(hrefToPrefetch));
|
|
214
|
+
observerCallbacks.set(node, () => prefetchUrl(hrefToPrefetch, prefetchMode, "low"));
|
|
178
215
|
observer.observe(node);
|
|
179
216
|
return () => {
|
|
180
217
|
observer.unobserve(node);
|
|
181
218
|
observerCallbacks.delete(node);
|
|
182
219
|
};
|
|
183
|
-
}, [
|
|
220
|
+
}, [
|
|
221
|
+
shouldPrefetch,
|
|
222
|
+
prefetchMode,
|
|
223
|
+
localizedHref
|
|
224
|
+
]);
|
|
225
|
+
const prefetchOnIntent = useCallback(() => {
|
|
226
|
+
if (!shouldPrefetch) return;
|
|
227
|
+
prefetchUrl(localizedHref, prefetchMode, "high");
|
|
228
|
+
}, [
|
|
229
|
+
shouldPrefetch,
|
|
230
|
+
prefetchMode,
|
|
231
|
+
localizedHref
|
|
232
|
+
]);
|
|
233
|
+
const handleMouseEnter = useCallback((e) => {
|
|
234
|
+
onMouseEnter?.(e);
|
|
235
|
+
prefetchOnIntent();
|
|
236
|
+
}, [onMouseEnter, prefetchOnIntent]);
|
|
237
|
+
const handleTouchStart = useCallback((e) => {
|
|
238
|
+
onTouchStart?.(e);
|
|
239
|
+
prefetchOnIntent();
|
|
240
|
+
}, [onTouchStart, prefetchOnIntent]);
|
|
184
241
|
const handleClick = async (e) => {
|
|
185
242
|
if (onClick) onClick(e);
|
|
186
243
|
if (e.defaultPrevented) return;
|
|
@@ -212,11 +269,12 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
212
269
|
} catch {}
|
|
213
270
|
if (typeof window.__VINEXT_RSC_NAVIGATE__ === "function") {
|
|
214
271
|
setPending(true);
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
272
|
+
React.startTransition(() => {
|
|
273
|
+
navigateClientSide(navigateHref, replace ? "replace" : "push", scroll, true).finally(() => {
|
|
274
|
+
if (mountedRef.current) setPending(false);
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
220
278
|
} else try {
|
|
221
279
|
const Router = (await import("next/router.js")).default;
|
|
222
280
|
if (replace) await Router.replace(absoluteHref, void 0, { scroll });
|
|
@@ -233,6 +291,8 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
233
291
|
if (process.env.NODE_ENV !== "production") console.warn(`<Link> blocked dangerous href: ${resolvedHref}`);
|
|
234
292
|
return /* @__PURE__ */ jsx("a", {
|
|
235
293
|
...anchorProps,
|
|
294
|
+
onMouseEnter: handleMouseEnter,
|
|
295
|
+
onTouchStart: handleTouchStart,
|
|
236
296
|
children
|
|
237
297
|
});
|
|
238
298
|
}
|
|
@@ -241,13 +301,17 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
241
301
|
children: /* @__PURE__ */ jsx("a", {
|
|
242
302
|
ref: setRefs,
|
|
243
303
|
href: fullHref,
|
|
244
|
-
onClick:
|
|
304
|
+
onClick: (event) => {
|
|
305
|
+
handleClick(event);
|
|
306
|
+
},
|
|
307
|
+
onMouseEnter: handleMouseEnter,
|
|
308
|
+
onTouchStart: handleTouchStart,
|
|
245
309
|
...anchorProps,
|
|
246
310
|
children
|
|
247
311
|
})
|
|
248
312
|
});
|
|
249
313
|
});
|
|
250
314
|
//#endregion
|
|
251
|
-
export { Link as default, useLinkStatus };
|
|
315
|
+
export { canAutoPrefetchFullAppRoute, Link as default, resolveLinkPrefetchMode, useLinkStatus };
|
|
252
316
|
|
|
253
317
|
//# sourceMappingURL=link.js.map
|