vinext 1.4.2 → 1.4.4
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 +4 -1
- package/dist/build/prerender-paths.d.ts +11 -1
- package/dist/build/prerender-paths.js +41 -11
- package/dist/cli.js +1 -1
- package/dist/client/dev-error-overlay.d.ts +2 -1
- package/dist/client/dev-error-overlay.js +8 -3
- package/dist/config/config-matchers.js +6 -2
- package/dist/config/next-config.d.ts +9 -0
- package/dist/entries/app-rsc-entry.js +24 -12
- package/dist/entries/pages-server-entry.js +17 -4
- package/dist/index.js +48 -39
- package/dist/init-platform.js +2 -2
- package/dist/init.js +42 -5
- package/dist/server/api-handler.js +8 -5
- package/dist/server/app-browser-entry.js +26 -47
- package/dist/server/app-browser-error.d.ts +1 -1
- package/dist/server/app-browser-error.js +13 -4
- package/dist/server/app-browser-navigation-controller.js +2 -2
- package/dist/server/app-browser-server-action-client.js +2 -2
- package/dist/server/app-browser-state.js +2 -2
- package/dist/server/app-browser-supplemental-refresh.d.ts +13 -0
- package/dist/server/app-browser-supplemental-refresh.js +36 -4
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-history-state.js +1 -1
- package/dist/server/app-middleware.d.ts +2 -0
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-page-boundary-render.js +4 -2
- package/dist/server/app-page-dispatch.d.ts +1 -0
- package/dist/server/app-page-dispatch.js +5 -1
- package/dist/server/app-page-element-builder.d.ts +2 -0
- package/dist/server/app-page-element-builder.js +6 -5
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +7 -5
- package/dist/server/app-page-route-wiring.js +11 -9
- package/dist/server/app-pages-bridge.d.ts +6 -0
- package/dist/server/app-pages-bridge.js +8 -3
- package/dist/server/app-request-context.js +1 -1
- package/dist/server/app-request-stage-independent-entry.js +2 -3
- package/dist/server/app-route-handler-dispatch.js +1 -1
- package/dist/server/app-route-handler-execution.js +1 -1
- package/dist/server/app-route-handler-response.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +27 -2
- package/dist/server/app-router-entry.js +2 -3
- package/dist/server/app-rsc-cache-busting.d.ts +8 -0
- package/dist/server/app-rsc-cache-busting.js +13 -1
- package/dist/server/app-rsc-combined-handler.js +2 -1
- package/dist/server/app-rsc-handler.d.ts +4 -0
- package/dist/server/app-rsc-handler.js +41 -24
- package/dist/server/app-rsc-response-finalizer.d.ts +15 -3
- package/dist/server/app-rsc-response-finalizer.js +51 -7
- package/dist/server/app-rsc-response-stage.js +1 -1
- package/dist/server/app-server-action-execution.js +1 -1
- package/dist/server/app-ssr-entry.js +18 -10
- package/dist/server/config-headers.d.ts +7 -0
- package/dist/server/config-headers.js +20 -1
- package/dist/server/edge-api-runtime.d.ts +6 -2
- package/dist/server/edge-api-runtime.js +21 -4
- package/dist/server/image-animation.d.ts +9 -0
- package/dist/server/image-animation.js +118 -0
- package/dist/server/image-optimization.d.ts +25 -5
- package/dist/server/image-optimization.js +305 -21
- package/dist/server/image-source-reader.d.ts +34 -0
- package/dist/server/image-source-reader.js +126 -0
- package/dist/server/metadata-route-response.d.ts +6 -1
- package/dist/server/metadata-route-response.js +24 -6
- package/dist/server/middleware-matcher.d.ts +1 -0
- package/dist/server/middleware-matcher.js +1 -1
- package/dist/server/middleware-runtime.d.ts +5 -0
- package/dist/server/middleware-runtime.js +48 -15
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +2 -1
- package/dist/server/navigation-planner.js +14 -6
- package/dist/server/nitro-request-target-plugin.d.ts +17 -0
- package/dist/server/nitro-request-target-plugin.js +22 -0
- package/dist/server/open-redirect.d.ts +2 -1
- package/dist/server/open-redirect.js +2 -1
- package/dist/server/pages-client-assets.d.ts +1 -0
- package/dist/server/pages-i18n.d.ts +7 -0
- package/dist/server/pages-i18n.js +14 -1
- package/dist/server/pages-node-compat.js +7 -3
- package/dist/server/pages-page-handler.js +4 -4
- package/dist/server/pages-request-pipeline.d.ts +9 -0
- package/dist/server/pages-request-pipeline.js +29 -10
- package/dist/server/pages-request-stage-entry.js +7 -2
- package/dist/server/pages-router-entry.js +3 -0
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +48 -54
- package/dist/server/remove-request-headers.d.ts +16 -0
- package/dist/server/remove-request-headers.js +23 -0
- package/dist/server/srvx-middleware-origin.d.ts +13 -0
- package/dist/server/srvx-middleware-origin.js +19 -0
- package/dist/server/srvx-request-target.d.ts +12 -0
- package/dist/server/srvx-request-target.js +20 -0
- package/dist/server/static-file-cache.js +10 -22
- package/dist/server/worker-image-optimization.d.ts +8 -1
- package/dist/server/worker-image-optimization.js +25 -6
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/shims/cache-runtime.js +1 -1
- package/dist/shims/cache.js +6 -3
- package/dist/shims/client-page-root.js +2 -2
- package/dist/shims/error-boundary.d.ts +6 -2
- package/dist/shims/error-boundary.js +6 -4
- package/dist/shims/internal/navigation-untracked.js +1 -1
- package/dist/shims/metadata.js +1 -1
- package/dist/shims/navigation-server.js +1 -1
- package/dist/shims/navigation.js +4 -4
- package/dist/shims/navigation.react-server.js +3 -3
- package/dist/shims/request-context.d.ts +3 -1
- package/dist/shims/root-params.js +16 -2
- package/dist/shims/slot.js +3 -3
- package/dist/shims/url-utils.js +6 -1
- package/dist/utils/client-entry-manifest.d.ts +5 -0
- package/dist/utils/client-entry-manifest.js +1 -0
- package/dist/utils/client-runtime-metadata.d.ts +5 -0
- package/dist/utils/client-runtime-metadata.js +33 -7
- package/package.json +1 -1
|
@@ -26,6 +26,8 @@ type RunAppMiddlewareOptions = {
|
|
|
26
26
|
isDataRequest: boolean;
|
|
27
27
|
middlewareRequest?: Request;
|
|
28
28
|
request: Request;
|
|
29
|
+
/** `shouldRestoreLocaleRootTrailingSlash` for the raw request pathname. */
|
|
30
|
+
restoreLocaleRootTrailingSlash?: boolean;
|
|
29
31
|
validateExternalRewriteRequest: () => Promise<Response | null>;
|
|
30
32
|
};
|
|
31
33
|
export type AppRscHandlerRoute = {
|
|
@@ -186,6 +188,8 @@ type RenderPagesFallbackOptions = {
|
|
|
186
188
|
pathname?: string;
|
|
187
189
|
pagesDataRequest?: Request | null;
|
|
188
190
|
request: Request;
|
|
191
|
+
/** The basePath `request.url` still carries, removed before the page renders. */
|
|
192
|
+
requestBasePath?: string;
|
|
189
193
|
/** The shared cache entry answers every host; a request-time render is not stored. */
|
|
190
194
|
sharedAcrossHosts?: boolean;
|
|
191
195
|
url: URL;
|
|
@@ -15,12 +15,13 @@ import { patternToNextFormat } from "../routing/route-validation.js";
|
|
|
15
15
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
16
16
|
import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
|
|
17
17
|
import { isInterceptionMatchedUrlPath, normalizePath } from "./normalize-path.js";
|
|
18
|
-
import { normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
|
|
18
|
+
import { isLocaleRedirect, normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
|
|
19
19
|
import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
|
|
20
20
|
import { markRouteCacheabilityDynamic, preserveRouteCacheabilityResponsePolicy } from "../shims/cacheability-classification.js";
|
|
21
21
|
import { NEVER_CACHE_CONTROL, SERVER_ACTION_CACHE_CONTROL, applyCdnResponseHeaders, captureCdnResponsePolicyOverrides, isCdnResponsePolicyHeader, reconcileCdnResponseHeadersAfterOuterPolicy } from "./cache-control.js";
|
|
22
22
|
import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
|
|
23
23
|
import { getDraftModeCookieHeader, getEffectiveRequestCookieHeader, getHeadersContext, hasEffectiveRequestCookieChanges, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, runWithHeadersContext } from "../shims/headers.js";
|
|
24
|
+
import { normalizePathTrailingSlash } from "../shims/url-utils.js";
|
|
24
25
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
25
26
|
import { getScriptNonceFromHeaderSources } from "./csp.js";
|
|
26
27
|
import { traceFindPageComponents } from "./pages-execution-tracing.js";
|
|
@@ -31,9 +32,11 @@ import { openForwardedMiddlewareContext } from "./forwarded-middleware-context.j
|
|
|
31
32
|
import { consumeResponseStageLinkProvenance, copyLinkHeaderProvenance } from "./app-response-header-provenance.js";
|
|
32
33
|
import { setFrameworkRequestRoute, traceFrameworkRequest } from "./request-tracing.js";
|
|
33
34
|
import { mergeMiddlewareResponseHeaders, mergeMiddlewareResponseHeadersOntoResponse, withExternalRewriteResponseHeaders } from "./middleware-response-headers.js";
|
|
34
|
-
import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestUrl, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
35
|
+
import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, canonicalizeDynamicShellRscRequestHeaders, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestUrl, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
35
36
|
import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
36
|
-
import {
|
|
37
|
+
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
38
|
+
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
39
|
+
import { applyAppRscConfigHeaders, finalizeAppRscResponse, isStreamedActionRedirectResponse, markAppRscApplicationResponse, markAppRscResponseConfigHeadersApplied, markAppRscRouteHandlerResponse, markStreamedActionRedirectResponse } from "./app-rsc-response-finalizer.js";
|
|
37
40
|
import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
|
|
38
41
|
import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
|
|
39
42
|
import "./app-page-response.js";
|
|
@@ -44,10 +47,8 @@ import { traceAppPageRender } from "./app-page-tracing.js";
|
|
|
44
47
|
import { normalizeInterceptionContextHeader } from "./app-interception-context-header.js";
|
|
45
48
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
46
49
|
import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
|
|
47
|
-
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
48
50
|
import { createRouteTreePrefetchResponse, isRouteTreePrefetchRequest } from "./app-route-tree-prefetch.js";
|
|
49
51
|
import { createSharedAppCacheIdentity, createSharedAppPageCacheIdentity, createSharedAppRouteCacheIdentity, createSharedHybridPagesCacheIdentity, isStaticCandidateAppPageDispatch, prepareSharedAppPageDispatch, withoutAppPageDispatchQuery } from "./app-worker-stages.js";
|
|
50
|
-
import { flattenErrorCauses } from "../utils/error-cause.js";
|
|
51
52
|
import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
|
|
52
53
|
import { hasPagesPreviewCookie } from "./pages-response-stage.js";
|
|
53
54
|
import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
|
|
@@ -442,6 +443,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
442
443
|
isDataRequest: isMiddlewareDataRequest,
|
|
443
444
|
middlewareRequest: isolatedMiddlewareRequest,
|
|
444
445
|
request: userlandRequest,
|
|
446
|
+
restoreLocaleRootTrailingSlash,
|
|
445
447
|
validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
|
|
446
448
|
});
|
|
447
449
|
if (!dispatchResponseStage && middlewareResult.pathnameEligible) markRouteCacheabilityDynamic(middlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
|
|
@@ -499,19 +501,28 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
499
501
|
const responseStagePolicy = await loadResponseStagePolicy();
|
|
500
502
|
const cache = responseStageProbeMode || isOnDemandRevalidate || (props.kind === "app-page" || props.kind === "app-route-handler") && (props.bypassInterceptionContextCache || props.forceDynamic === true && responseStagePolicy === null) ? "bypass" : canUseSharedWorkerResponseStage ? "shared" : "bypass";
|
|
501
503
|
let dispatchRequest = props.kind === "app-page" ? prepareSharedAppPageDispatch(stageRequest, cache) : stageRequest;
|
|
504
|
+
let dispatchProps = props;
|
|
502
505
|
let canonicalRsc = null;
|
|
503
506
|
if (cache === "shared" && props.kind === "app-page" && props.isRscRequest && (props.matchKind === "request" || props.matchKind === "resolved") && props.interceptionContext === null && props.interceptionId === null && props.mountedSlotsHeader === null) {
|
|
504
507
|
const headers = new Headers(dispatchRequest.headers);
|
|
505
|
-
if (props.renderMode === "navigation" ? canonicalizePrewarmableRscRequestHeaders(headers) : props.renderMode === "prefetch-loading-shell" && props.canUseCanonicalLoadingShell ? canonicalizeLoadingShellRscRequestHeaders(headers) : false) {
|
|
508
|
+
if (props.renderMode === "navigation" ? canonicalizePrewarmableRscRequestHeaders(headers) : props.renderMode === "prefetch-loading-shell" && props.canUseCanonicalLoadingShell ? canonicalizeLoadingShellRscRequestHeaders(headers) : props.renderMode === "prefetch-dynamic-shell" ? canonicalizeDynamicShellRscRequestHeaders(headers) : false) {
|
|
506
509
|
canonicalRsc = {
|
|
507
510
|
headers,
|
|
508
|
-
navigation: props.renderMode
|
|
511
|
+
navigation: props.renderMode !== "prefetch-loading-shell"
|
|
509
512
|
};
|
|
510
513
|
dispatchRequest = cloneRequestWithHeaders(dispatchRequest, headers);
|
|
514
|
+
if (props.renderMode === "prefetch-dynamic-shell") {
|
|
515
|
+
const queryFree = withoutAppPageDispatchQuery(dispatchRequest.url, {
|
|
516
|
+
...props,
|
|
517
|
+
renderMode: "navigation"
|
|
518
|
+
});
|
|
519
|
+
dispatchRequest = cloneRequestWithUrl(dispatchRequest, queryFree.url);
|
|
520
|
+
dispatchProps = queryFree.props;
|
|
521
|
+
}
|
|
511
522
|
}
|
|
512
523
|
}
|
|
513
524
|
let stageProps = {
|
|
514
|
-
...
|
|
525
|
+
...dispatchProps,
|
|
515
526
|
cacheability: {
|
|
516
527
|
...props.cacheability,
|
|
517
528
|
policyHeaders: responseStagePolicy
|
|
@@ -579,7 +590,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
579
590
|
}
|
|
580
591
|
return options.handleMetadataRouteRequest?.(cleanPathname, metadataRoutePathname) ?? null;
|
|
581
592
|
};
|
|
582
|
-
const applyConfigHeadersToResponseStage = async (response, preserveExistingPolicy = false) => {
|
|
593
|
+
const applyConfigHeadersToResponseStage = async (response, preserveExistingPolicy = false, routeHandlerRuntime) => {
|
|
583
594
|
const headers = new Headers(response.headers);
|
|
584
595
|
copyLinkHeaderProvenance(response.headers, headers);
|
|
585
596
|
await applyAppRscConfigHeaders(headers, request, {
|
|
@@ -590,7 +601,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
590
601
|
middlewareHeaders: middlewareContext.headers,
|
|
591
602
|
overwriteExisting: preserveExistingPolicy ? /* @__PURE__ */ new Set() : isCdnResponsePolicyHeader,
|
|
592
603
|
recordCacheability: dispatchResponseStage === void 0,
|
|
593
|
-
requestContext: preMiddlewareRequestContext
|
|
604
|
+
requestContext: preMiddlewareRequestContext,
|
|
605
|
+
routeHandlerRuntime
|
|
594
606
|
});
|
|
595
607
|
return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
|
|
596
608
|
headers,
|
|
@@ -616,10 +628,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
616
628
|
})();
|
|
617
629
|
let outerResponsePolicyPromise;
|
|
618
630
|
const loadOuterResponsePolicy = () => outerResponsePolicyPromise ??= Promise.all([loadPreHandlerResponseHeaders(), loadResponseStagePolicy()]).then(([headers, responseStagePolicy]) => captureCdnResponsePolicyOverrides(headers, new Headers(responseStagePolicy ?? [])));
|
|
619
|
-
const composeResponseStageResponse = async (response) => {
|
|
631
|
+
const composeResponseStageResponse = async (response, routeHandlerRuntime) => {
|
|
620
632
|
const transportedLink = consumeResponseStageLinkProvenance(response);
|
|
621
633
|
response = transportedLink.response;
|
|
622
|
-
response = await applyConfigHeadersToResponseStage(response, Boolean(dispatchResponseStage || options.renderResponseStageLocally));
|
|
634
|
+
response = await applyConfigHeadersToResponseStage(response, Boolean(dispatchResponseStage || options.renderResponseStageLocally), routeHandlerRuntime);
|
|
623
635
|
response = applyMiddlewareContextToResponse(response, middlewareContext, transportedLink.appendToPostConfigLink);
|
|
624
636
|
reconcileCdnResponseHeadersAfterOuterPolicy(response.headers, await loadOuterResponsePolicy());
|
|
625
637
|
return markAppRscResponseConfigHeadersApplied(response);
|
|
@@ -770,6 +782,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
770
782
|
hadBasePath: resolvedPathnameHasBasePath,
|
|
771
783
|
isDataRequest: isMiddlewareDataRequest,
|
|
772
784
|
request: sourceMiddlewareRequest,
|
|
785
|
+
restoreLocaleRootTrailingSlash: shouldRestoreLocaleRootTrailingSlash(normalizePathTrailingSlash(sourceUrlPathname, options.trailingSlash ?? false), options),
|
|
773
786
|
validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
|
|
774
787
|
}));
|
|
775
788
|
} finally {
|
|
@@ -778,6 +791,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
778
791
|
}
|
|
779
792
|
if (!dispatchResponseStage && sourceMiddlewareResult.pathnameEligible) markRouteCacheabilityDynamic(sourceMiddlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
|
|
780
793
|
if (sourceMiddlewareResult.kind === "response") {
|
|
794
|
+
if (request.body && !request.body.locked) request.body.cancel().catch(() => {});
|
|
781
795
|
options.clearRequestContext();
|
|
782
796
|
return sourceMiddlewareResult.response;
|
|
783
797
|
}
|
|
@@ -913,7 +927,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
913
927
|
request,
|
|
914
928
|
routeMatch
|
|
915
929
|
});
|
|
916
|
-
if (progressiveActionResult instanceof Response) return markServerActionResponse(progressiveActionResult);
|
|
930
|
+
if (progressiveActionResult instanceof Response) return markServerActionResponse(markAppRscApplicationResponse(progressiveActionResult));
|
|
917
931
|
if (progressiveActionResult?.kind !== "form-state") return null;
|
|
918
932
|
if ("actionError" in progressiveActionResult && middlewareContext.status === null && progressiveActionHttpFallbackStatus(progressiveActionResult.actionError) === null) middlewareContext.status = 500;
|
|
919
933
|
return progressiveActionResult;
|
|
@@ -998,23 +1012,24 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
998
1012
|
pathname: pagesRouteUrl,
|
|
999
1013
|
pagesDataRequest,
|
|
1000
1014
|
request,
|
|
1015
|
+
requestBasePath: hadBasePath ? options.basePath : "",
|
|
1001
1016
|
url
|
|
1002
1017
|
})) ?? null : null;
|
|
1003
1018
|
if (response) preserveRouteCacheabilityResponsePolicy();
|
|
1004
1019
|
if (!response) return null;
|
|
1005
1020
|
if (sharedOuterPolicyNeedsReconciliation) reconcileCdnResponseHeadersAfterOuterPolicy(response.headers, await loadOuterResponsePolicy());
|
|
1021
|
+
const markPagesResponse = (pagesResponse) => dispatchPagesResponseStage ? markAppRscResponseConfigHeadersApplied(pagesResponse) : isLocaleRedirect(response) ? pagesResponse : markAppRscApplicationResponse(pagesResponse);
|
|
1006
1022
|
const isRewritten = resolvedUrl !== originalResolvedUrl;
|
|
1007
1023
|
const isPrerender = typeof process !== "undefined" && process.env?.VINEXT_PRERENDER === "1";
|
|
1008
|
-
if ((!pagesDataRequest || !isRewritten) && !isPrerender) return
|
|
1024
|
+
if ((!pagesDataRequest || !isRewritten) && !isPrerender) return markPagesResponse(response);
|
|
1009
1025
|
const headers = new Headers(response.headers);
|
|
1010
1026
|
if (pagesDataRequest && isRewritten) headers.set("x-nextjs-rewrite", resolvedUrl);
|
|
1011
1027
|
if (isPrerender) headers.set(VINEXT_PRERENDER_REWRITTEN_HEADER, isRewritten ? "1" : "0");
|
|
1012
|
-
|
|
1028
|
+
return markPagesResponse(new Response(response.body, {
|
|
1013
1029
|
headers,
|
|
1014
1030
|
status: response.status,
|
|
1015
1031
|
statusText: response.statusText
|
|
1016
|
-
});
|
|
1017
|
-
return dispatchPagesResponseStage ? markAppRscResponseConfigHeadersApplied(markedResponse) : markedResponse;
|
|
1032
|
+
}));
|
|
1018
1033
|
};
|
|
1019
1034
|
const staticPagesFallbackResponse = await renderPagesForMatchKind("static");
|
|
1020
1035
|
if (staticPagesFallbackResponse) {
|
|
@@ -1198,7 +1213,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
1198
1213
|
route: null,
|
|
1199
1214
|
scriptNonce
|
|
1200
1215
|
}));
|
|
1201
|
-
if (renderedNotFoundResponse) return withUnmatchedRouteCacheControl(renderedNotFoundResponse);
|
|
1216
|
+
if (renderedNotFoundResponse) return markAppRscApplicationResponse(withUnmatchedRouteCacheControl(renderedNotFoundResponse));
|
|
1202
1217
|
options.clearRequestContext();
|
|
1203
1218
|
const headers = new Headers();
|
|
1204
1219
|
mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
|
|
@@ -1249,9 +1264,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
1249
1264
|
const rootParams = pickRootParams(renderParams, route.rootParamNames);
|
|
1250
1265
|
setRootParams(rootParams);
|
|
1251
1266
|
if (route.routeHandler) {
|
|
1252
|
-
const
|
|
1267
|
+
const routeHandlerRuntime = isEdgeRouteHandler(route.routeHandler) ? "edge" : "node";
|
|
1268
|
+
const routeHandlerRequest = routeHandlerRuntime === "edge" ? userlandRequest : request;
|
|
1253
1269
|
const routeHandlerUrl = new URL(routeHandlerRequest.url);
|
|
1254
|
-
const internalRscValues =
|
|
1270
|
+
const internalRscValues = routeHandlerRuntime === "edge" ? [] : routeHandlerUrl.searchParams.getAll(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
|
|
1255
1271
|
routeHandlerUrl.search = resolvedSearchParams.toString();
|
|
1256
1272
|
for (const internalRscValue of internalRscValues) routeHandlerUrl.searchParams.append(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, internalRscValue);
|
|
1257
1273
|
if (matchedResponseStage) return composeResponseStageResponse(await matchedResponseStage(responseStageRequest(), {
|
|
@@ -1279,10 +1295,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
1279
1295
|
routePattern: route.pattern,
|
|
1280
1296
|
routePathname: responseStageRoutePathname,
|
|
1281
1297
|
scriptNonce: scriptNonce ?? null
|
|
1282
|
-
}));
|
|
1298
|
+
}), routeHandlerRuntime);
|
|
1283
1299
|
const { setCurrentFetchSoftTags } = await import("../shims/fetch-cache.js");
|
|
1284
1300
|
setCurrentFetchSoftTags(buildPageCacheTags(cleanPathname, [], [...route.routeSegments], "route"));
|
|
1285
|
-
|
|
1301
|
+
const routeHandlerResponse = await options.dispatchMatchedRouteHandler({
|
|
1286
1302
|
bypassInterceptionContextCache,
|
|
1287
1303
|
cachePathname,
|
|
1288
1304
|
cleanPathname,
|
|
@@ -1292,6 +1308,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
1292
1308
|
route,
|
|
1293
1309
|
searchParams: resolvedSearchParams
|
|
1294
1310
|
});
|
|
1311
|
+
return markAppRscRouteHandlerResponse(routeHandlerResponse, routeHandlerRuntime);
|
|
1295
1312
|
}
|
|
1296
1313
|
const failedProgressiveActionResult = progressiveActionFormState && "actionError" in progressiveActionFormState ? progressiveActionFormState : null;
|
|
1297
1314
|
const actionHttpFallbackStatus = failedProgressiveActionResult ? progressiveActionHttpFallbackStatus(failedProgressiveActionResult.actionError) : null;
|
|
@@ -1354,8 +1371,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
|
|
|
1354
1371
|
searchParams: resolvedSearchParams,
|
|
1355
1372
|
renderMode
|
|
1356
1373
|
}), isRscRequest && request.headers.get("Next-Router-Prefetch") === "1" && request.headers.has("Next-Router-Segment-Prefetch"));
|
|
1357
|
-
if (progressiveActionFormState) return markServerActionResponse(applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState));
|
|
1358
|
-
return pageResponse;
|
|
1374
|
+
if (progressiveActionFormState) return markServerActionResponse(markAppRscApplicationResponse(applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState)));
|
|
1375
|
+
return markAppRscApplicationResponse(pageResponse);
|
|
1359
1376
|
}
|
|
1360
1377
|
function progressiveActionHttpFallbackStatus(actionError) {
|
|
1361
1378
|
const actionErrorDigest = actionError && typeof actionError === "object" && "digest" in actionError ? String(actionError.digest) : null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextHeader, NextI18nConfig } from "../config/next-config.js";
|
|
2
2
|
import { RequestContext } from "../config/request-context.js";
|
|
3
|
+
import { RouteHandlerRuntime } from "./config-headers.js";
|
|
3
4
|
//#region src/server/app-rsc-response-finalizer.d.ts
|
|
4
5
|
type FinalizeAppRscResponseOptions = {
|
|
5
6
|
basePath: string;
|
|
@@ -29,12 +30,23 @@ type FinalizeAppRscResponseOptions = {
|
|
|
29
30
|
middlewareHeaders?: Headers | null;
|
|
30
31
|
/** Whether config matching should update the active cacheability classification. */
|
|
31
32
|
recordCacheability?: boolean;
|
|
33
|
+
/** The runtime of the Route Handler that produced the response, if one did. */
|
|
34
|
+
routeHandlerRuntime?: RouteHandlerRuntime;
|
|
32
35
|
};
|
|
33
36
|
/** Mark a response whose final target pipeline has already applied config headers. */
|
|
34
37
|
export declare function markAppRscResponseConfigHeadersApplied(response: Response): Response;
|
|
35
38
|
/** Mark a Server Action redirect that streams its target's render, and so keeps its policy. */
|
|
36
39
|
export declare function markStreamedActionRedirectResponse(response: Response): Response;
|
|
37
40
|
export declare function isStreamedActionRedirectResponse(response: Response): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Mark a response that a page, Route Handler, Server Action or Pages route
|
|
43
|
+
* produced. Next.js stages next.config headers before application code runs,
|
|
44
|
+
* so the redirects these return carry them. Redirects that routing answers
|
|
45
|
+
* itself (next.config redirects, trailing slash, middleware) go out without.
|
|
46
|
+
*/
|
|
47
|
+
export declare function markAppRscApplicationResponse(response: Response): Response;
|
|
48
|
+
/** Mark a response a Route Handler produced, so its own headers meet config as in Next.js. */
|
|
49
|
+
export declare function markAppRscRouteHandlerResponse(response: Response, runtime: RouteHandlerRuntime): Response;
|
|
38
50
|
/** Apply only the matching next.config headers for an App Router request. */
|
|
39
51
|
export declare function applyAppRscConfigHeaders(headers: Headers, request: Request, options: FinalizeAppRscResponseOptions): Promise<void>;
|
|
40
52
|
/**
|
|
@@ -45,9 +57,9 @@ export declare function applyAppRscConfigHeaders(headers: Headers, request: Requ
|
|
|
45
57
|
* handling, so that every response path (page, route handler, server action,
|
|
46
58
|
* metadata, not-found) gets headers applied consistently.
|
|
47
59
|
*
|
|
48
|
-
* Skips 3xx
|
|
49
|
-
*
|
|
50
|
-
*
|
|
60
|
+
* Skips 3xx responses that routing answered itself, as Next.js does not
|
|
61
|
+
* apply config headers to those. A 3xx that application code returned is
|
|
62
|
+
* finalized like any other response.
|
|
51
63
|
*/
|
|
52
64
|
export declare function finalizeAppRscResponse(response: Response, request: Request, options: FinalizeAppRscResponseOptions): Promise<Response>;
|
|
53
65
|
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
|
|
1
2
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
3
|
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
|
|
3
4
|
import { sanitizeMethodNotAllowedHeaders } from "./http-error-responses.js";
|
|
@@ -6,12 +7,14 @@ import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
|
|
|
6
7
|
import { isNonCacheableCacheControl } from "../shims/cdn-cache.js";
|
|
7
8
|
import { captureRouteCacheabilityResponsePolicy } from "../shims/cacheability-classification.js";
|
|
8
9
|
import { NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, captureCdnResponsePolicyHeaders, hasExplicitNonCacheableResponsePolicy, isCdnResponsePolicyHeader } from "./cache-control.js";
|
|
9
|
-
import { hasPostConfigLinkHeaders } from "./app-response-header-provenance.js";
|
|
10
|
+
import { copyLinkHeaderProvenance, hasPostConfigLinkHeaders } from "./app-response-header-provenance.js";
|
|
10
11
|
import { mergeVaryHeader } from "./middleware-response-headers.js";
|
|
11
12
|
import "./app-rsc-cache-busting.js";
|
|
12
13
|
//#region src/server/app-rsc-response-finalizer.ts
|
|
13
14
|
const HAS_CONFIG_HEADERS = process.env.__VINEXT_HAS_CONFIG_HEADERS !== "false";
|
|
14
15
|
const configHeadersAlreadyApplied = /* @__PURE__ */ new WeakSet();
|
|
16
|
+
const applicationResponses = /* @__PURE__ */ new WeakSet();
|
|
17
|
+
const routeHandlerResponses = /* @__PURE__ */ new WeakMap();
|
|
15
18
|
function normalizeExplicitNonCacheablePolicy(headers) {
|
|
16
19
|
if (!hasExplicitNonCacheableResponsePolicy(headers)) return;
|
|
17
20
|
const cacheControl = headers.get("Cache-Control");
|
|
@@ -34,6 +37,39 @@ function markStreamedActionRedirectResponse(response) {
|
|
|
34
37
|
function isStreamedActionRedirectResponse(response) {
|
|
35
38
|
return streamedActionRedirects.has(response);
|
|
36
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Mark a response that a page, Route Handler, Server Action or Pages route
|
|
42
|
+
* produced. Next.js stages next.config headers before application code runs,
|
|
43
|
+
* so the redirects these return carry them. Redirects that routing answers
|
|
44
|
+
* itself (next.config redirects, trailing slash, middleware) go out without.
|
|
45
|
+
*/
|
|
46
|
+
function markAppRscApplicationResponse(response) {
|
|
47
|
+
applicationResponses.add(response);
|
|
48
|
+
return response;
|
|
49
|
+
}
|
|
50
|
+
/** Mark a response a Route Handler produced, so its own headers meet config as in Next.js. */
|
|
51
|
+
function markAppRscRouteHandlerResponse(response, runtime) {
|
|
52
|
+
routeHandlerResponses.set(response, runtime);
|
|
53
|
+
return markAppRscApplicationResponse(response);
|
|
54
|
+
}
|
|
55
|
+
/** Response.redirect() creates immutable headers; copy them only when needed. */
|
|
56
|
+
function withMutableHeaders(response) {
|
|
57
|
+
const probe = "x-vinext-mutable-headers-probe";
|
|
58
|
+
const probeValue = response.headers.get(probe);
|
|
59
|
+
try {
|
|
60
|
+
if (probeValue === null) response.headers.delete(probe);
|
|
61
|
+
else response.headers.set(probe, probeValue);
|
|
62
|
+
return response;
|
|
63
|
+
} catch {
|
|
64
|
+
const headers = new Headers(response.headers);
|
|
65
|
+
copyLinkHeaderProvenance(response.headers, headers);
|
|
66
|
+
return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
|
|
67
|
+
headers,
|
|
68
|
+
status: response.status,
|
|
69
|
+
statusText: response.statusText
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
37
73
|
/** Apply only the matching next.config headers for an App Router request. */
|
|
38
74
|
async function applyAppRscConfigHeaders(headers, request, options) {
|
|
39
75
|
if (!HAS_CONFIG_HEADERS || !options.configHeaders.length) return;
|
|
@@ -57,6 +93,7 @@ async function applyAppRscConfigHeaders(headers, request, options) {
|
|
|
57
93
|
appendToPostConfigLink: hasPostConfigLinkHeaders(headers),
|
|
58
94
|
middlewareHeaders: options.middlewareHeaders,
|
|
59
95
|
recordCacheability: options.recordCacheability,
|
|
96
|
+
routeHandlerRuntime: options.routeHandlerRuntime,
|
|
60
97
|
overwriteExisting: options.overwriteExisting ?? isCdnResponsePolicyHeader
|
|
61
98
|
});
|
|
62
99
|
}
|
|
@@ -68,12 +105,16 @@ async function applyAppRscConfigHeaders(headers, request, options) {
|
|
|
68
105
|
* handling, so that every response path (page, route handler, server action,
|
|
69
106
|
* metadata, not-found) gets headers applied consistently.
|
|
70
107
|
*
|
|
71
|
-
* Skips 3xx
|
|
72
|
-
*
|
|
73
|
-
*
|
|
108
|
+
* Skips 3xx responses that routing answered itself, as Next.js does not
|
|
109
|
+
* apply config headers to those. A 3xx that application code returned is
|
|
110
|
+
* finalized like any other response.
|
|
74
111
|
*/
|
|
75
112
|
async function finalizeAppRscResponse(response, request, options) {
|
|
76
|
-
|
|
113
|
+
const routeHandlerRuntime = routeHandlerResponses.get(response);
|
|
114
|
+
if (response.status >= 300 && response.status < 400) {
|
|
115
|
+
if (!applicationResponses.has(response) || configHeadersAlreadyApplied.has(response)) return response;
|
|
116
|
+
response = withMutableHeaders(response);
|
|
117
|
+
}
|
|
77
118
|
if (!isStaticFileSignal(response)) {
|
|
78
119
|
const varyHeader = response.headers.get("Vary");
|
|
79
120
|
if (varyHeader === null) response.headers.set("Vary", VINEXT_RSC_VARY_HEADER);
|
|
@@ -88,10 +129,13 @@ async function finalizeAppRscResponse(response, request, options) {
|
|
|
88
129
|
normalizeExplicitNonCacheablePolicy(response.headers);
|
|
89
130
|
return response;
|
|
90
131
|
}
|
|
91
|
-
await applyAppRscConfigHeaders(response.headers, request,
|
|
132
|
+
await applyAppRscConfigHeaders(response.headers, request, {
|
|
133
|
+
...options,
|
|
134
|
+
routeHandlerRuntime
|
|
135
|
+
});
|
|
92
136
|
normalizeExplicitNonCacheablePolicy(response.headers);
|
|
93
137
|
if (response.status === 405 && response.headers.get("Allow") === "GET, HEAD") sanitizeMethodNotAllowedHeaders(response.headers, "GET, HEAD");
|
|
94
138
|
return response;
|
|
95
139
|
}
|
|
96
140
|
//#endregion
|
|
97
|
-
export { applyAppRscConfigHeaders, finalizeAppRscResponse, isStreamedActionRedirectResponse, markAppRscResponseConfigHeadersApplied, markStreamedActionRedirectResponse };
|
|
141
|
+
export { applyAppRscConfigHeaders, finalizeAppRscResponse, isStreamedActionRedirectResponse, markAppRscApplicationResponse, markAppRscResponseConfigHeadersApplied, markAppRscRouteHandlerResponse, markStreamedActionRedirectResponse };
|
|
@@ -11,9 +11,9 @@ import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.
|
|
|
11
11
|
import { traceFindPageComponents } from "./pages-execution-tracing.js";
|
|
12
12
|
import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
|
|
13
13
|
import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, hasRscCacheBustingSearchParam, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
14
|
+
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
14
15
|
import { traceAppPageRender } from "./app-page-tracing.js";
|
|
15
16
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
16
|
-
import { pickRootParams, setRootParams } from "../shims/root-params.js";
|
|
17
17
|
import "./app-worker-stages.js";
|
|
18
18
|
import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
|
|
19
19
|
import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
|
|
@@ -22,6 +22,7 @@ import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
|
|
|
22
22
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
23
23
|
import { VINEXT_RSC_CONTENT_TYPE, applyRscCompatibilityIdHeader, createRscRequestUrl, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
24
24
|
import { getSetCookieName } from "./cookie-utils.js";
|
|
25
|
+
import { createRootParamsUsageController, runWithRootParamsUsage } from "../shims/root-params.js";
|
|
25
26
|
import { markAppRscResponseConfigHeadersApplied, markStreamedActionRedirectResponse } from "./app-rsc-response-finalizer.js";
|
|
26
27
|
import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
|
|
27
28
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
@@ -32,7 +33,6 @@ import { hasDigest } from "./app-rsc-errors.js";
|
|
|
32
33
|
import { buildAppPageTags } from "./implicit-tags.js";
|
|
33
34
|
import { resolveAppPageInterceptSegmentConfig } from "./app-page-intercept-segment-config.js";
|
|
34
35
|
import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
|
|
35
|
-
import { createRootParamsUsageController, runWithRootParamsUsage } from "../shims/root-params.js";
|
|
36
36
|
import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
|
|
37
37
|
//#region src/server/app-server-action-execution.ts
|
|
38
38
|
/**
|
|
@@ -13,27 +13,28 @@ import { getClientTraceMetadataHTML, markClientTraceMetadataBlock } from "./clie
|
|
|
13
13
|
import { setPagesClientAssets } from "./pages-client-assets.js";
|
|
14
14
|
import { RSC_FORM_STATE_GLOBAL } from "../client/browser-globals.js";
|
|
15
15
|
import { createNavigationRuntimeRenderedSearchScript, createNavigationRuntimeRscCompatibilityScript, createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, rewriteInlineCssStylesheetLinks, waitAtLeastOneReactRenderTask } from "./app-ssr-stream.js";
|
|
16
|
-
import {
|
|
17
|
-
import "
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
16
|
+
import { withAppRouterTree } from "../shims/app-router-tree-context.js";
|
|
17
|
+
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
18
|
+
import { runWithRootParamsScope } from "../shims/root-params.js";
|
|
19
|
+
import { CAUGHT_NOT_FOUND_BOUNDARIES_GLOBAL, withCaughtNotFoundBoundaries } from "../shims/caught-not-found-boundaries.js";
|
|
20
20
|
import { ServerInsertedHTMLContext, clearServerInsertedHTML, getBfcacheIdMapContext, registerServerInsertedHTMLCallback, renderServerInsertedHTML, setNavigationContext } from "../shims/navigation-context-state.js";
|
|
21
|
+
import { isBailoutToCSRError, isDynamicServerError } from "../shims/navigation-errors.js";
|
|
21
22
|
import "../shims/navigation-server.js";
|
|
23
|
+
import { AppElementsWire } from "./app-elements-wire.js";
|
|
24
|
+
import "./app-elements.js";
|
|
22
25
|
import { BfcacheIdentityMapContext } from "../shims/slot.js";
|
|
23
|
-
import { createAppRouteTree } from "./app-route-tree.js";
|
|
24
26
|
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
25
|
-
import {
|
|
27
|
+
import { runWithNavigationContext } from "../shims/navigation-state.js";
|
|
28
|
+
import { createInitialBfcacheMaps } from "./app-bfcache-identity.js";
|
|
29
|
+
import { createAppRouteTree } from "./app-route-tree.js";
|
|
26
30
|
import { ssrServerConsumerManifest } from "./app-client-reference-manifest.js";
|
|
27
31
|
import { createClientReferencePreloader, resolveRouteClientReferences } from "./app-client-reference-preloader.js";
|
|
28
32
|
import { getNextErrorDigest } from "./next-error-digest.js";
|
|
29
33
|
import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
|
|
30
34
|
import { createClientPageSsrSearchParamsSource } from "./app-page-search-params-observation.js";
|
|
31
35
|
import { createRenderStreamCancellation, isAppRenderAbortError } from "./app-render-abort-error.js";
|
|
32
|
-
import { runWithRootParamsScope } from "../shims/root-params.js";
|
|
33
|
-
import { runWithNavigationContext } from "../shims/navigation-state.js";
|
|
34
36
|
import { startCandidateSearchParamsGate } from "./app-ssr-search-params-gate.js";
|
|
35
|
-
import {
|
|
36
|
-
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
37
|
+
import { isSrvxAbsoluteFormTarget } from "./srvx-request-target.js";
|
|
37
38
|
import { renderBeforeInteractiveInlineScripts } from "./before-interactive-head.js";
|
|
38
39
|
import { createInitialDevServerErrorScript } from "./dev-initial-server-error.js";
|
|
39
40
|
import { createStreamedClientReferences, renderStreamedStylesheets, resetStreamedClientReferences, runWithStreamedClientReferences, wrapClientReferenceRequire } from "./app-streamed-client-references.js";
|
|
@@ -230,6 +231,12 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
230
231
|
fetchPriority: "low",
|
|
231
232
|
nonce: options?.scriptNonce
|
|
232
233
|
});
|
|
234
|
+
for (const moduleUrl of pagesClientAssets.appBootstrapPreloadModules ?? []) preloadModule(moduleUrl, {
|
|
235
|
+
as: "script",
|
|
236
|
+
crossOrigin: assetCrossOrigin,
|
|
237
|
+
fetchPriority: "low",
|
|
238
|
+
nonce: options?.scriptNonce
|
|
239
|
+
});
|
|
233
240
|
if (pagesClientAssets.appRouteManifestModule) preloadModule(pagesClientAssets.appRouteManifestModule, {
|
|
234
241
|
as: "script",
|
|
235
242
|
crossOrigin: assetCrossOrigin,
|
|
@@ -420,6 +427,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
420
427
|
});
|
|
421
428
|
}
|
|
422
429
|
var app_ssr_entry_default = { async fetch(request) {
|
|
430
|
+
if (isSrvxAbsoluteFormTarget(request)) return notFoundResponse();
|
|
423
431
|
const url = new URL(request.url);
|
|
424
432
|
const slashRedirect = repeatedSlashRedirectResponse(url.pathname + url.search);
|
|
425
433
|
if (slashRedirect) return slashRedirect;
|
|
@@ -3,6 +3,7 @@ import { RequestContext } from "../config/request-context.js";
|
|
|
3
3
|
import { BasePathMatchState } from "../config/config-matchers.js";
|
|
4
4
|
import { HeaderRecord } from "./request-pipeline.js";
|
|
5
5
|
//#region src/server/config-headers.d.ts
|
|
6
|
+
export type RouteHandlerRuntime = "node" | "edge";
|
|
6
7
|
export type ResponseStageCachePolicyOptions = {
|
|
7
8
|
basePathState?: BasePathMatchState;
|
|
8
9
|
configHeaders: NextHeader[];
|
|
@@ -34,6 +35,12 @@ type ApplyConfigHeadersOptions = {
|
|
|
34
35
|
middlewareHeaders?: Headers | null;
|
|
35
36
|
/** Whether this composition participates in response-cache admission. */
|
|
36
37
|
recordCacheability?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Set when a Route Handler produced the response. Next.js copies a Node
|
|
40
|
+
* handler's headers only where config left none, and appends an edge
|
|
41
|
+
* handler's after config. Cache policy headers keep their own rules.
|
|
42
|
+
*/
|
|
43
|
+
routeHandlerRuntime?: RouteHandlerRuntime;
|
|
37
44
|
};
|
|
38
45
|
/** Apply matched next.config.js headers to a Web Headers object. */
|
|
39
46
|
export declare function applyConfigHeadersToResponse(responseHeaders: Headers, options: ApplyConfigHeadersOptions): void;
|
|
@@ -5,6 +5,15 @@ import { isCdnResponsePolicyHeader, isNonCacheableCdnResponsePolicy } from "./ca
|
|
|
5
5
|
import { mergeVaryHeader } from "./middleware-response-headers.js";
|
|
6
6
|
//#region src/server/config-headers.ts
|
|
7
7
|
const ADDITIVE_CONFIG_HEADER_NAMES = /* @__PURE__ */ new Set(["set-cookie", "vary"]);
|
|
8
|
+
const ROUTE_HANDLER_APPENDED_HEADER_NAMES = /* @__PURE__ */ new Set(["www-authenticate", "proxy-authenticate"]);
|
|
9
|
+
/**
|
|
10
|
+
* Next.js sets x-nextjs-cache over config only on the responses its cache
|
|
11
|
+
* manages, which vinext marks with x-vinext-cache too. A Route Handler's own
|
|
12
|
+
* x-nextjs-cache meets config like any other header.
|
|
13
|
+
*/
|
|
14
|
+
function isFrameworkCacheStateHeader(headers, lowerName) {
|
|
15
|
+
return lowerName === "X-Vinext-Cache".toLowerCase() || lowerName === "x-nextjs-cache" && headers.has("X-Vinext-Cache");
|
|
16
|
+
}
|
|
8
17
|
/**
|
|
9
18
|
* Resolve positive config cache policy that must accompany an inner artifact.
|
|
10
19
|
* The request stage evaluates every condition. Shared stage transports must key
|
|
@@ -77,6 +86,7 @@ function applyConfigHeadersToResponse(responseHeaders, options) {
|
|
|
77
86
|
const matched = retainLastSingularConfigValues(matchHeaders(options.pathname, options.configHeaders, options.requestContext, options.basePathState, options.recordCacheability === false ? void 0 : markConditionalConfigHeaderCacheability));
|
|
78
87
|
if (options.recordCacheability !== false) markExplicitConfigResponseVeto(matched);
|
|
79
88
|
const configCookies = [];
|
|
89
|
+
const configVary = [];
|
|
80
90
|
for (const header of matched) {
|
|
81
91
|
const lowerName = header.key.toLowerCase();
|
|
82
92
|
if (lowerName === "x-vinext-special-error-status") continue;
|
|
@@ -86,9 +96,18 @@ function applyConfigHeadersToResponse(responseHeaders, options) {
|
|
|
86
96
|
const postConfigLink = options.appendToPostConfigLink ? responseHeaders.get(lowerName) : null;
|
|
87
97
|
responseHeaders.set(header.key, postConfigLink ? `${header.value}, ${postConfigLink}` : header.value);
|
|
88
98
|
} else if (!ADDITIVE_CONFIG_HEADER_NAMES.has(lowerName) && options.middlewareHeaders?.has(lowerName)) continue;
|
|
89
|
-
else if (lowerName === "vary")
|
|
99
|
+
else if (lowerName === "vary") configVary.push(header.value);
|
|
90
100
|
else if (ADDITIVE_CONFIG_HEADER_NAMES.has(lowerName)) responseHeaders.append(header.key, header.value);
|
|
91
101
|
else if ((typeof options.overwriteExisting === "function" ? options.overwriteExisting(lowerName) : options.overwriteExisting?.has(lowerName)) || !responseHeaders.has(lowerName)) responseHeaders.set(header.key, header.value);
|
|
102
|
+
else if (options.routeHandlerRuntime && !isFrameworkCacheStateHeader(responseHeaders, lowerName) && !isCdnResponsePolicyHeader(lowerName)) {
|
|
103
|
+
const handlerValue = responseHeaders.get(lowerName);
|
|
104
|
+
responseHeaders.set(header.key, handlerValue !== header.value && (options.routeHandlerRuntime === "edge" || ROUTE_HANDLER_APPENDED_HEADER_NAMES.has(lowerName)) ? `${header.value}, ${handlerValue}` : header.value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (configVary.length > 0) {
|
|
108
|
+
const routeHandlerVary = options.routeHandlerRuntime ? responseHeaders.get("vary") : null;
|
|
109
|
+
if (routeHandlerVary) responseHeaders.delete("vary");
|
|
110
|
+
for (const value of [...configVary, ...routeHandlerVary ? [routeHandlerVary] : []]) mergeVaryHeader(responseHeaders, value);
|
|
92
111
|
}
|
|
93
112
|
if (configCookies.length > 0 && !options.middlewareHeaders?.get("set-cookie")) {
|
|
94
113
|
const responseCookies = responseHeaders.getSetCookie();
|
|
@@ -5,8 +5,12 @@ export type EdgeApiExecutionRuntime = "node" | "worker";
|
|
|
5
5
|
* Remove wire-level body headers after Node's fetch implementation has decoded
|
|
6
6
|
* an Edge API response. Next.js applies the same boundary in its edge sandbox.
|
|
7
7
|
*
|
|
8
|
-
* Workers keep the original response untouched: workerd preserves
|
|
9
|
-
* body/header pair and can stream it directly to the client.
|
|
8
|
+
* Workers otherwise keep the original response untouched: workerd preserves
|
|
9
|
+
* the encoded body/header pair and can stream it directly to the client.
|
|
10
|
+
*
|
|
11
|
+
* Both runtimes drop `x-middleware-set-cookie`, the internal copy of the
|
|
12
|
+
* cookies that `NextResponse.cookies` keeps for middleware. Next.js's
|
|
13
|
+
* send-response never writes it to the client.
|
|
10
14
|
*/
|
|
11
15
|
export declare function finalizeEdgeApiResponse(response: Response, runtime: EdgeApiExecutionRuntime): Response;
|
|
12
16
|
//#endregion
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { MIDDLEWARE_SET_COOKIE_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
+
import "./headers.js";
|
|
1
3
|
//#region src/server/edge-api-runtime.ts
|
|
2
4
|
function isEdgeApiRuntime(runtime) {
|
|
3
5
|
return runtime === "edge" || runtime === "experimental-edge";
|
|
@@ -11,13 +13,28 @@ const NODE_EDGE_RESPONSE_FORBIDDEN_HEADERS = [
|
|
|
11
13
|
* Remove wire-level body headers after Node's fetch implementation has decoded
|
|
12
14
|
* an Edge API response. Next.js applies the same boundary in its edge sandbox.
|
|
13
15
|
*
|
|
14
|
-
* Workers keep the original response untouched: workerd preserves
|
|
15
|
-
* body/header pair and can stream it directly to the client.
|
|
16
|
+
* Workers otherwise keep the original response untouched: workerd preserves
|
|
17
|
+
* the encoded body/header pair and can stream it directly to the client.
|
|
18
|
+
*
|
|
19
|
+
* Both runtimes drop `x-middleware-set-cookie`, the internal copy of the
|
|
20
|
+
* cookies that `NextResponse.cookies` keeps for middleware. Next.js's
|
|
21
|
+
* send-response never writes it to the client.
|
|
16
22
|
*/
|
|
17
23
|
function finalizeEdgeApiResponse(response, runtime) {
|
|
18
|
-
if (runtime === "worker")
|
|
24
|
+
if (runtime === "worker") {
|
|
25
|
+
if (!response.headers.has("x-middleware-set-cookie")) return response;
|
|
26
|
+
try {
|
|
27
|
+
response.headers.delete(MIDDLEWARE_SET_COOKIE_HEADER);
|
|
28
|
+
return response;
|
|
29
|
+
} catch {
|
|
30
|
+
const copy = new Response(response.body, response);
|
|
31
|
+
copy.headers.delete(MIDDLEWARE_SET_COOKIE_HEADER);
|
|
32
|
+
return copy;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
19
35
|
const headers = new Headers(response.headers);
|
|
20
|
-
let changed =
|
|
36
|
+
let changed = headers.has(MIDDLEWARE_SET_COOKIE_HEADER);
|
|
37
|
+
headers.delete(MIDDLEWARE_SET_COOKIE_HEADER);
|
|
21
38
|
for (const name of NODE_EDGE_RESPONSE_FORBIDDEN_HEADERS) {
|
|
22
39
|
if (!headers.has(name)) continue;
|
|
23
40
|
headers.delete(name);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ImageSourceReader } from "./image-source-reader.js";
|
|
2
|
+
//#region src/server/image-animation.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether a source is an animated GIF, PNG or WebP, judged by its signature.
|
|
5
|
+
* The source is parsed as it streams in, so only the bytes a format's check
|
|
6
|
+
* needs are read, and none are kept beyond what the reader holds to replay.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isAnimatedImage(source: ImageSourceReader): Promise<boolean>;
|
|
9
|
+
//#endregion
|