vinext 0.1.7 → 0.2.0
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/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -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.d.ts +2 -1
- package/dist/build/prerender.js +13 -6
- 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 +10 -1
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- 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 +113 -97
- 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/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 +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +89 -15
- package/dist/entries/app-rsc-manifest.js +10 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +16 -1
- package/dist/entries/pages-server-entry.js +6 -2
- 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 +211 -118
- 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 +208 -97
- 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 +1 -1
- 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 +276 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
- 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/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- 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 +29 -4
- package/dist/routing/app-route-graph.js +182 -40
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- 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 +194 -190
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- 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 +32 -0
- package/dist/server/app-browser-server-action-client.js +127 -0
- package/dist/server/app-browser-state.d.ts +11 -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 +43 -25
- 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 +5 -2
- package/dist/server/app-fallback-renderer.js +15 -7
- 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-render.d.ts +3 -0
- package/dist/server/app-page-boundary-render.js +14 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- 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 +5 -2
- package/dist/server/app-page-dispatch.d.ts +33 -4
- package/dist/server/app-page-dispatch.js +63 -90
- package/dist/server/app-page-element-builder.d.ts +9 -2
- package/dist/server/app-page-element-builder.js +114 -23
- package/dist/server/app-page-head.d.ts +16 -1
- package/dist/server/app-page-head.js +44 -22
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-ppr-runtime.d.ts +7 -0
- package/dist/server/app-page-ppr-runtime.js +70 -0
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +26 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +92 -15
- package/dist/server/app-page-route-wiring.d.ts +14 -2
- package/dist/server/app-page-route-wiring.js +61 -25
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- 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 +5 -0
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- 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-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +16 -8
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.d.ts +3 -1
- package/dist/server/app-rsc-handler.js +67 -39
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +6 -3
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +94 -33
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +19 -8
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -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.js +19 -18
- 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 +5 -15
- package/dist/server/headers.js +4 -15
- 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 +1 -1
- package/dist/server/isr-cache.js +2 -2
- 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-node-compat.d.ts +8 -1
- package/dist/server/pages-node-compat.js +32 -4
- package/dist/server/pages-page-data.d.ts +24 -1
- package/dist/server/pages-page-data.js +45 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +19 -12
- package/dist/server/pages-page-response.d.ts +7 -0
- package/dist/server/pages-page-response.js +4 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- 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 +1 -1
- package/dist/server/prod-server.js +48 -26
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- 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.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image.js +75 -14
- 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 +2 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
- package/dist/shims/internal/pages-data-target.d.ts +10 -9
- package/dist/shims/internal/pages-data-target.js +91 -12
- 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.js +70 -37
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.d.ts +5 -1
- package/dist/shims/navigation.js +45 -10
- package/dist/shims/navigation.react-server.js +1 -1
- 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 +374 -94
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/typegen.js +6 -5
- 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 +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +52 -2
- package/dist/utils/project.js +230 -5
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +53 -4
- package/dist/deploy.d.ts +0 -190
- package/dist/deploy.js +0 -1033
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -14,12 +14,18 @@ import { resolvePagesI18nRequest } from "./pages-i18n.js";
|
|
|
14
14
|
import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
|
|
15
15
|
import { buildPagesReadinessNextData } from "./pages-readiness.js";
|
|
16
16
|
import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
|
|
17
|
+
import { renderPagesPageResponse } from "./pages-page-response.js";
|
|
18
|
+
import { hasPagesGetInitialProps } from "./pages-get-initial-props.js";
|
|
17
19
|
import { buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, normalizePagesDataRequest, parseNextDataPathname } from "./pages-data-route.js";
|
|
20
|
+
import { resolvePagesPageData } from "./pages-page-data.js";
|
|
18
21
|
import { createPagesReqRes } from "./pages-node-compat.js";
|
|
19
22
|
import { collectAssetTags, resolveClientModuleUrl } from "./pages-asset-tags.js";
|
|
20
|
-
import { renderPagesPageResponse } from "./pages-page-response.js";
|
|
21
|
-
import { resolvePagesPageData } from "./pages-page-data.js";
|
|
22
23
|
//#region src/server/pages-page-handler.ts
|
|
24
|
+
function shouldEmitPagesClientTraceMetadata(pageModule, appComponent) {
|
|
25
|
+
if (typeof pageModule.getServerSideProps === "function") return true;
|
|
26
|
+
if (typeof pageModule.getStaticProps === "function") return false;
|
|
27
|
+
return hasPagesGetInitialProps(pageModule.default) || hasPagesGetInitialProps(appComponent);
|
|
28
|
+
}
|
|
23
29
|
function buildI18nRenderContext(i18nConfig, locale, currentDefaultLocale, domainLocales) {
|
|
24
30
|
return {
|
|
25
31
|
locale,
|
|
@@ -182,6 +188,12 @@ function createPagesPageHandler(opts) {
|
|
|
182
188
|
if (allFontPreloads.length > 0) fontLinkHeader = allFontPreloads.map((p) => "<" + appendAssetDeploymentIdQuery(p.href) + ">; rel=preload; as=font; type=" + p.type + "; crossorigin").join(", ");
|
|
183
189
|
} catch {}
|
|
184
190
|
const pagesResolvedUrl = (new URL(routeUrl, originalRequestUrl).pathname || "/") + originalRequestUrl.search;
|
|
191
|
+
const createPageReqRes = () => createPagesReqRes({
|
|
192
|
+
body: void 0,
|
|
193
|
+
query,
|
|
194
|
+
request,
|
|
195
|
+
url: originalRequestPathAndSearch
|
|
196
|
+
});
|
|
185
197
|
const pageDataResult = await resolvePagesPageData({
|
|
186
198
|
isDataReq,
|
|
187
199
|
err: err instanceof Error ? err : void 0,
|
|
@@ -189,14 +201,7 @@ function createPagesPageHandler(opts) {
|
|
|
189
201
|
buildId,
|
|
190
202
|
deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
|
|
191
203
|
htmlLimitedBots: vinextConfig.htmlLimitedBots,
|
|
192
|
-
createGsspReqRes
|
|
193
|
-
return createPagesReqRes({
|
|
194
|
-
body: void 0,
|
|
195
|
-
query,
|
|
196
|
-
request,
|
|
197
|
-
url: originalRequestPathAndSearch
|
|
198
|
-
});
|
|
199
|
-
},
|
|
204
|
+
createGsspReqRes: createPageReqRes,
|
|
200
205
|
createAppTree(appTreeProps) {
|
|
201
206
|
const el = createPageElement(PageComponent, AppComponent, appTreeProps);
|
|
202
207
|
return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
|
|
@@ -264,6 +269,7 @@ function createPagesPageHandler(opts) {
|
|
|
264
269
|
};
|
|
265
270
|
}
|
|
266
271
|
const gsspRes = pageDataResult.gsspRes;
|
|
272
|
+
const documentReqRes = serializedPagesNextData.autoExport === true ? null : pageDataResult.documentReqRes ?? createPageReqRes();
|
|
267
273
|
const isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;
|
|
268
274
|
const isFallbackRender = pageDataResult.isFallback === true;
|
|
269
275
|
if (isFallbackRender && typeof setSSRContext === "function") setSSRContext({
|
|
@@ -334,7 +340,8 @@ function createPagesPageHandler(opts) {
|
|
|
334
340
|
getFontLinks,
|
|
335
341
|
getFontStyles,
|
|
336
342
|
getSSRHeadHTML: typeof getSSRHeadHTML === "function" ? getSSRHeadHTML : void 0,
|
|
337
|
-
clientTraceMetadata: vinextConfig.clientTraceMetadata,
|
|
343
|
+
clientTraceMetadata: shouldEmitPagesClientTraceMetadata(pageModule, AppComponent) ? vinextConfig.clientTraceMetadata : void 0,
|
|
344
|
+
documentReqRes,
|
|
338
345
|
gsspRes,
|
|
339
346
|
isrCacheKey: pageIsrCacheKey,
|
|
340
347
|
expireSeconds: vinextConfig.expireTime,
|
|
@@ -400,4 +407,4 @@ function createPagesPageHandler(opts) {
|
|
|
400
407
|
return renderPage;
|
|
401
408
|
}
|
|
402
409
|
//#endregion
|
|
403
|
-
export { createPagesPageHandler };
|
|
410
|
+
export { createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
|
|
@@ -45,9 +45,15 @@ type PagesI18nRenderContext = {
|
|
|
45
45
|
domainLocales?: unknown;
|
|
46
46
|
};
|
|
47
47
|
type PagesGsspResponse = {
|
|
48
|
+
headersSent?: boolean;
|
|
48
49
|
statusCode: number;
|
|
49
50
|
getHeaders(): Record<string, string | number | boolean | string[]>;
|
|
50
51
|
};
|
|
52
|
+
type PagesDocumentReqRes = {
|
|
53
|
+
req: unknown;
|
|
54
|
+
res: PagesGsspResponse;
|
|
55
|
+
responsePromise?: Promise<Response>;
|
|
56
|
+
};
|
|
51
57
|
type RenderPagesPageResponseOptions = {
|
|
52
58
|
assetTags: string;
|
|
53
59
|
buildId: string | null;
|
|
@@ -80,6 +86,7 @@ type RenderPagesPageResponseOptions = {
|
|
|
80
86
|
*/
|
|
81
87
|
clientTraceMetadata?: readonly string[] | undefined;
|
|
82
88
|
setDocumentInitialHead?: ((head: ReactNode[]) => void) | undefined;
|
|
89
|
+
documentReqRes?: PagesDocumentReqRes | null;
|
|
83
90
|
gsspRes: PagesGsspResponse | null;
|
|
84
91
|
isrCacheKey: (router: string, pathname: string) => string;
|
|
85
92
|
expireSeconds?: number;
|
|
@@ -197,11 +197,14 @@ async function renderPagesPageResponse(options) {
|
|
|
197
197
|
scriptNonce: options.scriptNonce,
|
|
198
198
|
context: {
|
|
199
199
|
err: options.err,
|
|
200
|
+
req: options.documentReqRes?.req,
|
|
201
|
+
res: options.documentReqRes?.res,
|
|
200
202
|
pathname: options.routePattern,
|
|
201
203
|
query: options.query ?? options.params,
|
|
202
204
|
asPath: options.routeUrl
|
|
203
205
|
}
|
|
204
206
|
});
|
|
207
|
+
if (options.documentReqRes?.res.headersSent && options.documentReqRes.responsePromise) return options.documentReqRes.responsePromise;
|
|
205
208
|
let bodyStream;
|
|
206
209
|
if (documentRenderPage.status === "rendered") bodyStream = new ReadableStream({ start(controller) {
|
|
207
210
|
controller.enqueue(new TextEncoder().encode(documentRenderPage.bodyHtml));
|
|
@@ -230,7 +233,7 @@ async function renderPagesPageResponse(options) {
|
|
|
230
233
|
const shellPrefix = shellHtml.slice(0, markerIndex);
|
|
231
234
|
const shellSuffix = shellHtml.slice(markerIndex + 25);
|
|
232
235
|
const responseHeaders = new Headers({ "Content-Type": "text/html" });
|
|
233
|
-
const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes, options.statusCode);
|
|
236
|
+
const finalStatus = applyGsspHeaders(responseHeaders, options.gsspRes ?? options.documentReqRes?.res ?? null, options.statusCode);
|
|
234
237
|
let responseBodyStream = bodyStream;
|
|
235
238
|
if (!options.scriptNonce && options.isrRevalidateSeconds !== null && options.isrRevalidateSeconds > 0) {
|
|
236
239
|
const cacheBodyStreamPair = bodyStream.tee();
|
|
@@ -34,11 +34,13 @@ type PagesPipelineDeps = {
|
|
|
34
34
|
hadBasePath: boolean;
|
|
35
35
|
isDataReq: boolean;
|
|
36
36
|
isDataRequest: boolean;
|
|
37
|
+
hasMiddleware: boolean;
|
|
37
38
|
ctx?: unknown;
|
|
38
39
|
rawSearch?: string;
|
|
39
40
|
matchPageRoute?: ((pathname: string, request: Request) => {
|
|
40
41
|
route: {
|
|
41
42
|
isDynamic: boolean;
|
|
43
|
+
pattern?: string;
|
|
42
44
|
};
|
|
43
45
|
} | null) | null;
|
|
44
46
|
runMiddleware?: ((request: Request, ctx: unknown, opts: {
|
|
@@ -1,4 +1,5 @@
|
|
|
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";
|
|
@@ -141,6 +142,13 @@ async function runPagesRequest(request, deps) {
|
|
|
141
142
|
});
|
|
142
143
|
let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
143
144
|
const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
|
|
145
|
+
const matchedPathnameForRoute = (routePattern) => {
|
|
146
|
+
const matchedPathname = routePattern ? patternToNextFormat(routePattern) : resolvedPathname;
|
|
147
|
+
if (!i18nConfig) return matchedPathname;
|
|
148
|
+
const resolvedLocale = resolvedPathname.split("/", 3)[1];
|
|
149
|
+
if (resolvedLocale && i18nConfig.locales.includes(resolvedLocale)) return matchedPathname === "/" ? `/${resolvedLocale}` : `/${resolvedLocale}${matchedPathname}`;
|
|
150
|
+
return matchResolvedPathname(matchedPathname);
|
|
151
|
+
};
|
|
144
152
|
if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
|
|
145
153
|
configHeaders,
|
|
146
154
|
pathname: matchPathname,
|
|
@@ -268,12 +276,28 @@ async function runPagesRequest(request, deps) {
|
|
|
268
276
|
if (fallbackFilesystemResult) return fallbackFilesystemResult;
|
|
269
277
|
const fallbackApiResult = await handleResolvedApiRoute();
|
|
270
278
|
if (fallbackApiResult) return fallbackApiResult;
|
|
279
|
+
renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
271
280
|
response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
272
281
|
matchedFallbackRewrite = true;
|
|
273
282
|
if (response.status !== 404) break;
|
|
274
283
|
}
|
|
275
284
|
if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
276
|
-
const
|
|
285
|
+
const matchedPathHeaders = { ...middlewareHeaders };
|
|
286
|
+
if ((isDataReq || isDataRequest) && deps.hasMiddleware && !renderPageMatch && response.status === 404 && (middlewareStatus === void 0 || middlewareStatus === 200 || middlewareStatus === 404)) {
|
|
287
|
+
const headers = new Headers(response.headers);
|
|
288
|
+
headers.set("content-type", "application/json");
|
|
289
|
+
headers.set("x-nextjs-matched-path", matchResolvedPathname(pathname));
|
|
290
|
+
return {
|
|
291
|
+
type: "response",
|
|
292
|
+
response: mergeHeaders(new Response("{}", {
|
|
293
|
+
status: 200,
|
|
294
|
+
headers
|
|
295
|
+
}), matchedPathHeaders, void 0),
|
|
296
|
+
defaultContentType: "application/json"
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
if ((isDataReq || isDataRequest) && renderPageMatch && (middlewareStatus ?? response.status) === 200) matchedPathHeaders["x-nextjs-matched-path"] = matchedPathnameForRoute(renderPageMatch?.route.pattern);
|
|
300
|
+
const merged = mergeHeaders(response, matchedPathHeaders, middlewareStatus);
|
|
277
301
|
if (merged !== response) merged.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
|
|
278
302
|
return {
|
|
279
303
|
type: "response",
|
|
@@ -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 { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
|
|
6
|
+
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.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) {
|
|
@@ -74,7 +74,7 @@ declare function mergeResponseHeaders(middlewareHeaders: Record<string, string |
|
|
|
74
74
|
* arguments in (headers, response) order. The request path now calls
|
|
75
75
|
* `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
|
|
76
76
|
* only for its existing tests and any external callers, so there is a single
|
|
77
|
-
* implementation to keep in sync.
|
|
77
|
+
* implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
|
|
78
78
|
*/
|
|
79
79
|
declare function mergeWebResponse(middlewareHeaders: Record<string, string | string[]>, response: Response, statusOverride?: number): Response;
|
|
80
80
|
/**
|
|
@@ -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 } 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, parseNextDataPathname } from "./pages-data-route.js";
|
|
9
11
|
import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
10
12
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, isSafeImageContentType, parseImageParams } from "./image-optimization.js";
|
|
11
13
|
import { installSocketErrorBackstop } from "./socket-error-backstop.js";
|
|
12
14
|
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
|
|
13
15
|
import { CONTENT_TYPES, StaticFileCache, etagFromFilenameHash } from "./static-file-cache.js";
|
|
14
|
-
import { buildNextDataNotFoundResponse, isNextDataPathname, parseNextDataPathname } from "./pages-data-route.js";
|
|
15
16
|
import { collectInlineCssManifest } from "../build/inline-css.js";
|
|
16
17
|
import { mergeHeaders } from "./worker-utils.js";
|
|
17
18
|
import { runPagesRequest, wrapMiddlewareWithBasePath } from "./pages-request-pipeline.js";
|
|
18
|
-
import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
19
19
|
import { computeClientRuntimeMetadata } from "../utils/client-runtime-metadata.js";
|
|
20
|
+
import { readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
|
|
21
|
+
import { setPagesClientAssets } from "./pages-client-assets.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.
|
|
@@ -275,8 +277,11 @@ function installClientBuildManifestGlobals(clientDir, assetBase, assetPrefix) {
|
|
|
275
277
|
assetBase,
|
|
276
278
|
assetPrefix
|
|
277
279
|
});
|
|
278
|
-
|
|
279
|
-
|
|
280
|
+
setPagesClientAssets({
|
|
281
|
+
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
282
|
+
lazyChunks: metadata.lazyChunks,
|
|
283
|
+
dynamicPreloads: metadata.dynamicPreloads
|
|
284
|
+
});
|
|
280
285
|
}
|
|
281
286
|
function isNoBodyResponseStatus(status) {
|
|
282
287
|
return NO_BODY_RESPONSE_STATUSES.has(status);
|
|
@@ -305,7 +310,7 @@ function logProdServerStarted(host, port, purpose) {
|
|
|
305
310
|
* arguments in (headers, response) order. The request path now calls
|
|
306
311
|
* `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
|
|
307
312
|
* only for its existing tests and any external callers, so there is a single
|
|
308
|
-
* implementation to keep in sync.
|
|
313
|
+
* implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
|
|
309
314
|
*/
|
|
310
315
|
function mergeWebResponse(middlewareHeaders, response, statusOverride) {
|
|
311
316
|
return mergeHeaders(response, middlewareHeaders, statusOverride);
|
|
@@ -736,18 +741,21 @@ function readSsrManifest(clientDir) {
|
|
|
736
741
|
}
|
|
737
742
|
return parsed;
|
|
738
743
|
}
|
|
739
|
-
function
|
|
744
|
+
function installPagesClientAssets(options) {
|
|
740
745
|
const ssrManifest = readSsrManifest(options.clientDir);
|
|
741
|
-
globalThis.__VINEXT_SSR_MANIFEST__ = Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0;
|
|
742
746
|
const metadata = computeClientRuntimeMetadata({
|
|
743
747
|
clientDir: options.clientDir,
|
|
744
748
|
assetBase: options.assetBase,
|
|
745
749
|
assetPrefix: options.assetPrefix,
|
|
746
750
|
includeClientEntry: options.clientEntryLookup === "pages-client-entry" ? "pages-client-entry" : true
|
|
747
751
|
});
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
752
|
+
setPagesClientAssets({
|
|
753
|
+
clientEntry: metadata.clientEntryFile,
|
|
754
|
+
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
755
|
+
ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
|
|
756
|
+
lazyChunks: metadata.lazyChunks,
|
|
757
|
+
dynamicPreloads: metadata.dynamicPreloads
|
|
758
|
+
});
|
|
751
759
|
return ssrManifest;
|
|
752
760
|
}
|
|
753
761
|
/**
|
|
@@ -769,11 +777,6 @@ function installPagesClientAssetGlobals(options) {
|
|
|
769
777
|
*/
|
|
770
778
|
async function startAppRouterServer(options) {
|
|
771
779
|
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 {}
|
|
777
780
|
const prerenderSecret = readPrerenderSecret(path.dirname(rscEntryPath));
|
|
778
781
|
const rscModule = await importServerEntryModule(rscEntryPath);
|
|
779
782
|
const rscHandler = resolveAppRouterHandler(rscModule.default);
|
|
@@ -781,10 +784,18 @@ async function startAppRouterServer(options) {
|
|
|
781
784
|
const appRouterBasePath = typeof rscModule.__basePath === "string" ? rscModule.__basePath : "";
|
|
782
785
|
const appRouterInlineCss = rscModule.__inlineCss === true;
|
|
783
786
|
const appRouterHasPagesDir = rscModule.__hasPagesDir === true;
|
|
787
|
+
const appImageAllowedWidths = Array.isArray(rscModule.__imageAllowedWidths) ? rscModule.__imageAllowedWidths : [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES];
|
|
788
|
+
let imageConfig = typeof rscModule.__imageConfig === "object" && rscModule.__imageConfig !== null ? rscModule.__imageConfig : void 0;
|
|
789
|
+
if (imageConfig === void 0) {
|
|
790
|
+
const imageConfigPath = path.join(path.dirname(rscEntryPath), "image-config.json");
|
|
791
|
+
if (fs.existsSync(imageConfigPath)) try {
|
|
792
|
+
imageConfig = JSON.parse(fs.readFileSync(imageConfigPath, "utf-8"));
|
|
793
|
+
} catch {}
|
|
794
|
+
}
|
|
784
795
|
globalThis.__VINEXT_INLINE_CSS__ = appRouterInlineCss ? collectInlineCssManifest(clientDir, appRouterAssetPrefix) : void 0;
|
|
785
796
|
const appAssetPathPrefix = assetPrefixPathname(appRouterAssetPrefix);
|
|
786
797
|
const appAssetBase = appRouterBasePath ? `${appRouterBasePath}/` : "/";
|
|
787
|
-
if (appRouterHasPagesDir)
|
|
798
|
+
if (appRouterHasPagesDir) installPagesClientAssets({
|
|
788
799
|
clientDir,
|
|
789
800
|
assetPrefix: appRouterAssetPrefix,
|
|
790
801
|
assetBase: appAssetBase,
|
|
@@ -819,17 +830,16 @@ async function startAppRouterServer(options) {
|
|
|
819
830
|
return;
|
|
820
831
|
}
|
|
821
832
|
}
|
|
833
|
+
let missingBuildAsset = false;
|
|
822
834
|
{
|
|
823
835
|
const assetLookupPath = resolveAppRouterAssetPath(pathname, appAssetPathPrefix, appRouterAssetPrefix);
|
|
824
836
|
if (assetLookupPath) {
|
|
825
837
|
if (await tryServeStatic(req, res, clientDir, assetLookupPath, compress, staticCache)) return;
|
|
826
|
-
|
|
827
|
-
res.end("Not Found");
|
|
828
|
-
return;
|
|
838
|
+
missingBuildAsset = true;
|
|
829
839
|
}
|
|
830
840
|
}
|
|
831
841
|
if (isImageOptimizationPath(pathname)) {
|
|
832
|
-
const params = parseImageParams(new URL(rawUrl, "http://localhost"),
|
|
842
|
+
const params = parseImageParams(new URL(rawUrl, "http://localhost"), appImageAllowedWidths, imageConfig?.qualities);
|
|
833
843
|
if (!params) {
|
|
834
844
|
res.writeHead(400);
|
|
835
845
|
res.end("Bad Request");
|
|
@@ -868,6 +878,12 @@ async function startAppRouterServer(options) {
|
|
|
868
878
|
await sendWebResponse(notFoundResponse({ headers: toWebHeaders(staticResponseHeaders) }), req, res, compress);
|
|
869
879
|
return;
|
|
870
880
|
}
|
|
881
|
+
if (missingBuildAsset && response.status === 404) {
|
|
882
|
+
cancelResponseBody(response);
|
|
883
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
884
|
+
res.end("Not Found");
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
871
887
|
await sendWebResponse(response, req, res, compress);
|
|
872
888
|
} catch (e) {
|
|
873
889
|
console.error("[vinext] Server error:", e);
|
|
@@ -918,6 +934,7 @@ async function startPagesRouterServer(options) {
|
|
|
918
934
|
const serverEntry = await importServerEntryModule(serverEntryPath);
|
|
919
935
|
const { renderPage, handleApiRoute: handleApi, runMiddleware, vinextConfig, buildId: pagesBuildId } = serverEntry;
|
|
920
936
|
const matchPageRoute = typeof serverEntry.matchPageRoute === "function" ? serverEntry.matchPageRoute : void 0;
|
|
937
|
+
const hasMiddleware = serverEntry.hasMiddleware === true;
|
|
921
938
|
const pageRoutes = readPagesServerEntryPageRoutes(serverEntry.pageRoutes);
|
|
922
939
|
const prerenderSecret = readPrerenderSecret(path.dirname(serverEntryPath));
|
|
923
940
|
const basePath = vinextConfig?.basePath ?? "";
|
|
@@ -941,7 +958,7 @@ async function startPagesRouterServer(options) {
|
|
|
941
958
|
contentDispositionType: vinextConfig.images.contentDispositionType,
|
|
942
959
|
contentSecurityPolicy: vinextConfig.images.contentSecurityPolicy
|
|
943
960
|
} : void 0;
|
|
944
|
-
const ssrManifest =
|
|
961
|
+
const ssrManifest = installPagesClientAssets({
|
|
945
962
|
clientDir,
|
|
946
963
|
assetPrefix,
|
|
947
964
|
assetBase,
|
|
@@ -1000,11 +1017,9 @@ async function startPagesRouterServer(options) {
|
|
|
1000
1017
|
}
|
|
1001
1018
|
const staticLookupPath = stripBasePath(pathname, basePath);
|
|
1002
1019
|
const pagesAssetLookup = resolveAppRouterAssetPath(pathname, pagesAssetPathPrefix, assetPrefix);
|
|
1020
|
+
const missingBuildAsset = pagesAssetLookup !== null;
|
|
1003
1021
|
if (pagesAssetLookup) {
|
|
1004
1022
|
if (await tryServeStatic(req, res, clientDir, pagesAssetLookup, compress, staticCache)) return;
|
|
1005
|
-
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
1006
|
-
res.end("Not Found");
|
|
1007
|
-
return;
|
|
1008
1023
|
}
|
|
1009
1024
|
if (isImageOptimizationPath(pathname) || isImageOptimizationPath(staticLookupPath)) {
|
|
1010
1025
|
const params = parseImageParams(new URL(rawUrl, "http://localhost"), allowedImageWidths, pagesImageConfig?.qualities);
|
|
@@ -1072,6 +1087,7 @@ async function startPagesRouterServer(options) {
|
|
|
1072
1087
|
hadBasePath,
|
|
1073
1088
|
isDataReq,
|
|
1074
1089
|
isDataRequest,
|
|
1090
|
+
hasMiddleware,
|
|
1075
1091
|
ctx: void 0,
|
|
1076
1092
|
rawSearch: rawQs,
|
|
1077
1093
|
matchPageRoute: matchPageRoute ?? null,
|
|
@@ -1089,6 +1105,12 @@ async function startPagesRouterServer(options) {
|
|
|
1089
1105
|
if (result.type === "handled") return;
|
|
1090
1106
|
if (result.type === "response") {
|
|
1091
1107
|
const { response } = result;
|
|
1108
|
+
if (missingBuildAsset && response.status === 404) {
|
|
1109
|
+
cancelResponseBody(response);
|
|
1110
|
+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
1111
|
+
res.end("Not Found");
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1092
1114
|
if (isVinextStreamedHtmlResponse(response) || !response.body || result.defaultContentType === void 0) {
|
|
1093
1115
|
await sendWebResponse(response, req, res, compress);
|
|
1094
1116
|
return;
|
|
@@ -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";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isrCacheKey, isrSetPrerenderedAppPage } from "./isr-cache.js";
|
|
2
|
+
import { getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest } from "./prerender-manifest.js";
|
|
2
3
|
import { buildAppPageCacheTags } from "./app-page-cache.js";
|
|
3
4
|
import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths.js";
|
|
4
5
|
import { addPregeneratedConcretePath, clearPregeneratedConcretePaths, normalizePregeneratedPathname } from "./pregenerated-concrete-paths.js";
|
|
5
|
-
import { getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest } from "./prerender-manifest.js";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
//#region src/server/seed-cache.ts
|
|
@@ -67,7 +67,7 @@ async function seedMemoryCacheFromPrerender(serverDir, options) {
|
|
|
67
67
|
const revalidateSeconds = typeof route.revalidate === "number" ? route.revalidate : void 0;
|
|
68
68
|
const expireSeconds = typeof route.expire === "number" ? route.expire : void 0;
|
|
69
69
|
const tags = buildAppPageCacheTags(cachePathname, []);
|
|
70
|
-
if (await seedHtml(writeAppPageEntry, prerenderDir, htmlKey, artifactPathname, trailingSlash, revalidateSeconds, expireSeconds, tags)) {
|
|
70
|
+
if (await seedHtml(writeAppPageEntry, prerenderDir, htmlKey, artifactPathname, trailingSlash, route.headers, revalidateSeconds, expireSeconds, tags)) {
|
|
71
71
|
await seedRsc(writeAppPageEntry, prerenderDir, rscKey, artifactPathname, revalidateSeconds, expireSeconds, tags);
|
|
72
72
|
seeded++;
|
|
73
73
|
}
|
|
@@ -81,7 +81,7 @@ function createDefaultAppPageEntryWriter() {
|
|
|
81
81
|
* Seed the HTML cache entry for a single route.
|
|
82
82
|
* Returns true if the file existed and was seeded.
|
|
83
83
|
*/
|
|
84
|
-
async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailingSlash, revalidateSeconds, expireSeconds, tags) {
|
|
84
|
+
async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailingSlash, headers, revalidateSeconds, expireSeconds, tags) {
|
|
85
85
|
const relPath = getOutputPath(pathname, trailingSlash);
|
|
86
86
|
const fullPath = path.join(prerenderDir, relPath);
|
|
87
87
|
if (!fs.existsSync(fullPath)) return false;
|
|
@@ -89,7 +89,7 @@ async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailing
|
|
|
89
89
|
kind: "APP_PAGE",
|
|
90
90
|
html: fs.readFileSync(fullPath, "utf-8"),
|
|
91
91
|
rscData: void 0,
|
|
92
|
-
headers
|
|
92
|
+
headers,
|
|
93
93
|
postponed: void 0,
|
|
94
94
|
status: void 0
|
|
95
95
|
}, {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//#region src/server/worker-utils.d.ts
|
|
2
|
+
declare function finalizeMissingStaticAssetResponse(response: Response, missingBuildAsset: boolean): Response;
|
|
2
3
|
declare function mergeHeaders(response: Response, extraHeaders: Record<string, string | string[]>, statusOverride?: number): Response;
|
|
3
4
|
declare function resolveStaticAssetSignal(signalResponse: Response, options: {
|
|
4
5
|
fetchAsset(path: string): Promise<Response>;
|
|
5
6
|
}): Promise<Response | null>;
|
|
6
7
|
//#endregion
|
|
7
|
-
export { mergeHeaders, resolveStaticAssetSignal };
|
|
8
|
+
export { finalizeMissingStaticAssetResponse, mergeHeaders, resolveStaticAssetSignal };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { VINEXT_STATIC_FILE_HEADER } from "./headers.js";
|
|
2
|
+
import { notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
2
3
|
//#region src/server/worker-utils.ts
|
|
3
4
|
/**
|
|
4
5
|
* Shared utilities for Cloudflare Worker entries.
|
|
@@ -29,6 +30,11 @@ function cancelResponseBody(response) {
|
|
|
29
30
|
if (!body || body.locked) return;
|
|
30
31
|
body.cancel().catch(() => {});
|
|
31
32
|
}
|
|
33
|
+
function finalizeMissingStaticAssetResponse(response, missingBuildAsset) {
|
|
34
|
+
if (!missingBuildAsset || response.status !== 404) return response;
|
|
35
|
+
cancelResponseBody(response);
|
|
36
|
+
return notFoundStaticAssetResponse();
|
|
37
|
+
}
|
|
32
38
|
function buildHeaderRecord(response, omitNames = []) {
|
|
33
39
|
const omitted = new Set(omitNames.map((name) => name.toLowerCase()));
|
|
34
40
|
const headers = {};
|
|
@@ -96,4 +102,4 @@ async function resolveStaticAssetSignal(signalResponse, options) {
|
|
|
96
102
|
return mergeHeaders(assetResponse, extraHeaders, assetResponse.ok && signalResponse.status !== 200 ? signalResponse.status : void 0);
|
|
97
103
|
}
|
|
98
104
|
//#endregion
|
|
99
|
-
export { mergeHeaders, resolveStaticAssetSignal };
|
|
105
|
+
export { finalizeMissingStaticAssetResponse, mergeHeaders, resolveStaticAssetSignal };
|