vinext 0.1.8 → 0.2.1
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 +51 -30
- package/dist/build/css-url-assets.d.ts +3 -1
- package/dist/build/css-url-assets.js +18 -1
- package/dist/build/inject-pregenerated-paths.d.ts +7 -0
- package/dist/build/inject-pregenerated-paths.js +21 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender-server-entry.d.ts +1 -0
- package/dist/build/prerender-server-entry.js +49 -0
- package/dist/build/prerender-server-pool.d.ts +44 -0
- package/dist/build/prerender-server-pool.js +194 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +98 -27
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +12 -2
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +4 -6
- package/dist/check.js +48 -11
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +112 -96
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/vinext-next-data.d.ts +4 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +45 -19
- package/dist/config/next-config.d.ts +41 -9
- package/dist/config/next-config.js +60 -3
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/entries/app-browser-entry.js +5 -1
- package/dist/entries/app-rsc-entry.d.ts +5 -3
- package/dist/entries/app-rsc-entry.js +44 -10
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +28 -3
- package/dist/entries/pages-server-entry.js +23 -6
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +482 -120
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +209 -99
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +272 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/og-assets.js +2 -1
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
- package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
- package/dist/plugins/sass.d.ts +17 -1
- package/dist/plugins/sass.js +74 -1
- package/dist/plugins/styled-jsx.d.ts +16 -0
- package/dist/plugins/styled-jsx.js +149 -0
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +23 -2
- package/dist/routing/app-route-graph.js +138 -38
- package/dist/routing/file-matcher.d.ts +11 -1
- package/dist/routing/file-matcher.js +18 -3
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +198 -57
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +1 -1
- package/dist/server/app-browser-server-action-client.js +8 -7
- package/dist/server/app-browser-state.d.ts +12 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +42 -24
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +10 -6
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +5 -4
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +27 -7
- package/dist/server/app-page-dispatch.d.ts +1 -0
- package/dist/server/app-page-dispatch.js +26 -8
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +59 -4
- package/dist/server/app-page-execution.js +2 -1
- package/dist/server/app-page-probe.js +5 -0
- package/dist/server/app-page-render-identity.d.ts +2 -0
- package/dist/server/app-page-render-identity.js +3 -2
- package/dist/server/app-page-render.d.ts +2 -0
- package/dist/server/app-page-render.js +85 -16
- package/dist/server/app-page-request.d.ts +14 -0
- package/dist/server/app-page-request.js +69 -4
- package/dist/server/app-page-response.d.ts +7 -0
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-route-wiring.d.ts +8 -1
- package/dist/server/app-page-route-wiring.js +32 -18
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +7 -1
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-route-handler-execution.js +5 -1
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-tree-prefetch.d.ts +43 -0
- package/dist/server/app-route-tree-prefetch.js +187 -0
- package/dist/server/app-router-entry.js +9 -2
- package/dist/server/app-rsc-cache-busting.d.ts +2 -1
- package/dist/server/app-rsc-cache-busting.js +9 -4
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +148 -39
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.d.ts +6 -6
- package/dist/server/app-rsc-request-normalization.js +10 -8
- package/dist/server/app-segment-config.d.ts +11 -0
- package/dist/server/app-segment-config.js +62 -6
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +61 -30
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +13 -5
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/cache-control.d.ts +3 -1
- package/dist/server/cache-control.js +13 -1
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-route-files.js +4 -0
- package/dist/server/dev-server.d.ts +11 -1
- package/dist/server/dev-server.js +94 -35
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +7 -15
- package/dist/server/headers.js +11 -18
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +3 -2
- package/dist/server/isr-cache.js +9 -5
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-data-route.d.ts +4 -2
- package/dist/server/pages-data-route.js +18 -4
- package/dist/server/pages-dev-module-url.d.ts +2 -1
- package/dist/server/pages-dev-module-url.js +6 -3
- package/dist/server/pages-node-compat.d.ts +19 -1
- package/dist/server/pages-node-compat.js +81 -4
- package/dist/server/pages-page-data.d.ts +33 -1
- package/dist/server/pages-page-data.js +62 -33
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +38 -19
- package/dist/server/pages-page-response.d.ts +8 -0
- package/dist/server/pages-page-response.js +7 -3
- package/dist/server/pages-request-pipeline.d.ts +9 -5
- package/dist/server/pages-request-pipeline.js +55 -7
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +5 -3
- package/dist/server/prod-server.js +68 -39
- package/dist/server/request-pipeline.js +2 -1
- package/dist/server/seed-cache.js +4 -4
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache-handler.js +8 -1
- package/dist/shims/cache.js +22 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +77 -52
- package/dist/shims/form.d.ts +4 -2
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +7 -1
- package/dist/shims/headers.js +17 -3
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
- package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
- package/dist/shims/internal/pages-data-target.d.ts +18 -12
- package/dist/shims/internal/pages-data-target.js +97 -13
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.d.ts +1 -1
- package/dist/shims/link.js +224 -58
- package/dist/shims/navigation.d.ts +19 -3
- package/dist/shims/navigation.js +245 -47
- package/dist/shims/request-context.js +18 -0
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +387 -102
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -1
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +3 -3
- package/dist/utils/project.d.ts +48 -2
- package/dist/utils/project.js +225 -4
- package/dist/utils/protocol-headers.d.ts +23 -0
- package/dist/utils/protocol-headers.js +23 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/dist/utils/vite-version.d.ts +2 -0
- package/dist/utils/vite-version.js +11 -1
- package/package.json +47 -2
- package/dist/deploy.d.ts +0 -197
- package/dist/deploy.js +0 -1040
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
2
3
|
import { applyMiddlewareRequestHeaders, isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
3
4
|
import { applyConfigHeadersToHeaderRecord, cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
4
5
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
5
6
|
import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
|
|
7
|
+
import { buildMiddlewarePrefetchSkipResponse } from "./pages-data-route.js";
|
|
6
8
|
import { mergeHeaders } from "./worker-utils.js";
|
|
7
9
|
//#region src/server/pages-request-pipeline.ts
|
|
8
10
|
async function fetchWorkerFilesystemRoute(request, requestPathname, phase, fetchAsset) {
|
|
@@ -141,6 +143,22 @@ async function runPagesRequest(request, deps) {
|
|
|
141
143
|
});
|
|
142
144
|
let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
143
145
|
const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
|
|
146
|
+
const matchedPathnameForRoute = (routePattern) => {
|
|
147
|
+
const matchedPathname = routePattern ? patternToNextFormat(routePattern) : resolvedPathname;
|
|
148
|
+
if (!i18nConfig) return matchedPathname;
|
|
149
|
+
const resolvedLocale = resolvedPathname.split("/", 3)[1];
|
|
150
|
+
if (resolvedLocale && i18nConfig.locales.includes(resolvedLocale)) return matchedPathname === "/" ? `/${resolvedLocale}` : `/${resolvedLocale}${matchedPathname}`;
|
|
151
|
+
return matchResolvedPathname(matchedPathname);
|
|
152
|
+
};
|
|
153
|
+
const buildMiddlewarePrefetchSkipResult = (match) => {
|
|
154
|
+
if (!match) return null;
|
|
155
|
+
if (match.route.dataKind !== "server" || !isDataRequest || !deps.hasMiddleware || request.headers.get("x-middleware-prefetch") !== "1") return null;
|
|
156
|
+
return {
|
|
157
|
+
type: "response",
|
|
158
|
+
response: mergeHeaders(buildMiddlewarePrefetchSkipResponse(matchedPathnameForRoute(match.route.pattern)), middlewareHeaders, void 0),
|
|
159
|
+
defaultContentType: "application/json"
|
|
160
|
+
};
|
|
161
|
+
};
|
|
144
162
|
if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
|
|
145
163
|
configHeaders,
|
|
146
164
|
pathname: matchPathname,
|
|
@@ -170,14 +188,16 @@ async function runPagesRequest(request, deps) {
|
|
|
170
188
|
const beforeFilesResult = await serveFilesystemRoute(resolvedPathname, "beforeFiles");
|
|
171
189
|
if (beforeFilesResult) return beforeFilesResult;
|
|
172
190
|
}
|
|
173
|
-
|
|
191
|
+
const isOutsideBasePathUnclaimed = () => basePath && !hadBasePath && !configRewriteFired;
|
|
192
|
+
const outOfBasePathNotFound = () => ({
|
|
174
193
|
type: "response",
|
|
175
194
|
response: new Response("This page could not be found", {
|
|
176
195
|
status: 404,
|
|
177
196
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
178
197
|
})
|
|
179
|
-
};
|
|
198
|
+
});
|
|
180
199
|
const handleResolvedApiRoute = async () => {
|
|
200
|
+
if (isOutsideBasePathUnclaimed()) return null;
|
|
181
201
|
const apiLookupUrl = stripI18nLocaleForApiRoute(resolvedUrl, i18nConfig);
|
|
182
202
|
const apiLookupPathname = apiLookupUrl.split("?")[0];
|
|
183
203
|
if (!apiLookupPathname.startsWith("/api/") && apiLookupPathname !== "/api") return null;
|
|
@@ -204,7 +224,7 @@ async function runPagesRequest(request, deps) {
|
|
|
204
224
|
};
|
|
205
225
|
const apiResult = await handleResolvedApiRoute();
|
|
206
226
|
if (apiResult) return apiResult;
|
|
207
|
-
let pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
227
|
+
let pageMatch = !isOutsideBasePathUnclaimed() && deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
208
228
|
let resolvedPathnameChanged = false;
|
|
209
229
|
if (!pageMatch || pageMatch.route.isDynamic) for (const rewrite of configRewrites.afterFiles ?? []) {
|
|
210
230
|
const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
@@ -215,6 +235,7 @@ async function runPagesRequest(request, deps) {
|
|
|
215
235
|
};
|
|
216
236
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
|
|
217
237
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
238
|
+
configRewriteFired = true;
|
|
218
239
|
resolvedPathnameChanged = true;
|
|
219
240
|
const afterFilesFilesystemResult = await serveFilesystemRoute(resolvedPathname, "afterFiles");
|
|
220
241
|
if (afterFilesFilesystemResult) return afterFilesFilesystemResult;
|
|
@@ -231,7 +252,7 @@ async function runPagesRequest(request, deps) {
|
|
|
231
252
|
refreshDataRewriteHeader();
|
|
232
253
|
if (typeof deps.renderPage === "function") {
|
|
233
254
|
let renderPageMatch = pageMatch;
|
|
234
|
-
if ((isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
255
|
+
if ((isOutsideBasePathUnclaimed() || isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
235
256
|
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
236
257
|
if (!fallbackRewrite) continue;
|
|
237
258
|
if (isExternalUrl(fallbackRewrite)) return {
|
|
@@ -240,6 +261,7 @@ async function runPagesRequest(request, deps) {
|
|
|
240
261
|
};
|
|
241
262
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
242
263
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
264
|
+
configRewriteFired = true;
|
|
243
265
|
const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
|
|
244
266
|
if (fallbackFilesystemResult) return fallbackFilesystemResult;
|
|
245
267
|
const fallbackApiResult = await handleResolvedApiRoute();
|
|
@@ -248,6 +270,9 @@ async function runPagesRequest(request, deps) {
|
|
|
248
270
|
refreshDataRewriteHeader();
|
|
249
271
|
if (renderPageMatch) break;
|
|
250
272
|
}
|
|
273
|
+
const prefetchSkipResult = buildMiddlewarePrefetchSkipResult(renderPageMatch);
|
|
274
|
+
if (prefetchSkipResult) return prefetchSkipResult;
|
|
275
|
+
if (isOutsideBasePathUnclaimed()) return outOfBasePathNotFound();
|
|
251
276
|
const shouldDeferErrorPageOnMiss = !isDataReq && !isDataRequest && !!deps.matchPageRoute && !renderPageMatch;
|
|
252
277
|
const initialRenderOptions = shouldDeferErrorPageOnMiss ? { renderErrorPageOnMiss: false } : isDataReq ? { isDataReq: true } : void 0;
|
|
253
278
|
const stagedHeaders = new Headers();
|
|
@@ -264,16 +289,33 @@ async function runPagesRequest(request, deps) {
|
|
|
264
289
|
};
|
|
265
290
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
266
291
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
292
|
+
configRewriteFired = true;
|
|
267
293
|
const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
|
|
268
294
|
if (fallbackFilesystemResult) return fallbackFilesystemResult;
|
|
269
295
|
const fallbackApiResult = await handleResolvedApiRoute();
|
|
270
296
|
if (fallbackApiResult) return fallbackApiResult;
|
|
297
|
+
renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
271
298
|
response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
272
299
|
matchedFallbackRewrite = true;
|
|
273
300
|
if (response.status !== 404) break;
|
|
274
301
|
}
|
|
275
302
|
if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
276
|
-
const
|
|
303
|
+
const matchedPathHeaders = { ...middlewareHeaders };
|
|
304
|
+
if ((isDataReq || isDataRequest) && deps.hasMiddleware && !renderPageMatch && response.status === 404 && (middlewareStatus === void 0 || middlewareStatus === 200 || middlewareStatus === 404)) {
|
|
305
|
+
const headers = new Headers(response.headers);
|
|
306
|
+
headers.set("content-type", "application/json");
|
|
307
|
+
headers.set("x-nextjs-matched-path", matchResolvedPathname(pathname));
|
|
308
|
+
return {
|
|
309
|
+
type: "response",
|
|
310
|
+
response: mergeHeaders(new Response("{}", {
|
|
311
|
+
status: 200,
|
|
312
|
+
headers
|
|
313
|
+
}), matchedPathHeaders, void 0),
|
|
314
|
+
defaultContentType: "application/json"
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
if ((isDataReq || isDataRequest) && renderPageMatch && (middlewareStatus ?? response.status) === 200) matchedPathHeaders["x-nextjs-matched-path"] = matchedPathnameForRoute(renderPageMatch?.route.pattern);
|
|
318
|
+
const merged = mergeHeaders(response, matchedPathHeaders, middlewareStatus);
|
|
277
319
|
if (merged !== response) merged.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
|
|
278
320
|
return {
|
|
279
321
|
type: "response",
|
|
@@ -281,7 +323,8 @@ async function runPagesRequest(request, deps) {
|
|
|
281
323
|
defaultContentType: "text/html"
|
|
282
324
|
};
|
|
283
325
|
}
|
|
284
|
-
|
|
326
|
+
let devPageMatch = isOutsideBasePathUnclaimed() ? null : resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch;
|
|
327
|
+
if (!devPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
285
328
|
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
286
329
|
if (!fallbackRewrite) continue;
|
|
287
330
|
if (isExternalUrl(fallbackRewrite)) return {
|
|
@@ -290,12 +333,17 @@ async function runPagesRequest(request, deps) {
|
|
|
290
333
|
};
|
|
291
334
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
292
335
|
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
336
|
+
configRewriteFired = true;
|
|
293
337
|
const fallbackFilesystemResult = await serveFilesystemRoute(resolvedPathname, "fallback");
|
|
294
338
|
if (fallbackFilesystemResult) return fallbackFilesystemResult;
|
|
295
339
|
const fallbackApiResult = await handleResolvedApiRoute();
|
|
296
340
|
if (fallbackApiResult) return fallbackApiResult;
|
|
297
|
-
|
|
341
|
+
devPageMatch = deps.matchPageRoute?.(resolvedPathname, request) ?? null;
|
|
342
|
+
if (devPageMatch) break;
|
|
298
343
|
}
|
|
344
|
+
const prefetchSkipResult = buildMiddlewarePrefetchSkipResult(devPageMatch);
|
|
345
|
+
if (prefetchSkipResult) return prefetchSkipResult;
|
|
346
|
+
if (isOutsideBasePathUnclaimed()) return outOfBasePathNotFound();
|
|
299
347
|
refreshDataRewriteHeader();
|
|
300
348
|
return {
|
|
301
349
|
type: "render",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/server/pages-router-entry.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Router-specific Cloudflare Worker entry point for vinext Pages Router.
|
|
4
|
+
*
|
|
5
|
+
* New projects should usually use the router-selected entry in wrangler.jsonc:
|
|
6
|
+
* "main": "vinext/server/fetch-handler"
|
|
7
|
+
*
|
|
8
|
+
* This Pages Router entry remains available for existing configs and for custom
|
|
9
|
+
* workers that need to opt into the Pages Router handler explicitly:
|
|
10
|
+
* "main": "vinext/server/pages-router-entry"
|
|
11
|
+
*
|
|
12
|
+
* Or import and delegate to it from a custom worker:
|
|
13
|
+
* import handler from "vinext/server/pages-router-entry";
|
|
14
|
+
* return handler.fetch(request, env, ctx);
|
|
15
|
+
*/
|
|
16
|
+
type AssetFetcher = {
|
|
17
|
+
fetch(request: Request): Promise<Response> | Response;
|
|
18
|
+
};
|
|
19
|
+
type PagesWorkerEnv = {
|
|
20
|
+
ASSETS?: AssetFetcher;
|
|
21
|
+
} & Record<string, unknown>;
|
|
22
|
+
type PagesWorkerExecutionContext = {
|
|
23
|
+
waitUntil?(promise: Promise<unknown>): void;
|
|
24
|
+
passThroughOnException?(): void;
|
|
25
|
+
};
|
|
26
|
+
declare const _default: {
|
|
27
|
+
fetch(request: Request, env?: PagesWorkerEnv, ctx?: PagesWorkerExecutionContext): Promise<Response>;
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { _default as default };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
3
|
+
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
4
|
+
import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders } from "./request-pipeline.js";
|
|
5
|
+
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
6
|
+
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
|
|
7
|
+
import { finalizeMissingStaticAssetResponse } from "./worker-utils.js";
|
|
8
|
+
import { fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
|
|
9
|
+
import { registerConfiguredCacheAdapters } from "virtual:vinext-cache-adapters";
|
|
10
|
+
import { registerConfiguredImageOptimizer } from "virtual:vinext-image-adapters";
|
|
11
|
+
import * as pagesEntry from "virtual:vinext-server-entry";
|
|
12
|
+
//#region src/server/pages-router-entry.ts
|
|
13
|
+
/**
|
|
14
|
+
* Router-specific Cloudflare Worker entry point for vinext Pages Router.
|
|
15
|
+
*
|
|
16
|
+
* New projects should usually use the router-selected entry in wrangler.jsonc:
|
|
17
|
+
* "main": "vinext/server/fetch-handler"
|
|
18
|
+
*
|
|
19
|
+
* This Pages Router entry remains available for existing configs and for custom
|
|
20
|
+
* workers that need to opt into the Pages Router handler explicitly:
|
|
21
|
+
* "main": "vinext/server/pages-router-entry"
|
|
22
|
+
*
|
|
23
|
+
* Or import and delegate to it from a custom worker:
|
|
24
|
+
* import handler from "vinext/server/pages-router-entry";
|
|
25
|
+
* return handler.fetch(request, env, ctx);
|
|
26
|
+
*/
|
|
27
|
+
const { handleApiRoute, hasMiddleware, matchPageRoute, normalizeDataRequest, renderPage, runMiddleware, vinextConfig } = pagesEntry;
|
|
28
|
+
const basePath = vinextConfig?.basePath ?? "";
|
|
29
|
+
const assetPathPrefix = assetPrefixPathname(vinextConfig?.assetPrefix ?? "");
|
|
30
|
+
const trailingSlash = vinextConfig?.trailingSlash ?? false;
|
|
31
|
+
const i18nConfig = vinextConfig?.i18n ?? null;
|
|
32
|
+
const configRedirects = vinextConfig?.redirects ?? [];
|
|
33
|
+
const configRewrites = vinextConfig?.rewrites ?? {
|
|
34
|
+
beforeFiles: [],
|
|
35
|
+
afterFiles: [],
|
|
36
|
+
fallback: []
|
|
37
|
+
};
|
|
38
|
+
const configHeaders = vinextConfig?.headers ?? [];
|
|
39
|
+
const imageConfig = vinextConfig?.images ? {
|
|
40
|
+
qualities: vinextConfig.images.qualities,
|
|
41
|
+
dangerouslyAllowSVG: vinextConfig.images.dangerouslyAllowSVG,
|
|
42
|
+
dangerouslyAllowLocalIP: vinextConfig.images.dangerouslyAllowLocalIP,
|
|
43
|
+
contentDispositionType: vinextConfig.images.contentDispositionType,
|
|
44
|
+
contentSecurityPolicy: vinextConfig.images.contentSecurityPolicy
|
|
45
|
+
} : void 0;
|
|
46
|
+
var pages_router_entry_default = { async fetch(request, env, ctx) {
|
|
47
|
+
return handleRequest(request, env, ctx);
|
|
48
|
+
} };
|
|
49
|
+
async function handleRequest(request, env, ctx) {
|
|
50
|
+
registerConfiguredCacheAdapters(env);
|
|
51
|
+
registerConfiguredImageOptimizer(env);
|
|
52
|
+
try {
|
|
53
|
+
let pathname = new URL(request.url).pathname;
|
|
54
|
+
if (isOpenRedirectShaped(pathname)) return new Response("This page could not be found", { status: 404 });
|
|
55
|
+
const missingBuildAsset = isNextStaticPath(pathname, basePath, assetPathPrefix);
|
|
56
|
+
request = cloneRequestWithHeaders(request, filterInternalHeaders(request.headers));
|
|
57
|
+
const hadBasePath = !basePath || hasBasePath(pathname, basePath);
|
|
58
|
+
{
|
|
59
|
+
const stripped = stripBasePath(pathname, basePath);
|
|
60
|
+
if (stripped !== pathname) {
|
|
61
|
+
const strippedUrl = new URL(request.url);
|
|
62
|
+
strippedUrl.pathname = stripped;
|
|
63
|
+
request = cloneRequestWithUrl(request, strippedUrl.toString());
|
|
64
|
+
pathname = stripped;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const dataNorm = normalizeDataRequest(request);
|
|
68
|
+
if (dataNorm.notFoundResponse) return dataNorm.notFoundResponse;
|
|
69
|
+
const isDataReq = dataNorm.isDataReq;
|
|
70
|
+
if (isDataReq) {
|
|
71
|
+
request = dataNorm.request;
|
|
72
|
+
pathname = dataNorm.normalizedPathname;
|
|
73
|
+
}
|
|
74
|
+
if (isImageOptimizationPath(pathname) && env?.ASSETS) {
|
|
75
|
+
const allowedWidths = [...vinextConfig?.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...vinextConfig?.images?.imageSizes ?? DEFAULT_IMAGE_SIZES];
|
|
76
|
+
return handleConfiguredImageOptimization(request, (assetPath) => Promise.resolve(env.ASSETS.fetch(new Request(new URL(assetPath, request.url)))), allowedWidths, imageConfig);
|
|
77
|
+
}
|
|
78
|
+
const deps = {
|
|
79
|
+
basePath,
|
|
80
|
+
trailingSlash,
|
|
81
|
+
i18nConfig,
|
|
82
|
+
configRedirects,
|
|
83
|
+
configRewrites,
|
|
84
|
+
configHeaders,
|
|
85
|
+
hadBasePath,
|
|
86
|
+
isDataReq,
|
|
87
|
+
isDataRequest: isDataReq,
|
|
88
|
+
hasMiddleware,
|
|
89
|
+
ctx,
|
|
90
|
+
matchPageRoute: typeof matchPageRoute === "function" ? matchPageRoute : null,
|
|
91
|
+
runMiddleware: typeof runMiddleware === "function" ? wrapMiddlewareWithBasePath(runMiddleware, basePath, hadBasePath) : null,
|
|
92
|
+
renderPage: typeof renderPage === "function" ? (req, resolvedUrl, options, stagedHeaders) => renderPage(req, resolvedUrl, null, ctx, stagedHeaders, options) : null,
|
|
93
|
+
handleApi: typeof handleApiRoute === "function" ? (req, apiUrl) => handleApiRoute(req, apiUrl, ctx) : null,
|
|
94
|
+
serveFilesystemRoute: async (requestPathname, _stagedHeaders, phase) => {
|
|
95
|
+
if (!env?.ASSETS) return false;
|
|
96
|
+
return fetchWorkerFilesystemRoute(request, requestPathname, phase, (assetRequest) => Promise.resolve(env.ASSETS.fetch(assetRequest)));
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const result = await runPagesRequest(request, deps);
|
|
100
|
+
if (result.type === "response") return finalizeMissingStaticAssetResponse(result.response, missingBuildAsset);
|
|
101
|
+
return missingBuildAsset ? notFoundStaticAssetResponse() : new Response("This page could not be found", { status: 404 });
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error("[vinext] Worker error:", error);
|
|
104
|
+
return new Response("Internal Server Error", { status: 500 });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export { pages_router_entry_default as default };
|
|
@@ -7,11 +7,13 @@ type PrerenderManifestRoute = {
|
|
|
7
7
|
path?: string;
|
|
8
8
|
router?: string;
|
|
9
9
|
fallback?: boolean;
|
|
10
|
+
headers?: Record<string, string>;
|
|
10
11
|
};
|
|
11
12
|
type PrerenderManifest = {
|
|
12
13
|
buildId?: string;
|
|
13
14
|
trailingSlash?: boolean;
|
|
14
15
|
routes?: PrerenderManifestRoute[];
|
|
16
|
+
pregeneratedConcretePaths?: Array<[string, string[]]>;
|
|
15
17
|
};
|
|
16
18
|
declare function readPrerenderManifest(manifestPath: string): PrerenderManifest | null;
|
|
17
19
|
declare function getRenderedAppRoutes(routes: PrerenderManifestRoute[]): PrerenderManifestRoute[];
|
|
@@ -30,4 +32,4 @@ declare function isFallbackShellArtifactPath(pathname: string, route?: Prerender
|
|
|
30
32
|
*/
|
|
31
33
|
declare function buildPregeneratedConcretePathTable(manifest: PrerenderManifest): Array<[string, string[]]>;
|
|
32
34
|
//#endregion
|
|
33
|
-
export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
|
|
35
|
+
export { PrerenderManifest, buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "
|
|
1
|
+
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
|
|
2
2
|
import { isUnknownRecord } from "../utils/record.js";
|
|
3
3
|
//#region src/server/prerender-route-params.ts
|
|
4
4
|
function isPrerenderRouteParams(value) {
|
|
@@ -41,6 +41,7 @@ import { IncomingMessage, ServerResponse } from "node:http";
|
|
|
41
41
|
* Exported for direct unit testing of the URL choice.
|
|
42
42
|
*/
|
|
43
43
|
declare function resolveServerEntryImportUrl(entryPath: string): string;
|
|
44
|
+
declare function rememberCurrentServerEntryImportMtime(entryPath: string): void;
|
|
44
45
|
declare function importServerEntryModule(entryPath: string): Promise<any>;
|
|
45
46
|
/** Convert a Node.js IncomingMessage into a ReadableStream for Web Request body. */
|
|
46
47
|
declare function readNodeStream(req: IncomingMessage): ReadableStream<Uint8Array>;
|
|
@@ -54,7 +55,8 @@ type ProdServerOptions = {
|
|
|
54
55
|
* Omitted for normal `vinext start` so the existing production-server output
|
|
55
56
|
* remains stable.
|
|
56
57
|
*/
|
|
57
|
-
purpose?: "prerender";
|
|
58
|
+
purpose?: "prerender"; /** Suppress the startup log for internal child-process servers. */
|
|
59
|
+
silent?: boolean;
|
|
58
60
|
};
|
|
59
61
|
/** Content types that benefit from compression. */
|
|
60
62
|
declare const COMPRESSIBLE_TYPES: Set<string>;
|
|
@@ -74,7 +76,7 @@ declare function mergeResponseHeaders(middlewareHeaders: Record<string, string |
|
|
|
74
76
|
* arguments in (headers, response) order. The request path now calls
|
|
75
77
|
* `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
|
|
76
78
|
* only for its existing tests and any external callers, so there is a single
|
|
77
|
-
* implementation to keep in sync.
|
|
79
|
+
* implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
|
|
78
80
|
*/
|
|
79
81
|
declare function mergeWebResponse(middlewareHeaders: Record<string, string | string[]>, response: Response, statusOverride?: number): Response;
|
|
80
82
|
/**
|
|
@@ -145,4 +147,4 @@ declare function resolveAppRouterPrerenderSeeder(entryModule: unknown): AppRoute
|
|
|
145
147
|
*/
|
|
146
148
|
declare function resolveAppRouterAssetPath(pathname: string, assetPathPrefix: string, assetPrefix: string): string | null;
|
|
147
149
|
//#endregion
|
|
148
|
-
export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
|
|
150
|
+
export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, rememberCurrentServerEntryImportMtime, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
2
2
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
3
|
-
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER,
|
|
3
|
+
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
|
|
4
|
+
import { VINEXT_STATIC_FILE_HEADER } from "./headers.js";
|
|
4
5
|
import { normalizePath } from "./normalize-path.js";
|
|
5
6
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
6
7
|
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
7
8
|
import { filterInternalHeaders } from "./request-pipeline.js";
|
|
8
9
|
import { isUnknownRecord } from "../utils/record.js";
|
|
10
|
+
import { buildNextDataNotFoundResponse, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname } from "./pages-data-route.js";
|
|
11
|
+
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
|
|
12
|
+
import { setPagesClientAssets } from "./pages-client-assets.js";
|
|
9
13
|
import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
10
14
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, isSafeImageContentType, parseImageParams } from "./image-optimization.js";
|
|
11
15
|
import { installSocketErrorBackstop } from "./socket-error-backstop.js";
|
|
12
|
-
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
|
|
13
16
|
import { CONTENT_TYPES, StaticFileCache, etagFromFilenameHash } from "./static-file-cache.js";
|
|
14
|
-
import { buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname } from "./pages-data-route.js";
|
|
15
17
|
import { collectInlineCssManifest } from "../build/inline-css.js";
|
|
16
18
|
import { mergeHeaders } from "./worker-utils.js";
|
|
17
19
|
import { runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
|
|
18
|
-
import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
19
20
|
import { computeClientRuntimeMetadata } from "../utils/client-runtime-metadata.js";
|
|
21
|
+
import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
20
22
|
import { readPrerenderSecret } from "../build/server-manifest.js";
|
|
21
23
|
import { seedMemoryCacheFromPrerender } from "./seed-cache.js";
|
|
22
24
|
import { negotiateEncoding, parseAcceptedEncodings, selectContentEncoding } from "./accept-encoding.js";
|
|
@@ -24,9 +26,9 @@ import fs from "node:fs";
|
|
|
24
26
|
import path from "node:path";
|
|
25
27
|
import fs$1 from "node:fs/promises";
|
|
26
28
|
import { pathToFileURL } from "node:url";
|
|
29
|
+
import { Readable, pipeline } from "node:stream";
|
|
27
30
|
import zlib from "node:zlib";
|
|
28
31
|
import { createServer } from "node:http";
|
|
29
|
-
import { Readable, pipeline } from "node:stream";
|
|
30
32
|
//#region src/server/prod-server.ts
|
|
31
33
|
/**
|
|
32
34
|
* Production server for vinext.
|
|
@@ -54,6 +56,18 @@ import { Readable, pipeline } from "node:stream";
|
|
|
54
56
|
* through a cache-busted URL instead.
|
|
55
57
|
*/
|
|
56
58
|
const bareServerEntryMtimes = /* @__PURE__ */ new Map();
|
|
59
|
+
function resolveCanonicalServerEntry(entryPath) {
|
|
60
|
+
let canonicalEntryPath;
|
|
61
|
+
try {
|
|
62
|
+
canonicalEntryPath = fs.realpathSync.native(entryPath);
|
|
63
|
+
} catch {
|
|
64
|
+
canonicalEntryPath = entryPath;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
href: pathToFileURL(canonicalEntryPath).href,
|
|
68
|
+
mtime: fs.statSync(canonicalEntryPath).mtimeMs
|
|
69
|
+
};
|
|
70
|
+
}
|
|
57
71
|
/**
|
|
58
72
|
* Import a built server entry module (App Router RSC entry or Pages Router
|
|
59
73
|
* server entry) by absolute file path.
|
|
@@ -91,14 +105,7 @@ const bareServerEntryMtimes = /* @__PURE__ */ new Map();
|
|
|
91
105
|
* Exported for direct unit testing of the URL choice.
|
|
92
106
|
*/
|
|
93
107
|
function resolveServerEntryImportUrl(entryPath) {
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
canonicalEntryPath = fs.realpathSync.native(entryPath);
|
|
97
|
-
} catch {
|
|
98
|
-
canonicalEntryPath = entryPath;
|
|
99
|
-
}
|
|
100
|
-
const href = pathToFileURL(canonicalEntryPath).href;
|
|
101
|
-
const mtime = fs.statSync(canonicalEntryPath).mtimeMs;
|
|
108
|
+
const { href, mtime } = resolveCanonicalServerEntry(entryPath);
|
|
102
109
|
const bareMtime = bareServerEntryMtimes.get(href);
|
|
103
110
|
if (bareMtime === void 0 || bareMtime === mtime) {
|
|
104
111
|
bareServerEntryMtimes.set(href, mtime);
|
|
@@ -106,6 +113,10 @@ function resolveServerEntryImportUrl(entryPath) {
|
|
|
106
113
|
}
|
|
107
114
|
return `${href}?t=${mtime}`;
|
|
108
115
|
}
|
|
116
|
+
function rememberCurrentServerEntryImportMtime(entryPath) {
|
|
117
|
+
const { href, mtime } = resolveCanonicalServerEntry(entryPath);
|
|
118
|
+
bareServerEntryMtimes.set(href, mtime);
|
|
119
|
+
}
|
|
109
120
|
async function importServerEntryModule(entryPath) {
|
|
110
121
|
return import(resolveServerEntryImportUrl(entryPath));
|
|
111
122
|
}
|
|
@@ -275,8 +286,11 @@ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
|
|
|
275
286
|
assetBase,
|
|
276
287
|
assetPrefix
|
|
277
288
|
});
|
|
278
|
-
|
|
279
|
-
|
|
289
|
+
setPagesClientAssets({
|
|
290
|
+
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
291
|
+
lazyChunks: metadata.lazyChunks,
|
|
292
|
+
dynamicPreloads: metadata.dynamicPreloads
|
|
293
|
+
});
|
|
280
294
|
}
|
|
281
295
|
function isNoBodyResponseStatus(status) {
|
|
282
296
|
return NO_BODY_RESPONSE_STATUSES.has(status);
|
|
@@ -305,7 +319,7 @@ function logProdServerStarted(host, port, purpose) {
|
|
|
305
319
|
* arguments in (headers, response) order. The request path now calls
|
|
306
320
|
* `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
|
|
307
321
|
* only for its existing tests and any external callers, so there is a single
|
|
308
|
-
* implementation to keep in sync.
|
|
322
|
+
* implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
|
|
309
323
|
*/
|
|
310
324
|
function mergeWebResponse(middlewareHeaders, response, statusOverride) {
|
|
311
325
|
return mergeHeaders(response, middlewareHeaders, statusOverride);
|
|
@@ -552,9 +566,11 @@ function nodeToWebRequest(req, urlOverride, prerenderSecret) {
|
|
|
552
566
|
const url = new URL(urlOverride ?? req.url ?? "/", origin);
|
|
553
567
|
const rawHeaders = nodeHeadersToWebHeaders(req.headers);
|
|
554
568
|
const prerenderRouteParamsPayload = readTrustedPrerenderRouteParamsFromHeaders(rawHeaders, prerenderSecret);
|
|
569
|
+
const isTrustedSpeculativePrerender = process.env.VINEXT_PRERENDER === "1" && prerenderSecret !== void 0 && rawHeaders.get("x-vinext-prerender-secret") === prerenderSecret && rawHeaders.get("x-vinext-prerender-speculative") === "1";
|
|
555
570
|
const headers = filterInternalHeaders(rawHeaders);
|
|
556
571
|
const prerenderRouteParamsHeader = serializePrerenderRouteParamsHeader(prerenderRouteParamsPayload);
|
|
557
572
|
if (prerenderRouteParamsHeader !== null) headers.set(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, prerenderRouteParamsHeader);
|
|
573
|
+
if (isTrustedSpeculativePrerender) headers.set(VINEXT_PRERENDER_SPECULATIVE_HEADER, "1");
|
|
558
574
|
const method = req.method ?? "GET";
|
|
559
575
|
const hasBody = method !== "GET" && method !== "HEAD";
|
|
560
576
|
const init = {
|
|
@@ -617,7 +633,7 @@ async function sendWebResponse(webResponse, req, res, compress) {
|
|
|
617
633
|
*/
|
|
618
634
|
async function startProdServer(options = {}) {
|
|
619
635
|
installSocketErrorBackstop();
|
|
620
|
-
const { port = process.env.PORT ? parseInt(process.env.PORT) : 3e3, host = "0.0.0.0", outDir = path.resolve("dist"), noCompression = false, purpose } = options;
|
|
636
|
+
const { port = process.env.PORT ? parseInt(process.env.PORT) : 3e3, host = "0.0.0.0", outDir = path.resolve("dist"), noCompression = false, purpose, silent = false } = options;
|
|
621
637
|
const compress = !noCompression;
|
|
622
638
|
const resolvedOutDir = path.resolve(outDir);
|
|
623
639
|
const clientDir = path.join(resolvedOutDir, "client");
|
|
@@ -635,7 +651,8 @@ async function startProdServer(options = {}) {
|
|
|
635
651
|
clientDir,
|
|
636
652
|
rscEntryPath,
|
|
637
653
|
compress,
|
|
638
|
-
purpose
|
|
654
|
+
purpose,
|
|
655
|
+
silent
|
|
639
656
|
});
|
|
640
657
|
return startPagesRouterServer({
|
|
641
658
|
port,
|
|
@@ -643,7 +660,8 @@ async function startProdServer(options = {}) {
|
|
|
643
660
|
clientDir,
|
|
644
661
|
serverEntryPath,
|
|
645
662
|
compress,
|
|
646
|
-
purpose
|
|
663
|
+
purpose,
|
|
664
|
+
silent
|
|
647
665
|
});
|
|
648
666
|
}
|
|
649
667
|
function createNodeExecutionContext() {
|
|
@@ -736,18 +754,21 @@ function readSsrManifest(clientDir) {
|
|
|
736
754
|
}
|
|
737
755
|
return parsed;
|
|
738
756
|
}
|
|
739
|
-
function
|
|
757
|
+
function installPagesClientAssets(options) {
|
|
740
758
|
const ssrManifest = readSsrManifest(options.clientDir);
|
|
741
|
-
globalThis.__VINEXT_SSR_MANIFEST__ = Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0;
|
|
742
759
|
const metadata = computeClientRuntimeMetadata({
|
|
743
760
|
clientDir: options.clientDir,
|
|
744
761
|
assetBase: options.assetBase,
|
|
745
762
|
assetPrefix: options.assetPrefix,
|
|
746
763
|
includeClientEntry: options.clientEntryLookup === "pages-client-entry" ? "pages-client-entry" : true
|
|
747
764
|
});
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
765
|
+
setPagesClientAssets({
|
|
766
|
+
clientEntry: metadata.clientEntryFile,
|
|
767
|
+
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
768
|
+
ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
|
|
769
|
+
lazyChunks: metadata.lazyChunks,
|
|
770
|
+
dynamicPreloads: metadata.dynamicPreloads
|
|
771
|
+
});
|
|
751
772
|
return ssrManifest;
|
|
752
773
|
}
|
|
753
774
|
/**
|
|
@@ -768,12 +789,7 @@ function installPagesClientAssetGlobals(options) {
|
|
|
768
789
|
* 4. Stream the Web Response back (with optional compression)
|
|
769
790
|
*/
|
|
770
791
|
async function startAppRouterServer(options) {
|
|
771
|
-
const { port, host, clientDir, rscEntryPath, compress, purpose } = options;
|
|
772
|
-
let imageConfig;
|
|
773
|
-
const imageConfigPath = path.join(path.dirname(rscEntryPath), "image-config.json");
|
|
774
|
-
if (fs.existsSync(imageConfigPath)) try {
|
|
775
|
-
imageConfig = JSON.parse(fs.readFileSync(imageConfigPath, "utf-8"));
|
|
776
|
-
} catch {}
|
|
792
|
+
const { port, host, clientDir, rscEntryPath, compress, purpose, silent } = options;
|
|
777
793
|
const prerenderSecret = readPrerenderSecret(path.dirname(rscEntryPath));
|
|
778
794
|
const rscModule = await importServerEntryModule(rscEntryPath);
|
|
779
795
|
const rscHandler = resolveAppRouterHandler(rscModule.default);
|
|
@@ -781,10 +797,18 @@ async function startAppRouterServer(options) {
|
|
|
781
797
|
const appRouterBasePath = typeof rscModule.__basePath === "string" ? rscModule.__basePath : "";
|
|
782
798
|
const appRouterInlineCss = rscModule.__inlineCss === true;
|
|
783
799
|
const appRouterHasPagesDir = rscModule.__hasPagesDir === true;
|
|
800
|
+
const appImageAllowedWidths = Array.isArray(rscModule.__imageAllowedWidths) ? rscModule.__imageAllowedWidths : [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES];
|
|
801
|
+
let imageConfig = typeof rscModule.__imageConfig === "object" && rscModule.__imageConfig !== null ? rscModule.__imageConfig : void 0;
|
|
802
|
+
if (imageConfig === void 0) {
|
|
803
|
+
const imageConfigPath = path.join(path.dirname(rscEntryPath), "image-config.json");
|
|
804
|
+
if (fs.existsSync(imageConfigPath)) try {
|
|
805
|
+
imageConfig = JSON.parse(fs.readFileSync(imageConfigPath, "utf-8"));
|
|
806
|
+
} catch {}
|
|
807
|
+
}
|
|
784
808
|
globalThis.__VINEXT_INLINE_CSS__ = appRouterInlineCss ? collectInlineCssManifest(clientDir, appRouterAssetPrefix) : void 0;
|
|
785
809
|
const appAssetPathPrefix = assetPrefixPathname(appRouterAssetPrefix);
|
|
786
810
|
const appAssetBase = appRouterBasePath ? `${appRouterBasePath}/` : "/";
|
|
787
|
-
if (appRouterHasPagesDir)
|
|
811
|
+
if (appRouterHasPagesDir) installPagesClientAssets({
|
|
788
812
|
clientDir,
|
|
789
813
|
assetPrefix: appRouterAssetPrefix,
|
|
790
814
|
assetBase: appAssetBase,
|
|
@@ -828,7 +852,7 @@ async function startAppRouterServer(options) {
|
|
|
828
852
|
}
|
|
829
853
|
}
|
|
830
854
|
if (isImageOptimizationPath(pathname)) {
|
|
831
|
-
const params = parseImageParams(new URL(rawUrl, "http://localhost"),
|
|
855
|
+
const params = parseImageParams(new URL(rawUrl, "http://localhost"), appImageAllowedWidths, imageConfig?.qualities);
|
|
832
856
|
if (!params) {
|
|
833
857
|
res.writeHead(400);
|
|
834
858
|
res.end("Bad Request");
|
|
@@ -888,7 +912,8 @@ async function startAppRouterServer(options) {
|
|
|
888
912
|
await new Promise((resolve) => {
|
|
889
913
|
server.listen(port, host, () => {
|
|
890
914
|
const addr = server.address();
|
|
891
|
-
|
|
915
|
+
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
916
|
+
if (!silent) logProdServerStarted(host, actualPort, purpose);
|
|
892
917
|
resolve();
|
|
893
918
|
});
|
|
894
919
|
});
|
|
@@ -919,10 +944,11 @@ function readPagesServerEntryPageRoutes(value) {
|
|
|
919
944
|
* - vinextConfig — embedded next.config.js settings
|
|
920
945
|
*/
|
|
921
946
|
async function startPagesRouterServer(options) {
|
|
922
|
-
const { port, host, clientDir, serverEntryPath, compress, purpose } = options;
|
|
947
|
+
const { port, host, clientDir, serverEntryPath, compress, purpose, silent } = options;
|
|
923
948
|
const serverEntry = await importServerEntryModule(serverEntryPath);
|
|
924
949
|
const { renderPage, handleApiRoute: handleApi, runMiddleware, vinextConfig, buildId: pagesBuildId } = serverEntry;
|
|
925
950
|
const matchPageRoute = typeof serverEntry.matchPageRoute === "function" ? serverEntry.matchPageRoute : void 0;
|
|
951
|
+
const hasMiddleware = serverEntry.hasMiddleware === true;
|
|
926
952
|
const pageRoutes = readPagesServerEntryPageRoutes(serverEntry.pageRoutes);
|
|
927
953
|
const prerenderSecret = readPrerenderSecret(path.dirname(serverEntryPath));
|
|
928
954
|
const basePath = vinextConfig?.basePath ?? "";
|
|
@@ -946,7 +972,7 @@ async function startPagesRouterServer(options) {
|
|
|
946
972
|
contentDispositionType: vinextConfig.images.contentDispositionType,
|
|
947
973
|
contentSecurityPolicy: vinextConfig.images.contentSecurityPolicy
|
|
948
974
|
} : void 0;
|
|
949
|
-
const ssrManifest =
|
|
975
|
+
const ssrManifest = installPagesClientAssets({
|
|
950
976
|
clientDir,
|
|
951
977
|
assetPrefix,
|
|
952
978
|
assetBase,
|
|
@@ -1050,8 +1076,9 @@ async function startPagesRouterServer(options) {
|
|
|
1050
1076
|
}
|
|
1051
1077
|
isDataReq = true;
|
|
1052
1078
|
const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
|
|
1053
|
-
|
|
1054
|
-
|
|
1079
|
+
const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, hasMiddleware && trailingSlash);
|
|
1080
|
+
url = pagePathname + qs;
|
|
1081
|
+
pathname = pagePathname;
|
|
1055
1082
|
}
|
|
1056
1083
|
const protocol = resolveRequestProtocol(req);
|
|
1057
1084
|
const hostHeader = resolveRequestHost(req, `${host}:${port}`);
|
|
@@ -1075,6 +1102,7 @@ async function startPagesRouterServer(options) {
|
|
|
1075
1102
|
hadBasePath,
|
|
1076
1103
|
isDataReq,
|
|
1077
1104
|
isDataRequest,
|
|
1105
|
+
hasMiddleware,
|
|
1078
1106
|
ctx: void 0,
|
|
1079
1107
|
rawSearch: rawQs,
|
|
1080
1108
|
matchPageRoute: matchPageRoute ?? null,
|
|
@@ -1131,7 +1159,8 @@ async function startPagesRouterServer(options) {
|
|
|
1131
1159
|
await new Promise((resolve) => {
|
|
1132
1160
|
server.listen(port, host, () => {
|
|
1133
1161
|
const addr = server.address();
|
|
1134
|
-
|
|
1162
|
+
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
1163
|
+
if (!silent) logProdServerStarted(host, actualPort, purpose);
|
|
1135
1164
|
resolve();
|
|
1136
1165
|
});
|
|
1137
1166
|
});
|
|
@@ -1142,4 +1171,4 @@ async function startPagesRouterServer(options) {
|
|
|
1142
1171
|
};
|
|
1143
1172
|
}
|
|
1144
1173
|
//#endregion
|
|
1145
|
-
export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
|
|
1174
|
+
export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, readNodeStream, rememberCurrentServerEntryImportMtime, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import "../utils/protocol-headers.js";
|
|
2
3
|
import { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, VINEXT_STATIC_FILE_HEADER } from "./headers.js";
|
|
3
4
|
import { matchHeaders } from "../config/config-matchers.js";
|
|
4
5
|
import { forbiddenResponse, notFoundResponse } from "./http-error-responses.js";
|
|
@@ -337,7 +338,7 @@ function isOriginAllowed(origin, allowed) {
|
|
|
337
338
|
*/
|
|
338
339
|
function processMiddlewareHeaders(headers) {
|
|
339
340
|
const keysToDelete = [];
|
|
340
|
-
for (const key of headers.keys()) if (key.startsWith("x-middleware-")) keysToDelete.push(key);
|
|
341
|
+
for (const key of headers.keys()) if (key.startsWith("x-middleware-") && key !== "x-middleware-cache") keysToDelete.push(key);
|
|
341
342
|
for (const key of keysToDelete) headers.delete(key);
|
|
342
343
|
}
|
|
343
344
|
const STRIPPED_INTERNAL_HEADERS = new Set([...INTERNAL_HEADERS, ...VINEXT_INTERNAL_HEADERS]);
|