vinext 1.0.0-beta.11 → 1.0.0-beta.13
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 +39 -12
- package/dist/build/action-owner-manifest.js +23 -5
- package/dist/build/lifecycle.d.ts +42 -0
- package/dist/build/lifecycle.js +246 -0
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +0 -3
- package/dist/build/pages-client-assets-module.js +1 -13
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.d.ts +1 -1
- package/dist/build/prerender-paths.js +6 -6
- package/dist/build/prerender-server-pool.js +1 -1
- package/dist/build/prerender.d.ts +1 -1
- package/dist/build/prerender.js +5 -5
- package/dist/build/preview-credentials.d.ts +1 -1
- package/dist/build/preview-credentials.js +2 -2
- package/dist/build/report.js +1 -1
- package/dist/build/run-prerender.d.ts +2 -2
- package/dist/build/run-prerender.js +5 -5
- package/dist/build/standalone.js +2 -2
- package/dist/cli-args.d.ts +5 -13
- package/dist/cli-args.js +2 -45
- package/dist/cli-dev-config.d.ts +6 -2
- package/dist/cli-dev-config.js +160 -3
- package/dist/cli.js +104 -439
- package/dist/config/config-matchers.js +1 -1
- package/dist/config/next-config.d.ts +2 -2
- package/dist/config/next-config.js +5 -5
- package/dist/config/prerender.d.ts +3 -0
- package/dist/config/prerender.js +8 -2
- package/dist/entries/app-browser-entry.js +1 -1
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +25 -5
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +17 -2
- package/dist/index.d.ts +6 -8
- package/dist/index.js +282 -105
- package/dist/init-cloudflare.d.ts +3 -2
- package/dist/init-cloudflare.js +117 -5
- package/dist/init-platform.d.ts +2 -0
- package/dist/init-platform.js +9 -3
- package/dist/init.d.ts +7 -5
- package/dist/init.js +41 -22
- package/dist/plugins/dynamic-preload-metadata.js +1 -1
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +1 -1
- package/dist/plugins/import-meta-url.js +1 -1
- package/dist/plugins/instrumentation-client.js +1 -1
- package/dist/plugins/og-assets.js +32 -13
- package/dist/plugins/og-harfbuzz.d.ts +24 -0
- package/dist/plugins/og-harfbuzz.js +260 -0
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/require-condition-resolution.js +2 -2
- package/dist/plugins/require-context.js +2 -2
- package/dist/plugins/typeof-window.js +1 -1
- package/dist/plugins/use-cache-callable.d.ts +0 -2
- package/dist/plugins/use-cache-callable.js +40 -22
- package/dist/plugins/worker-image-imports.js +1 -1
- package/dist/routing/app-route-graph.js +1 -1
- package/dist/routing/app-router.js +1 -1
- package/dist/routing/pages-router.js +1 -1
- package/dist/server/app-action-forwarding.js +1 -1
- package/dist/server/app-browser-entry.js +1 -0
- package/dist/server/app-browser-error.js +1 -1
- package/dist/server/app-elements-wire.js +2 -2
- package/dist/server/app-middleware.js +1 -1
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +14 -2
- package/dist/server/app-page-dispatch.js +1 -1
- package/dist/server/app-page-element-builder.js +3 -2
- package/dist/server/app-page-probe.js +3 -3
- package/dist/server/app-page-render.js +1 -0
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +16 -12
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-request-stage-independent-entry.js +2 -2
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +3 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +2 -2
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-router-entry.js +2 -2
- package/dist/server/app-rsc-handler.d.ts +9 -2
- package/dist/server/app-rsc-handler.js +30 -10
- package/dist/server/app-rsc-response-stage.js +6 -3
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.js +35 -6
- package/dist/server/app-ssr-entry.js +7 -2
- package/dist/server/app-ssr-stream.js +25 -6
- package/dist/server/app-worker-stages.d.ts +4 -1
- package/dist/server/app-worker-stages.js +4 -4
- package/dist/server/artifact-compatibility.js +1 -1
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/dev-lockfile.d.ts +1 -1
- package/dist/server/dev-lockfile.js +4 -1
- package/dist/server/dev-server.d.ts +1 -1
- package/dist/server/dev-server.js +28 -6
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/html.d.ts +0 -20
- package/dist/server/html.js +16 -1
- package/dist/server/instrumentation.d.ts +4 -9
- package/dist/server/instrumentation.js +10 -15
- package/dist/server/isr-cache.js +3 -3
- package/dist/server/metadata-route-response.d.ts +1 -0
- package/dist/server/metadata-route-response.js +65 -0
- package/dist/server/middleware-runtime.js +3 -3
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +37 -2
- package/dist/server/pages-client-assets.d.ts +7 -0
- package/dist/server/pages-data-route.js +1 -1
- package/dist/server/pages-dev-hydration.d.ts +6 -0
- package/dist/server/pages-dev-hydration.js +19 -7
- package/dist/server/pages-document-initial-props.d.ts +1 -0
- package/dist/server/pages-document-initial-props.js +1 -1
- package/dist/server/pages-page-data.js +2 -2
- package/dist/server/pages-page-handler.js +5 -2
- package/dist/server/pages-page-response.d.ts +1 -0
- package/dist/server/pages-page-response.js +3 -2
- package/dist/server/pages-request-pipeline.js +3 -3
- package/dist/server/pages-request-stage-entry.js +3 -3
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.js +19 -13
- package/dist/server/request-pipeline.js +2 -2
- package/dist/server/rsc-stream-hints.d.ts +12 -0
- package/dist/server/rsc-stream-hints.js +70 -35
- package/dist/server/seed-cache.js +3 -4
- package/dist/server/socket-error-backstop.js +1 -1
- package/dist/shims/cache-callable-runtime.d.ts +38 -0
- package/dist/shims/cache-callable-runtime.js +162 -11
- package/dist/shims/cache-runtime.d.ts +6 -8
- package/dist/shims/cache-runtime.js +89 -24
- package/dist/shims/constants.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +6 -2
- package/dist/shims/font-local.js +1 -1
- package/dist/shims/form.js +1 -1
- package/dist/shims/head.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/image-config.js +2 -0
- package/dist/shims/internal/app-page-props-cache-key.d.ts +29 -0
- package/dist/shims/internal/app-page-props-cache-key.js +53 -1
- package/dist/shims/internal/format-url-object.d.ts +7 -0
- package/dist/shims/internal/format-url-object.js +53 -0
- package/dist/shims/internal/normalize-router-href.d.ts +15 -0
- package/dist/shims/internal/normalize-router-href.js +41 -0
- package/dist/shims/internal/pages-data-target.d.ts +4 -1
- package/dist/shims/internal/pages-data-target.js +28 -35
- package/dist/shims/internal/route-pattern-for-warning.d.ts +2 -2
- package/dist/shims/internal/route-pattern-for-warning.js +3 -3
- package/dist/shims/link.js +31 -92
- package/dist/shims/metadata.js +5 -4
- package/dist/shims/navigation.js +2 -2
- package/dist/shims/router-state.js +1 -1
- package/dist/shims/router.d.ts +8 -7
- package/dist/shims/router.js +312 -148
- package/dist/shims/script-nonce-context.d.ts +4 -1
- package/dist/shims/script-nonce-context.js +15 -6
- package/dist/shims/server.js +3 -3
- package/dist/utils/built-asset-url.js +1 -1
- package/dist/utils/client-runtime-metadata.d.ts +6 -0
- package/dist/utils/client-runtime-metadata.js +16 -0
- package/dist/utils/lazy-chunks.js +1 -1
- package/dist/utils/project.d.ts +1 -11
- package/dist/utils/project.js +20 -29
- package/dist/utils/react-version.d.ts +3 -1
- package/dist/utils/react-version.js +19 -1
- package/dist/utils/vite-cli-invocation.d.ts +21 -0
- package/dist/utils/vite-cli-invocation.js +144 -0
- package/package.json +10 -2
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { markFullyBufferedBody } from "./fully-buffered-response.js";
|
|
2
2
|
import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
3
|
+
import { decodeMatchedParams } from "../routing/utils.js";
|
|
3
4
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
5
|
import { VINEXT_METADATA_ROUTE_CACHE_HEADER } from "./headers.js";
|
|
5
6
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
7
|
+
import { beginRouteCacheability, markRouteCacheabilityExplicitResponsePolicy } from "../shims/cacheability-classification.js";
|
|
8
|
+
import { hasCdnResponsePolicy, hasExplicitNonCacheableResponsePolicy } from "./cache-control.js";
|
|
6
9
|
import { isrCacheControl } from "./isr-cache.js";
|
|
7
10
|
import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
|
|
8
11
|
import { _consumeRequestScopedCacheLife, cacheLifeProfiles } from "../shims/cache-request-state.js";
|
|
9
12
|
import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
|
|
10
13
|
import { isValidMetadataImageId, manifestToJson, matchMetadataRoutePattern, robotsToText, sitemapToXml } from "./metadata-routes.js";
|
|
11
14
|
import { applyPrerenderCacheLifeHeader, applyPrerenderCacheTagsHeader } from "./prerender-cache-life-header.js";
|
|
15
|
+
import { canonicalizeAppPageParams } from "./app-page-segment-state.js";
|
|
12
16
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
13
17
|
import { buildAppRouteCacheValue, buildRouteHandlerCachedResponse } from "./app-route-handler-response.js";
|
|
14
18
|
import { isMetadataResponseCacheable } from "./metadata-route-cache-policy.js";
|
|
@@ -50,6 +54,7 @@ function metadataRouteCacheHeader(route) {
|
|
|
50
54
|
return CACHE_HEADERS.revalidate;
|
|
51
55
|
}
|
|
52
56
|
function withMetadataRouteCacheHeader(response, route) {
|
|
57
|
+
if (hasCdnResponsePolicy(response.headers) && !hasExplicitNonCacheableResponsePolicy(response.headers)) markRouteCacheabilityExplicitResponsePolicy();
|
|
53
58
|
const headers = new Headers(response.headers);
|
|
54
59
|
if (!headers.has("Cache-Control")) headers.set("Cache-Control", metadataRouteCacheHeader(route));
|
|
55
60
|
return new Response(response.body, {
|
|
@@ -58,13 +63,18 @@ function withMetadataRouteCacheHeader(response, route) {
|
|
|
58
63
|
statusText: response.statusText
|
|
59
64
|
});
|
|
60
65
|
}
|
|
66
|
+
function beginMetadataRouteCacheability(route) {
|
|
67
|
+
beginRouteCacheability("app-route", route.patternParts ? `/${route.patternParts.join("/")}` : route.servedUrl);
|
|
68
|
+
}
|
|
61
69
|
function getMetadataRouteFunctions(route) {
|
|
62
70
|
const cached = routeFunctionCache.get(route);
|
|
63
71
|
if (cached) return cached;
|
|
64
72
|
const generateImageMetadata = route.isDynamic && isImageMetadataRoute(route) ? readFunction(route.module, "generateImageMetadata") : null;
|
|
65
73
|
const functions = {
|
|
66
74
|
defaultExport: route.isDynamic ? readFunction(route.module, "default") : null,
|
|
75
|
+
dynamicParams: route.isDynamic && typeof route.module?.dynamicParams === "boolean" ? route.module.dynamicParams : void 0,
|
|
67
76
|
generateImageMetadata,
|
|
77
|
+
generateStaticParams: route.isDynamic ? readFunction(route.module, "generateStaticParams") : null,
|
|
68
78
|
generateSitemaps: route.type === "sitemap" && route.isDynamic ? readFunction(route.module, "generateSitemaps") : null,
|
|
69
79
|
hasGeneratedImageMetadata: route.isDynamic && isImageMetadataRoute(route) && Boolean(generateImageMetadata)
|
|
70
80
|
};
|
|
@@ -256,6 +266,39 @@ function matchMetadataRoute(route, cleanPathname, functions, getUrlParts) {
|
|
|
256
266
|
imageId: null
|
|
257
267
|
} : null;
|
|
258
268
|
}
|
|
269
|
+
function metadataRouteParamNames(patternParts) {
|
|
270
|
+
return patternParts.flatMap((part) => {
|
|
271
|
+
if (!part.startsWith(":")) return [];
|
|
272
|
+
return [part.slice(1, part.endsWith("+") || part.endsWith("*") ? -1 : void 0)];
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function metadataRouteOptionalCatchAllParamNames(patternParts) {
|
|
276
|
+
return patternParts.flatMap((part) => part.startsWith(":") && part.endsWith("*") ? [part.slice(1, -1)] : []);
|
|
277
|
+
}
|
|
278
|
+
function metadataRouteRawParams(route, match, routePathname) {
|
|
279
|
+
const urlParts = routePathname.split("/").filter(Boolean);
|
|
280
|
+
if (match.imageId !== null) urlParts.pop();
|
|
281
|
+
const params = Object.create(null);
|
|
282
|
+
let urlIndex = 0;
|
|
283
|
+
for (const part of route.patternParts ?? []) {
|
|
284
|
+
if (!part.startsWith(":")) {
|
|
285
|
+
urlIndex++;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
const isCatchAll = part.endsWith("+") || part.endsWith("*");
|
|
289
|
+
const name = part.slice(1, isCatchAll ? -1 : void 0);
|
|
290
|
+
if (!isCatchAll) {
|
|
291
|
+
const value = urlParts[urlIndex++];
|
|
292
|
+
if (value !== void 0) params[name] = value;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const matchedValue = match.params?.[name];
|
|
296
|
+
const valueCount = Array.isArray(matchedValue) ? matchedValue.length : matchedValue ? 1 : 0;
|
|
297
|
+
if (valueCount > 0) params[name] = urlParts.slice(urlIndex, urlIndex + valueCount);
|
|
298
|
+
urlIndex += valueCount;
|
|
299
|
+
}
|
|
300
|
+
return params;
|
|
301
|
+
}
|
|
259
302
|
function findGeneratedSitemapId(entries, rawId) {
|
|
260
303
|
if (!Array.isArray(entries)) return null;
|
|
261
304
|
for (const entry of entries) {
|
|
@@ -386,6 +429,7 @@ async function handleMetadataRouteRequest(options) {
|
|
|
386
429
|
if (route.type === "sitemap" && route.isDynamic) {
|
|
387
430
|
if (functions.generateSitemaps) {
|
|
388
431
|
if (isGeneratedSitemapPath(route, options.cleanPathname)) {
|
|
432
|
+
beginMetadataRouteCacheability(route);
|
|
389
433
|
const render = async () => {
|
|
390
434
|
setCurrentFetchSoftTags(buildMetadataRouteTags(route, options.cleanPathname, []));
|
|
391
435
|
const response = await handleGeneratedSitemap(route, options.cleanPathname, functions);
|
|
@@ -404,6 +448,27 @@ async function handleMetadataRouteRequest(options) {
|
|
|
404
448
|
}
|
|
405
449
|
const match = matchMetadataRoute(route, options.cleanPathname, functions, getUrlParts);
|
|
406
450
|
if (!match) continue;
|
|
451
|
+
beginMetadataRouteCacheability(route);
|
|
452
|
+
const rawParams = route.patternParts ? metadataRouteRawParams(route, match, options.routePathname ?? options.cleanPathname) : Object.create(null);
|
|
453
|
+
if (route.patternParts) {
|
|
454
|
+
const runtimeParams = { ...rawParams };
|
|
455
|
+
decodeMatchedParams(runtimeParams);
|
|
456
|
+
match.params = runtimeParams;
|
|
457
|
+
}
|
|
458
|
+
if (route.isDynamic && isImageMetadataRoute(route) && functions.dynamicParams === false) {
|
|
459
|
+
const validationParams = { ...rawParams };
|
|
460
|
+
canonicalizeAppPageParams(validationParams);
|
|
461
|
+
const { validateAppPageDynamicParams } = await import("./app-page-request.js");
|
|
462
|
+
const dynamicParamsResponse = await validateAppPageDynamicParams({
|
|
463
|
+
enforceStaticParamsOnly: true,
|
|
464
|
+
generateStaticParams: functions.generateStaticParams,
|
|
465
|
+
isDynamicRoute: Boolean(route.patternParts),
|
|
466
|
+
optionalCatchAllParamNames: metadataRouteOptionalCatchAllParamNames(route.patternParts ?? []),
|
|
467
|
+
params: validationParams,
|
|
468
|
+
requiredParamNames: metadataRouteParamNames(route.patternParts ?? [])
|
|
469
|
+
});
|
|
470
|
+
if (dynamicParamsResponse) return dynamicParamsResponse;
|
|
471
|
+
}
|
|
407
472
|
const render = async () => {
|
|
408
473
|
setCurrentFetchSoftTags(buildMetadataRouteTags(route, options.cleanPathname, []));
|
|
409
474
|
return captureRenderedMetadataRoute(route.isDynamic ? await callDynamicMetadataRoute(route, match, options.makeThenableParams, functions) : serveStaticMetadataRoute(route));
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import "../utils/protocol-headers.js";
|
|
3
|
+
import { shouldKeepMiddlewareHeader } from "../utils/middleware-request-headers.js";
|
|
4
|
+
import { normalizeHost } from "../config/request-context.js";
|
|
2
5
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
3
6
|
import { addBasePathToPathname, hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
4
7
|
import { getRequestExecutionContext, runWithExecutionContext } from "../shims/request-context.js";
|
|
5
8
|
import "./server-globals.js";
|
|
6
|
-
import { normalizeHost } from "../config/request-context.js";
|
|
7
|
-
import "../utils/protocol-headers.js";
|
|
8
9
|
import { MIDDLEWARE_REWRITE_HEADER } from "./headers.js";
|
|
9
|
-
import { shouldKeepMiddlewareHeader } from "../utils/middleware-request-headers.js";
|
|
10
10
|
import { NextFetchEvent, NextRequest } from "../shims/server.js";
|
|
11
11
|
import { normalizePath } from "./normalize-path.js";
|
|
12
12
|
import { matchesMiddleware, matchesMiddlewarePathname } from "./middleware-matcher.js";
|
|
@@ -34,6 +34,30 @@ function getManifestFilesForModule(manifest, moduleId) {
|
|
|
34
34
|
for (const key in manifest) if (moduleId.endsWith("/" + key) || moduleId === key) return manifest[key];
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
37
|
+
function collectGraphOrderedCss(graph, moduleIds) {
|
|
38
|
+
const ordered = [];
|
|
39
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
40
|
+
const visited = /* @__PURE__ */ new Set();
|
|
41
|
+
function findKey(moduleId) {
|
|
42
|
+
if (!moduleId) return void 0;
|
|
43
|
+
if (graph[moduleId]) return moduleId;
|
|
44
|
+
for (const key in graph) if (moduleId === key || moduleId.endsWith("/" + key)) return key;
|
|
45
|
+
}
|
|
46
|
+
function visit(key) {
|
|
47
|
+
if (!key || visited.has(key)) return;
|
|
48
|
+
visited.add(key);
|
|
49
|
+
const chunk = graph[key];
|
|
50
|
+
if (!chunk) return;
|
|
51
|
+
for (const importedKey of chunk.imports ?? []) visit(importedKey);
|
|
52
|
+
for (const file of chunk.css ?? []) {
|
|
53
|
+
if (emitted.has(file)) continue;
|
|
54
|
+
emitted.add(file);
|
|
55
|
+
ordered.push(file);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const moduleId of moduleIds) visit(findKey(moduleId));
|
|
59
|
+
return ordered;
|
|
60
|
+
}
|
|
37
61
|
/**
|
|
38
62
|
* Find the first `.js` file in the manifest for `moduleId` and return the URL it
|
|
39
63
|
* is actually SERVED from. Used to resolve the client-navigation / hydration URL
|
|
@@ -87,6 +111,14 @@ function collectAssetTags(options) {
|
|
|
87
111
|
tags.push("<link rel=\"modulepreload\"" + nonceAttr + " href=\"" + href(clientEntry) + "\"" + preloadCrossOriginAttr + " />");
|
|
88
112
|
tags.push("<script type=\"module\"" + deferAttr + nonceAttr + " src=\"" + href(clientEntry) + "\"" + scriptCrossOriginAttr + "><\/script>");
|
|
89
113
|
}
|
|
114
|
+
if (runtimeAssets.cssGraph) for (let file of collectGraphOrderedCss(runtimeAssets.cssGraph, options.moduleIds)) {
|
|
115
|
+
if (file.charAt(0) === "/") file = file.slice(1);
|
|
116
|
+
if (seen.has(file)) continue;
|
|
117
|
+
seen.add(file);
|
|
118
|
+
const stylesheetHref = href(file);
|
|
119
|
+
options.initialStylesheetHrefs?.add(stylesheetHref);
|
|
120
|
+
tags.push("<link rel=\"stylesheet\"" + nonceAttr + " href=\"" + stylesheetHref + "\" />");
|
|
121
|
+
}
|
|
90
122
|
if (m) {
|
|
91
123
|
const allFiles = [];
|
|
92
124
|
const moduleIds = options.moduleIds;
|
|
@@ -114,8 +146,11 @@ function collectAssetTags(options) {
|
|
|
114
146
|
if (tf.charAt(0) === "/") tf = tf.slice(1);
|
|
115
147
|
if (seen.has(tf)) continue;
|
|
116
148
|
seen.add(tf);
|
|
117
|
-
if (tf.endsWith(".css"))
|
|
118
|
-
|
|
149
|
+
if (tf.endsWith(".css")) {
|
|
150
|
+
const stylesheetHref = href(tf);
|
|
151
|
+
options.initialStylesheetHrefs?.add(stylesheetHref);
|
|
152
|
+
tags.push("<link rel=\"stylesheet\"" + nonceAttr + " href=\"" + stylesheetHref + "\" />");
|
|
153
|
+
} else if (tf.endsWith(".js")) {
|
|
119
154
|
if (lazySet && lazySet.has(tf)) continue;
|
|
120
155
|
tags.push("<link rel=\"modulepreload\"" + nonceAttr + " href=\"" + href(tf) + "\"" + preloadCrossOriginAttr + " />");
|
|
121
156
|
tags.push("<script type=\"module\"" + deferAttr + nonceAttr + " src=\"" + href(tf) + "\"" + scriptCrossOriginAttr + "><\/script>");
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
//#region src/server/pages-client-assets.d.ts
|
|
2
|
+
export type AssetCrossOrigin = "" | "anonymous" | "use-credentials";
|
|
2
3
|
export type PagesClientAssets = {
|
|
3
4
|
clientEntry?: string;
|
|
4
5
|
appBootstrapPreinitModules?: string[];
|
|
5
6
|
ssrManifest?: Record<string, string[]>;
|
|
7
|
+
cssGraph?: Record<string, {
|
|
8
|
+
imports?: string[];
|
|
9
|
+
css?: string[];
|
|
10
|
+
}>;
|
|
6
11
|
lazyChunks?: string[];
|
|
7
12
|
dynamicPreloads?: Record<string, string[]>;
|
|
13
|
+
/** next.config crossOrigin, defaulting to anonymous for Vite's CORS-fetched assets. */
|
|
14
|
+
crossOrigin?: AssetCrossOrigin;
|
|
8
15
|
};
|
|
9
16
|
export declare function setPagesClientAssets(assets: PagesClientAssets | undefined): void;
|
|
10
17
|
export declare function getPagesClientAssets(): PagesClientAssets;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
1
|
import { MIDDLEWARE_SKIP_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
+
import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
3
3
|
import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
4
4
|
//#region src/server/pages-data-route.ts
|
|
5
5
|
/**
|
|
@@ -4,6 +4,12 @@ export type PagesDevHydrationOptions = {
|
|
|
4
4
|
forceRouterReady?: boolean;
|
|
5
5
|
normalizePageProps?: boolean;
|
|
6
6
|
pageModuleSource: string;
|
|
7
|
+
/** Lazily importable page routes, matching the production client manifest. */
|
|
8
|
+
pageLoaders?: readonly {
|
|
9
|
+
pattern: string;
|
|
10
|
+
moduleSource: string;
|
|
11
|
+
dataKind?: "static" | "server" | "none";
|
|
12
|
+
}[];
|
|
7
13
|
reactStrictMode: boolean;
|
|
8
14
|
replaceFallbackRoute?: boolean;
|
|
9
15
|
scriptNonce?: string;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { resolveClientRuntimeModule } from "../entries/runtime-entry-module.js";
|
|
2
|
-
import { createNonceAttribute } from "./html.js";
|
|
2
|
+
import { createNonceAttribute, safeJsonStringify } from "./html.js";
|
|
3
3
|
//#region src/server/pages-dev-hydration.ts
|
|
4
4
|
function createPagesDevHydrationScript(options) {
|
|
5
5
|
const nonceAttr = createNonceAttribute(options.scriptNonce);
|
|
6
6
|
const reactInstanceBootstrapPath = resolveClientRuntimeModule("react-instance-bootstrap");
|
|
7
7
|
const initializeRouter = options.forceRouterReady ? "_initializePagesRouterReadyFromNextData(nextData, true);" : "_initializePagesRouterReadyFromNextData(nextData);";
|
|
8
|
-
const pagePatterns = options.setPagePatternsFromNextData ? "window.__VINEXT_PAGE_PATTERNS__ = [nextData.page];" : "";
|
|
8
|
+
const pagePatterns = options.setPagePatternsFromNextData ? options.pageLoaders ? "window.__VINEXT_PAGE_PATTERNS__ = Object.keys(window.__VINEXT_PAGE_LOADERS__);" : "window.__VINEXT_PAGE_PATTERNS__ = [nextData.page];" : "";
|
|
9
|
+
const pageLoaders = `{ ${[...options.pageLoaders?.map(({ pattern, moduleSource }) => {
|
|
10
|
+
const importer = moduleSource === "next/error" ? "import(\"next/error\")" : `loadDevPage(import.meta.env.BASE_URL + ${safeJsonStringify(moduleSource.slice(1))})`;
|
|
11
|
+
return `${safeJsonStringify(pattern)}: () => ${importer}`;
|
|
12
|
+
}) ?? [], `[nextData.page]: () => import(${safeJsonStringify(options.pageModuleSource)})`].join(", ")} }`;
|
|
13
|
+
const ssgPatterns = options.pageLoaders?.filter((route) => route.dataKind === "static").map((route) => route.pattern);
|
|
14
|
+
const sspPatterns = options.pageLoaders?.filter((route) => route.dataKind === "server").map((route) => route.pattern);
|
|
9
15
|
const pageProps = options.normalizePageProps === false ? "const pageProps = rawPageProps ?? {};" : "const pageProps = rawPageProps && typeof rawPageProps === \"object\" ? rawPageProps : {};";
|
|
10
16
|
const hydrationQueryUpdate = options.replaceFallbackRoute ? `
|
|
11
17
|
const initialMatchesMiddleware =
|
|
@@ -19,7 +25,7 @@ function createPagesDevHydrationScript(options) {
|
|
|
19
25
|
await Router.replace(routeUrl || currentUrl, routeUrl ? currentUrl : undefined, { _h: 1, scroll: false, shallow: !nextData.isFallback && !initialMatchesMiddleware });
|
|
20
26
|
}` : "";
|
|
21
27
|
const createElement = options.appModuleSource ? `
|
|
22
|
-
const appModule = await import(${
|
|
28
|
+
const appModule = await import(${safeJsonStringify(options.appModuleSource)});
|
|
23
29
|
const AppComponent = appModule.default;
|
|
24
30
|
window.__VINEXT_APP__ = AppComponent;
|
|
25
31
|
const appRouter = ${options.forceRouterReady ? "{ ...Router, isReady: true }" : "Router"};
|
|
@@ -33,7 +39,7 @@ function createPagesDevHydrationScript(options) {
|
|
|
33
39
|
`;
|
|
34
40
|
return `
|
|
35
41
|
<script type="module"${nonceAttr}>
|
|
36
|
-
import ${
|
|
42
|
+
import ${safeJsonStringify(reactInstanceBootstrapPath)};
|
|
37
43
|
import "vinext/instrumentation-client";
|
|
38
44
|
import React from "react";
|
|
39
45
|
import { hydrateRoot } from "react-dom/client";
|
|
@@ -47,13 +53,19 @@ if (nextDataElement?.textContent) {
|
|
|
47
53
|
window.__VINEXT_DEFAULT_LOCALE__ = window.__NEXT_DATA__.defaultLocale;
|
|
48
54
|
}
|
|
49
55
|
const nextData = window.__NEXT_DATA__;
|
|
56
|
+
window.__VINEXT_MIDDLEWARE_MATCHER__ = nextData.__vinext?.clientMiddlewareMatcher;
|
|
50
57
|
${initializeRouter}
|
|
51
58
|
const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
|
|
52
59
|
const rawPageProps = props.pageProps;
|
|
53
60
|
${pageProps}
|
|
54
|
-
|
|
61
|
+
// Other pages must not become static dependencies of this page's HMR proxy.
|
|
62
|
+
// Vite adds ?import to variable imports, so source URLs are bare and base-qualified here.
|
|
63
|
+
const loadDevPage = (source) => import(/* @vite-ignore */ source);
|
|
64
|
+
window.__VINEXT_PAGE_LOADERS__ = ${pageLoaders};
|
|
55
65
|
${pagePatterns}
|
|
56
|
-
|
|
66
|
+
${ssgPatterns ? `window.__VINEXT_PAGES_SSG_PATTERNS__ = ${safeJsonStringify(ssgPatterns)};` : ""}
|
|
67
|
+
${sspPatterns ? `window.__VINEXT_PAGES_SSP_PATTERNS__ = ${safeJsonStringify(sspPatterns)};` : ""}
|
|
68
|
+
window.__VINEXT_APP_LOADER__ = ${options.appModuleSource ? `() => import(${safeJsonStringify(options.appModuleSource)})` : "undefined"};
|
|
57
69
|
window.__VINEXT_REACT_STRICT_MODE__ = ${JSON.stringify(options.reactStrictMode)};
|
|
58
70
|
|
|
59
71
|
async function hydrate() {
|
|
@@ -69,7 +81,7 @@ async function hydrate() {
|
|
|
69
81
|
};
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
const pageModule = await import(${
|
|
84
|
+
const pageModule = await import(${safeJsonStringify(options.pageModuleSource)});
|
|
73
85
|
const PageComponent = pageModule.default;
|
|
74
86
|
let element;
|
|
75
87
|
${createElement}
|
|
@@ -23,6 +23,7 @@ type DocumentRenderPageInput = {
|
|
|
23
23
|
renderStylesToString: (element: React.ReactElement) => Promise<string>;
|
|
24
24
|
/** Per-request CSP nonce applied to the enhanced page tree, if any. */
|
|
25
25
|
scriptNonce?: string | undefined;
|
|
26
|
+
initialStylesheetHrefs?: ReadonlySet<string> | undefined;
|
|
26
27
|
/** Extra `DocumentContext` fields (pathname/query/asPath). */
|
|
27
28
|
context?: Record<string, unknown> | undefined;
|
|
28
29
|
};
|
|
@@ -75,7 +75,7 @@ async function runDocumentRenderPage(input) {
|
|
|
75
75
|
const enhancePageElement = input.enhancePageElement;
|
|
76
76
|
const renderPage = async (opts = {}) => {
|
|
77
77
|
const enhancedElement = enhancePageElement(typeof opts === "function" ? { enhanceComponent: opts } : opts);
|
|
78
|
-
const wrapped = withScriptNonce(enhancedElement, input.scriptNonce);
|
|
78
|
+
const wrapped = withScriptNonce(enhancedElement, input.scriptNonce, input.initialStylesheetHrefs);
|
|
79
79
|
const stream = await input.renderToReadableStream(wrapped);
|
|
80
80
|
return {
|
|
81
81
|
html: await readStreamAsText(stream),
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
2
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
1
3
|
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
2
4
|
import { NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
3
5
|
import { isDangerousScheme } from "../shims/url-safety.js";
|
|
4
6
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
5
7
|
import { buildMissIsrCacheControl, decideIsr } from "./isr-decision.js";
|
|
6
|
-
import { isUnknownRecord } from "../utils/record.js";
|
|
7
8
|
import { buildPagesCacheValue, isrCacheControl } from "./isr-cache.js";
|
|
8
9
|
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
9
10
|
import { normalizeStaticPathname } from "../routing/route-pattern.js";
|
|
10
11
|
import { buildCacheStateHeaders } from "./cache-headers.js";
|
|
11
|
-
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
12
12
|
import { matchesIfNoneMatch } from "./http-conditional.js";
|
|
13
13
|
import { buildPagesNextDataScript, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
|
|
14
14
|
import { createPagesGetInitialPropsRouter, hasPagesGetInitialProps, isResponseSent, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
|
|
2
2
|
import { closeAfterResponse, closeAfterResponseWithBody, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
3
|
+
import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
|
|
3
4
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
4
5
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
5
|
-
import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
|
|
6
6
|
import { NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_CACHE_HEADER, VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
|
|
7
7
|
import { extractLocaleFromUrl, resolvePagesI18nRequest } from "./pages-i18n.js";
|
|
8
8
|
import { reportRequestError } from "./instrumentation.js";
|
|
@@ -492,6 +492,7 @@ function createPagesPageHandler(opts) {
|
|
|
492
492
|
const pageModuleIds = [];
|
|
493
493
|
if (appAssetPath) pageModuleIds.push(appAssetPath);
|
|
494
494
|
if (route.filePath) pageModuleIds.push(route.filePath);
|
|
495
|
+
const initialStylesheetHrefs = /* @__PURE__ */ new Set();
|
|
495
496
|
let pageResponse = await renderTracedPagesPageResponse({
|
|
496
497
|
assetTags: collectAssetTags({
|
|
497
498
|
manifest,
|
|
@@ -501,7 +502,8 @@ function createPagesPageHandler(opts) {
|
|
|
501
502
|
basePath: vinextConfig.basePath,
|
|
502
503
|
assetPrefix: vinextConfig.assetPrefix,
|
|
503
504
|
deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
|
|
504
|
-
crossOrigin: vinextConfig.crossOrigin
|
|
505
|
+
crossOrigin: vinextConfig.crossOrigin,
|
|
506
|
+
initialStylesheetHrefs
|
|
505
507
|
}),
|
|
506
508
|
buildId,
|
|
507
509
|
clearSsrContext() {
|
|
@@ -549,6 +551,7 @@ function createPagesPageHandler(opts) {
|
|
|
549
551
|
routeUrl: renderRouteUrl,
|
|
550
552
|
safeJsonStringify,
|
|
551
553
|
scriptNonce,
|
|
554
|
+
initialStylesheetHrefs,
|
|
552
555
|
crossOrigin: vinextConfig.crossOrigin,
|
|
553
556
|
disableOptimizedLoading: vinextConfig.disableOptimizedLoading,
|
|
554
557
|
statusCode: renderStatusCode,
|
|
@@ -112,6 +112,7 @@ type RenderPagesPageResponseOptions = {
|
|
|
112
112
|
routeUrl: string;
|
|
113
113
|
safeJsonStringify: (value: unknown) => string;
|
|
114
114
|
scriptNonce?: string;
|
|
115
|
+
initialStylesheetHrefs?: ReadonlySet<string>;
|
|
115
116
|
crossOrigin?: string;
|
|
116
117
|
disableOptimizedLoading: boolean;
|
|
117
118
|
statusCode?: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
1
2
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
2
3
|
import { NEXTJS_CACHE_HEADER, VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
|
|
3
4
|
import { reportRequestError } from "./instrumentation.js";
|
|
@@ -15,7 +16,6 @@ import { setCacheStateHeaders } from "./cache-headers.js";
|
|
|
15
16
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
16
17
|
import { loadUserDocumentInitialProps, runDocumentRenderPage } from "./pages-document-initial-props.js";
|
|
17
18
|
import { callDocumentGetInitialProps } from "./document-initial-head.js";
|
|
18
|
-
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
19
19
|
import { matchesIfNoneMatch } from "./http-conditional.js";
|
|
20
20
|
import React from "react";
|
|
21
21
|
//#region src/server/pages-page-response.ts
|
|
@@ -189,6 +189,7 @@ async function renderPagesPageResponse(options) {
|
|
|
189
189
|
renderToReadableStream: options.renderToReadableStream,
|
|
190
190
|
renderStylesToString: async (element) => readStreamAsText(await options.renderToReadableStream(element)),
|
|
191
191
|
scriptNonce: options.scriptNonce,
|
|
192
|
+
initialStylesheetHrefs: options.initialStylesheetHrefs,
|
|
192
193
|
context: {
|
|
193
194
|
err: options.err,
|
|
194
195
|
req: options.documentReqRes?.req,
|
|
@@ -208,7 +209,7 @@ async function renderPagesPageResponse(options) {
|
|
|
208
209
|
controller.close();
|
|
209
210
|
} });
|
|
210
211
|
else {
|
|
211
|
-
const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(renderProps)), options.scriptNonce);
|
|
212
|
+
const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(renderProps)), options.scriptNonce, options.initialStylesheetHrefs);
|
|
212
213
|
bodyStream = await options.renderToReadableStream(pageElement);
|
|
213
214
|
}
|
|
214
215
|
if (documentRenderPage.status === "skipped") await callDocumentGetInitialProps(options.DocumentComponent, options.setDocumentInitialHead);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
|
|
2
|
-
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
3
|
-
import { requestContextFromRequest } from "../config/request-context.js";
|
|
4
1
|
import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
+
import { requestContextFromRequest } from "../config/request-context.js";
|
|
5
3
|
import { isExternalUrl } from "../utils/external-url.js";
|
|
6
4
|
import { applyMiddlewareRequestHeaders, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
5
|
+
import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
|
|
6
|
+
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
7
7
|
import { methodNotAllowedResponse, sanitizeMethodNotAllowedHeaders } from "./http-error-responses.js";
|
|
8
8
|
import { cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
9
9
|
import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
+
import { requestContextFromRequest } from "../config/request-context.js";
|
|
3
|
+
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
1
4
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
2
5
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
3
6
|
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
4
|
-
import { requestContextFromRequest } from "../config/request-context.js";
|
|
5
|
-
import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
|
|
6
7
|
import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./headers.js";
|
|
7
8
|
import { notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
8
9
|
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
@@ -11,7 +12,6 @@ import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
|
|
|
11
12
|
import { CACHEABILITY_REQUEST_STATE } from "../shims/cacheability-classification.js";
|
|
12
13
|
import { applyCdnResponseIdentityHeaders, captureCdnResponsePolicyOverrides, reconcileCdnResponseHeadersAfterOuterPolicy, validateCdnRequest } from "./cache-control.js";
|
|
13
14
|
import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
|
|
14
|
-
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
15
15
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
|
|
16
16
|
import { traceFrameworkRequest } from "./request-tracing.js";
|
|
17
17
|
import { resolveResponseStageCachePolicy } from "./config-headers.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
2
1
|
import { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
3
|
import { VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
|
|
4
4
|
import { normalizeDomainHostname } from "../utils/domain-locale.js";
|
|
5
5
|
import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
1
2
|
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
|
|
2
3
|
import "./headers.js";
|
|
3
|
-
import { isUnknownRecord } from "../utils/record.js";
|
|
4
4
|
//#region src/server/prerender-route-params.ts
|
|
5
5
|
function isPrerenderRouteParams(value) {
|
|
6
6
|
if (!isUnknownRecord(value)) return false;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import { isUnknownRecord } from "../utils/record.js";
|
|
3
|
+
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
|
|
4
|
+
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
|
|
5
|
+
import { StaticFileCache, contentTypeForPath, etagFromFilenameHash } from "./static-file-cache.js";
|
|
2
6
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
3
7
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
4
|
-
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
|
|
5
8
|
import { VINEXT_PRERENDER_RENDER_ERROR_HEADER } from "./headers.js";
|
|
6
9
|
import { normalizePath } from "./normalize-path.js";
|
|
7
10
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
8
11
|
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
9
12
|
import { readStaticFileSignal } from "./static-file-signal.js";
|
|
10
13
|
import { canonicalizeRequestPathname, filterInternalHeaders } from "./request-pipeline.js";
|
|
11
|
-
import { isUnknownRecord } from "../utils/record.js";
|
|
12
14
|
import { parseHttpDate } from "./http-date.js";
|
|
13
15
|
import { evaluateStaticPreconditions } from "./http-conditional.js";
|
|
14
16
|
import { buildNextDataNotFoundResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./pages-data-route.js";
|
|
15
|
-
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
|
|
16
17
|
import { setPagesClientAssets } from "./pages-client-assets.js";
|
|
17
18
|
import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
18
19
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, isSafeImageContentType, parseImageParams } from "./image-optimization.js";
|
|
19
20
|
import { installSocketErrorBackstop } from "./socket-error-backstop.js";
|
|
20
|
-
import { StaticFileCache, contentTypeForPath, etagFromFilenameHash } from "./static-file-cache.js";
|
|
21
21
|
import { collectInlineCssManifest } from "../build/inline-css.js";
|
|
22
22
|
import { readTrustedRevalidationHostname } from "./revalidation-host.js";
|
|
23
23
|
import { traceFrameworkRequest } from "./request-tracing.js";
|
|
@@ -32,8 +32,8 @@ import { ifRangeAllowsRange, parseByteRange } from "./http-range.js";
|
|
|
32
32
|
import { createRequire } from "node:module";
|
|
33
33
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
34
34
|
import fs from "node:fs";
|
|
35
|
-
import fsp from "node:fs/promises";
|
|
36
35
|
import { pathToFileURL } from "node:url";
|
|
36
|
+
import fsp from "node:fs/promises";
|
|
37
37
|
import { Readable, pipeline } from "node:stream";
|
|
38
38
|
import zlib from "node:zlib";
|
|
39
39
|
import { createServer } from "node:http";
|
|
@@ -41,7 +41,7 @@ import { createServer } from "node:http";
|
|
|
41
41
|
/**
|
|
42
42
|
* Production server for vinext.
|
|
43
43
|
*
|
|
44
|
-
* Serves the built output from `
|
|
44
|
+
* Serves the built output from `vite build`. Handles:
|
|
45
45
|
* - Static asset serving from client build output
|
|
46
46
|
* - Pages Router: SSR rendering + API route handling
|
|
47
47
|
* - App Router: RSC/SSR rendering, route handlers, server actions
|
|
@@ -315,7 +315,7 @@ const OMIT_METHOD_NOT_ALLOWED_HEADERS = /* @__PURE__ */ new Set([
|
|
|
315
315
|
"content-type",
|
|
316
316
|
"transfer-encoding"
|
|
317
317
|
]);
|
|
318
|
-
function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
|
|
318
|
+
function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix, crossOrigin) {
|
|
319
319
|
const metadata = computeClientRuntimeMetadata({
|
|
320
320
|
clientDir,
|
|
321
321
|
assetBase,
|
|
@@ -324,7 +324,8 @@ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
|
|
|
324
324
|
setPagesClientAssets({
|
|
325
325
|
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
326
326
|
lazyChunks: metadata.lazyChunks,
|
|
327
|
-
dynamicPreloads: metadata.dynamicPreloads
|
|
327
|
+
dynamicPreloads: metadata.dynamicPreloads,
|
|
328
|
+
crossOrigin
|
|
328
329
|
});
|
|
329
330
|
}
|
|
330
331
|
function isNoBodyResponseStatus(status) {
|
|
@@ -841,7 +842,7 @@ async function startProdServer(options = {}) {
|
|
|
841
842
|
const isAppRouter = fs.existsSync(rscEntryPath);
|
|
842
843
|
if (!isAppRouter && !fs.existsSync(serverEntryPath)) {
|
|
843
844
|
console.error(`[vinext] No build output found in ${outDir}`);
|
|
844
|
-
console.error("Run `
|
|
845
|
+
console.error("Run `vite build` first.");
|
|
845
846
|
process.exit(1);
|
|
846
847
|
}
|
|
847
848
|
if (isAppRouter) return startAppRouterServer({
|
|
@@ -980,8 +981,10 @@ function installPagesClientAssets(options) {
|
|
|
980
981
|
clientEntry: metadata.clientEntryFile,
|
|
981
982
|
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
982
983
|
ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
|
|
984
|
+
cssGraph: metadata.cssGraph,
|
|
983
985
|
lazyChunks: metadata.lazyChunks,
|
|
984
|
-
dynamicPreloads: metadata.dynamicPreloads
|
|
986
|
+
dynamicPreloads: metadata.dynamicPreloads,
|
|
987
|
+
crossOrigin: options.crossOrigin
|
|
985
988
|
});
|
|
986
989
|
return ssrManifest;
|
|
987
990
|
}
|
|
@@ -1011,6 +1014,7 @@ async function startAppRouterServer(options) {
|
|
|
1011
1014
|
const workerEntry = rscModule.default && typeof rscModule.default === "object" ? rscModule.default : void 0;
|
|
1012
1015
|
const ensureInstrumentation = typeof workerEntry?.__ensureInstrumentation === "function" ? () => workerEntry.__ensureInstrumentation() : typeof rscModule.__ensureInstrumentation === "function" ? () => rscModule.__ensureInstrumentation() : () => void 0;
|
|
1013
1016
|
const appRouterAssetPrefix = typeof rscModule.__assetPrefix === "string" ? rscModule.__assetPrefix : "";
|
|
1017
|
+
const appRouterCrossOrigin = rscModule.__crossOrigin === "anonymous" || rscModule.__crossOrigin === "use-credentials" ? rscModule.__crossOrigin : "";
|
|
1014
1018
|
const appRouterBasePath = typeof rscModule.__basePath === "string" ? rscModule.__basePath : "";
|
|
1015
1019
|
const appRouterInlineCss = rscModule.__inlineCss === true;
|
|
1016
1020
|
const appRouterHasPagesDir = rscModule.__hasPagesDir === true;
|
|
@@ -1031,9 +1035,10 @@ async function startAppRouterServer(options) {
|
|
|
1031
1035
|
clientDir,
|
|
1032
1036
|
assetPrefix: appRouterAssetPrefix,
|
|
1033
1037
|
assetBase: appAssetBase,
|
|
1034
|
-
clientEntryLookup: "pages-client-entry"
|
|
1038
|
+
clientEntryLookup: "pages-client-entry",
|
|
1039
|
+
crossOrigin: appRouterCrossOrigin
|
|
1035
1040
|
});
|
|
1036
|
-
else installClientBuildManifestGlobals(clientDir, appAssetBase, appRouterAssetPrefix);
|
|
1041
|
+
else installClientBuildManifestGlobals(clientDir, appAssetBase, appRouterAssetPrefix, appRouterCrossOrigin);
|
|
1037
1042
|
const seedPrerenderedRoutes = resolveAppRouterPrerenderSeeder(rscModule);
|
|
1038
1043
|
const seededRoutes = await runWithServerEntryRequire(rscEntryRequire, () => seedPrerenderedRoutes(serverDir));
|
|
1039
1044
|
if (seededRoutes > 0) console.log(`[vinext] Seeded ${seededRoutes} pre-rendered route${seededRoutes !== 1 ? "s" : ""} into memory cache`);
|
|
@@ -1230,7 +1235,8 @@ async function startPagesRouterServer(options) {
|
|
|
1230
1235
|
clientDir,
|
|
1231
1236
|
assetPrefix,
|
|
1232
1237
|
assetBase,
|
|
1233
|
-
clientEntryLookup: "any-client-entry"
|
|
1238
|
+
clientEntryLookup: "any-client-entry",
|
|
1239
|
+
crossOrigin: vinextConfig?.crossOrigin ?? ""
|
|
1234
1240
|
});
|
|
1235
1241
|
const staticCache = await StaticFileCache.create(clientDir);
|
|
1236
1242
|
const handleRequest = async (req, res) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
2
1
|
import "../utils/protocol-headers.js";
|
|
3
|
-
import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS } from "./headers.js";
|
|
4
2
|
import { getUnconsumedMiddlewareRequestHeaders } from "../utils/middleware-request-headers.js";
|
|
3
|
+
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
4
|
+
import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS } from "./headers.js";
|
|
5
5
|
import { forbiddenResponse, methodNotAllowedResponse, notFoundResponse } from "./http-error-responses.js";
|
|
6
6
|
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
7
7
|
import { createStaticFileSignal } from "./static-file-signal.js";
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
//#region src/server/rsc-stream-hints.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Rewrite stylesheet preload hints in a React Flight stream.
|
|
4
|
+
*
|
|
5
|
+
* The rewrite is byte-length preserving, so this transform keeps React's
|
|
6
|
+
* text chunk boundaries instead of re-emitting one chunk per Flight row. Every
|
|
7
|
+
* downstream consumer (the tee, the SSR Flight client, the inline RSC embed,
|
|
8
|
+
* RSC response wrappers) pays a per-chunk cost, and splitting per row
|
|
9
|
+
* multiplied the chunk count roughly 8x on content-heavy pages. Chunks with
|
|
10
|
+
* no stylesheet hint are forwarded as-is without copying; only rows whose
|
|
11
|
+
* tag is `HL` are decoded and inspected. Length-prefixed bodies remain separate
|
|
12
|
+
* so binary bytes do not force adjacent text through the embed's base64 path.
|
|
13
|
+
*/
|
|
2
14
|
export declare function normalizeReactFlightPreloadHints(stream: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;
|
|
3
15
|
export type RscRawRenderer = (model: unknown, options?: unknown) => ReadableStream<Uint8Array>;
|
|
4
16
|
export type RscRawPrerenderer = (model: unknown, options?: unknown) => Promise<{
|