vinext 0.2.1 → 1.0.0-beta.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 +67 -30
- package/dist/build/assets-ignore.js +1 -1
- package/dist/build/clean-output.js +1 -1
- package/dist/build/client-build-config.d.ts +13 -92
- package/dist/build/client-build-config.js +23 -99
- package/dist/build/css-url-assets.js +3 -3
- package/dist/build/google-fonts/fallback-metrics.js +1 -1
- package/dist/build/google-fonts/font-metadata.js +1 -1
- package/dist/build/inject-pregenerated-paths.js +1 -1
- package/dist/build/inline-css.js +2 -5
- package/dist/build/module-dependency-cache.d.ts +4 -0
- package/dist/build/module-dependency-cache.js +13 -0
- package/dist/build/next-client-runtime-manifests.js +1 -1
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/precompress.js +7 -7
- package/dist/build/prerender-paths.d.ts +23 -0
- package/dist/build/prerender-paths.js +291 -0
- package/dist/build/prerender-server-pool.js +2 -2
- package/dist/build/prerender.d.ts +12 -1
- package/dist/build/prerender.js +2 -2
- package/dist/build/preview-credentials.d.ts +11 -0
- package/dist/build/preview-credentials.js +19 -0
- package/dist/build/report.d.ts +0 -3
- package/dist/build/report.js +2 -4
- package/dist/build/run-prerender.d.ts +2 -11
- package/dist/build/run-prerender.js +2 -10
- package/dist/build/server-manifest.js +1 -1
- package/dist/build/ssr-manifest.d.ts +4 -0
- package/dist/build/ssr-manifest.js +10 -6
- package/dist/build/standalone.js +37 -37
- package/dist/cache/cache-adapters-virtual.d.ts +7 -17
- package/dist/cache/cache-adapters-virtual.js +35 -2
- package/dist/check.d.ts +0 -16
- package/dist/check.js +17 -34
- package/dist/cli.js +86 -101
- package/dist/client/instrumentation-client-inject.js +1 -1
- package/dist/client/pages-router-link-navigation.js +1 -1
- package/dist/config/config-matchers.js +2 -2
- package/dist/config/dotenv.js +1 -1
- package/dist/config/next-config.d.ts +4 -1
- package/dist/config/next-config.js +82 -16
- package/dist/config/prerender.d.ts +12 -2
- package/dist/config/prerender.js +22 -12
- package/dist/config/server-external-packages.js +1 -1
- package/dist/config/tsconfig-paths.js +7 -3
- package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
- package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
- package/dist/entries/app-rsc-entry.js +12 -5
- package/dist/entries/app-rsc-manifest.js +4 -4
- package/dist/entries/pages-client-entry.js +6 -5
- package/dist/entries/pages-server-entry.js +15 -26
- package/dist/entries/runtime-entry-module.js +2 -2
- package/dist/image/image-adapters-virtual.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +500 -338
- package/dist/init-cloudflare.js +13 -4
- package/dist/init-platform.d.ts +10 -1
- package/dist/init-platform.js +79 -13
- package/dist/init.d.ts +11 -3
- package/dist/init.js +133 -35
- package/dist/plugins/ast-utils.js +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +7 -7
- package/dist/plugins/extensionless-dynamic-import.js +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +13 -8
- package/dist/plugins/import-meta-url.js +16 -17
- package/dist/plugins/middleware-export-validation.js +1 -1
- package/dist/plugins/middleware-server-only.js +2 -2
- package/dist/plugins/og-asset-ownership.js +7 -6
- package/dist/plugins/og-assets.js +4 -5
- package/dist/plugins/optimize-imports.js +12 -13
- package/dist/plugins/postcss.js +1 -1
- package/dist/plugins/remove-console.js +1 -1
- package/dist/plugins/require-context.js +1 -1
- package/dist/plugins/sass.js +2 -2
- package/dist/plugins/server-externals-manifest.js +1 -1
- package/dist/plugins/strip-server-exports.js +1 -1
- package/dist/plugins/styled-jsx.js +3 -2
- package/dist/plugins/typeof-window.js +1 -1
- package/dist/routing/app-route-graph.d.ts +3 -10
- package/dist/routing/app-route-graph.js +28 -76
- package/dist/routing/app-router.d.ts +0 -5
- package/dist/routing/app-router.js +0 -5
- package/dist/routing/file-matcher.d.ts +2 -6
- package/dist/routing/file-matcher.js +10 -11
- package/dist/routing/pages-router.js +3 -3
- package/dist/server/api-handler.js +41 -33
- package/dist/server/app-browser-entry.js +15 -11
- package/dist/server/app-browser-navigation-controller.js +9 -4
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-elements-wire.d.ts +2 -1
- package/dist/server/app-fallback-renderer.d.ts +8 -0
- package/dist/server/app-fallback-renderer.js +13 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-page-boundary-render.d.ts +14 -1
- package/dist/server/app-page-boundary-render.js +107 -54
- package/dist/server/app-page-cache-render.d.ts +1 -1
- package/dist/server/app-page-dispatch.d.ts +2 -1
- package/dist/server/app-page-dispatch.js +29 -40
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +3 -3
- package/dist/server/app-page-execution.d.ts +3 -1
- package/dist/server/app-page-execution.js +31 -39
- package/dist/server/app-page-render.d.ts +1 -1
- package/dist/server/app-page-request.js +1 -1
- package/dist/server/app-page-route-wiring.js +4 -4
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-tree-prefetch.js +1 -1
- package/dist/server/app-rsc-cache-busting.js +1 -2
- package/dist/server/app-rsc-handler.js +2 -2
- package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
- package/dist/server/app-rsc-redirect-flight.js +71 -0
- package/dist/server/app-rsc-render-mode.d.ts +2 -5
- package/dist/server/app-rsc-render-mode.js +2 -12
- package/dist/server/app-segment-config.js +2 -2
- package/dist/server/app-server-action-execution.js +3 -3
- package/dist/server/app-ssr-entry.js +4 -1
- package/dist/server/app-ssr-stream.d.ts +2 -1
- package/dist/server/app-ssr-stream.js +4 -1
- package/dist/server/cache-proof.js +1 -1
- package/dist/server/default-global-error-module.d.ts +3 -1
- package/dist/server/default-not-found-module.d.ts +3 -1
- package/dist/server/dev-lockfile.js +2 -3
- package/dist/server/dev-module-runner.js +1 -1
- package/dist/server/dev-origin-check.d.ts +2 -2
- package/dist/server/dev-origin-check.js +2 -2
- package/dist/server/dev-route-files.js +1 -1
- package/dist/server/dev-server.js +256 -164
- package/dist/server/dev-stack-sourcemap.js +4 -3
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +3 -1
- package/dist/server/image-optimization.d.ts +12 -1
- package/dist/server/image-optimization.js +15 -3
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/instrumentation.js +2 -2
- package/dist/server/isr-cache.d.ts +12 -4
- package/dist/server/isr-cache.js +3 -3
- package/dist/server/metadata-routes.js +4 -4
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-runtime.js +1 -1
- package/dist/server/middleware.d.ts +1 -0
- package/dist/server/middleware.js +1 -1
- package/dist/server/navigation-planner.d.ts +2 -0
- package/dist/server/navigation-planner.js +8 -2
- package/dist/server/next-error-digest.d.ts +9 -24
- package/dist/server/next-error-digest.js +23 -15
- package/dist/server/operation-token.js +1 -1
- package/dist/server/pages-body-parser-config.js +2 -1
- package/dist/server/pages-dev-hydration.d.ts +14 -0
- package/dist/server/pages-dev-hydration.js +83 -0
- package/dist/server/pages-dev-module-url.js +2 -2
- package/dist/server/pages-node-compat.d.ts +13 -6
- package/dist/server/pages-node-compat.js +44 -45
- package/dist/server/pages-page-data.d.ts +1 -1
- package/dist/server/pages-page-data.js +5 -4
- package/dist/server/pages-page-handler.js +61 -29
- package/dist/server/pages-page-response.d.ts +2 -2
- package/dist/server/pages-page-response.js +2 -2
- package/dist/server/pages-preview.d.ts +26 -0
- package/dist/server/pages-preview.js +165 -0
- package/dist/server/pages-readiness.d.ts +2 -1
- package/dist/server/pages-readiness.js +4 -2
- package/dist/server/pages-request-pipeline.js +1 -1
- package/dist/server/prerender-manifest.d.ts +15 -1
- package/dist/server/prerender-manifest.js +29 -1
- package/dist/server/prod-server.d.ts +6 -5
- package/dist/server/prod-server.js +15 -15
- package/dist/server/request-pipeline.js +1 -1
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/socket-error-backstop.js +1 -1
- package/dist/server/static-file-cache.js +8 -9
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache.d.ts +1 -1
- package/dist/shims/cache.js +2 -1
- package/dist/shims/cdn-cache.d.ts +2 -7
- package/dist/shims/cdn-cache.js +2 -14
- package/dist/shims/constants.js +1 -1
- package/dist/shims/error-boundary.d.ts +4 -4
- package/dist/shims/error.d.ts +21 -5
- package/dist/shims/error.js +52 -14
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-utils.js +1 -1
- package/dist/shims/form.d.ts +1 -1
- package/dist/shims/head.js +3 -3
- package/dist/shims/headers.js +6 -4
- package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/link.d.ts +3 -1
- package/dist/shims/link.js +6 -3
- package/dist/shims/navigation-errors.d.ts +2 -1
- package/dist/shims/navigation-errors.js +9 -13
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +5 -5
- package/dist/shims/request-state-types.d.ts +2 -2
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router.d.ts +2 -1
- package/dist/shims/router.js +18 -11
- package/dist/shims/script.js +1 -1
- package/dist/shims/server.js +2 -2
- package/dist/shims/slot.d.ts +1 -1
- package/dist/shims/thenable-params.js +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/typegen.js +9 -11
- package/dist/utils/client-build-manifest.js +2 -2
- package/dist/utils/client-entry-manifest.js +1 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/commonjs-loader.js +3 -3
- package/dist/utils/mdx-scan.js +1 -1
- package/dist/utils/path.d.ts +1 -13
- package/dist/utils/path.js +1 -15
- package/dist/utils/plugin-options.d.ts +4 -0
- package/dist/utils/plugin-options.js +8 -0
- package/dist/utils/project.d.ts +1 -7
- package/dist/utils/project.js +2 -8
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.js +1 -1
- package/dist/utils/redirect-digest.d.ts +9 -0
- package/dist/utils/redirect-digest.js +25 -0
- package/dist/utils/vinext-root.js +1 -1
- package/dist/utils/vite-version.d.ts +6 -13
- package/dist/utils/vite-version.js +68 -34
- package/package.json +33 -14
- package/dist/cloudflare/index.d.ts +0 -3
- package/dist/cloudflare/index.js +0 -3
- package/dist/packages/cloudflare/src/cache/cdn-adapter.runtime.js +0 -102
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +0 -126
- package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +0 -442
- package/dist/packages/cloudflare/src/deploy-config.js +0 -150
- package/dist/packages/cloudflare/src/deploy-help.js +0 -55
- package/dist/packages/cloudflare/src/deploy.js +0 -272
- package/dist/packages/cloudflare/src/tpr.d.ts +0 -45
- package/dist/packages/cloudflare/src/tpr.js +0 -582
- package/dist/packages/cloudflare/src/utils/cache-control-metadata.js +0 -20
- /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
- /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
- /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/build/module-dependency-cache.ts
|
|
2
|
+
function createModuleDependencyCache(collect) {
|
|
3
|
+
const cache = /* @__PURE__ */ new Map();
|
|
4
|
+
return function getModuleDependencies(moduleId) {
|
|
5
|
+
const cached = cache.get(moduleId);
|
|
6
|
+
if (cached) return cached;
|
|
7
|
+
const pending = collect(moduleId);
|
|
8
|
+
cache.set(moduleId, pending);
|
|
9
|
+
return pending;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { createModuleDependencyCache };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
3
|
//#region src/build/next-client-runtime-manifests.ts
|
|
4
4
|
function normalizeRewriteForClientManifest(rewrite) {
|
|
5
5
|
if (rewrite.destination.startsWith("/")) return {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
3
|
//#region src/build/pages-client-assets-module.ts
|
|
4
4
|
const PAGES_CLIENT_ASSETS_MODULE = "vinext-client-assets.js";
|
|
5
5
|
const pagesClientAssetsByBuildSession = /* @__PURE__ */ new Map();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { ASSET_PREFIX_URL_DIR } from "../utils/asset-prefix.js";
|
|
2
|
-
import
|
|
3
|
-
import fs from "node:fs/promises";
|
|
3
|
+
import fsp from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import zlib from "node:zlib";
|
|
6
6
|
import { promisify } from "node:util";
|
|
@@ -20,7 +20,7 @@ const brotliCompress = promisify(zlib.brotliCompress);
|
|
|
20
20
|
const gzip = promisify(zlib.gzip);
|
|
21
21
|
const zstdCompress = typeof zlib.zstdCompress === "function" ? promisify(zlib.zstdCompress) : null;
|
|
22
22
|
/** File extensions worth compressing (text-based, not already compressed). */
|
|
23
|
-
const COMPRESSIBLE_EXTENSIONS = new Set([
|
|
23
|
+
const COMPRESSIBLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
24
24
|
".js",
|
|
25
25
|
".mjs",
|
|
26
26
|
".css",
|
|
@@ -46,7 +46,7 @@ const CONCURRENCY = Math.min(os.availableParallelism(), 8);
|
|
|
46
46
|
async function* walkFiles(dir, base = dir) {
|
|
47
47
|
let entries;
|
|
48
48
|
try {
|
|
49
|
-
entries = await
|
|
49
|
+
entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
50
50
|
} catch {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
@@ -89,13 +89,13 @@ async function precompressAssets(clientDir, options = {}) {
|
|
|
89
89
|
for (let i = 0; i < filePaths.length; i += CONCURRENCY) {
|
|
90
90
|
const chunk = filePaths.slice(i, i + CONCURRENCY);
|
|
91
91
|
await Promise.all(chunk.map(async (fullPath) => {
|
|
92
|
-
const content = await
|
|
92
|
+
const content = await fsp.readFile(fullPath);
|
|
93
93
|
if (content.length < MIN_SIZE) return;
|
|
94
94
|
const compressions = [brotliCompress(content, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 5 } }), gzip(content, { level: 8 })];
|
|
95
95
|
if (zstdCompress) compressions.push(zstdCompress(content, { params: { [zlib.constants.ZSTD_c_compressionLevel]: 8 } }));
|
|
96
96
|
const [brContent, gzContent, zstdContent] = await Promise.all(compressions);
|
|
97
|
-
const writes = [
|
|
98
|
-
if (zstdContent) writes.push(
|
|
97
|
+
const writes = [fsp.writeFile(fullPath + ".br", brContent), fsp.writeFile(fullPath + ".gz", gzContent)];
|
|
98
|
+
if (zstdContent) writes.push(fsp.writeFile(fullPath + ".zst", zstdContent));
|
|
99
99
|
await Promise.all(writes);
|
|
100
100
|
result.filesCompressed++;
|
|
101
101
|
result.totalOriginalBytes += content.length;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ResolvedNextConfig } from "../config/next-config.js";
|
|
2
|
+
import { VinextRouteRootConfig } from "../config/prerender.js";
|
|
3
|
+
|
|
4
|
+
//#region src/build/prerender-paths.d.ts
|
|
5
|
+
type PrerenderPathManifest = {
|
|
6
|
+
buildId?: string;
|
|
7
|
+
trailingSlash?: boolean;
|
|
8
|
+
paths: string[];
|
|
9
|
+
};
|
|
10
|
+
declare const PRERENDER_PATH_DISCOVERY_ENV = "__VINEXT_PRERENDER_PATH_DISCOVERY";
|
|
11
|
+
declare const PRERENDER_PATHS_MANIFEST = "vinext-prerender-paths.json";
|
|
12
|
+
type EmitPrerenderPathManifestOptions = {
|
|
13
|
+
root: string; /** Fully resolved Next.js config. Loaded from disk when omitted. */
|
|
14
|
+
nextConfig?: ResolvedNextConfig;
|
|
15
|
+
appDir?: string | null;
|
|
16
|
+
pagesDir?: string | null;
|
|
17
|
+
routeRootConfig?: VinextRouteRootConfig | null;
|
|
18
|
+
pagesBundlePath?: string;
|
|
19
|
+
rscBundlePath?: string;
|
|
20
|
+
};
|
|
21
|
+
declare function emitPrerenderPathManifest(options: EmitPrerenderPathManifestOptions): Promise<PrerenderPathManifest | null>;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { PRERENDER_PATHS_MANIFEST, PRERENDER_PATH_DISCOVERY_ENV, PrerenderPathManifest, emitPrerenderPathManifest };
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import { findDir } from "../utils/project.js";
|
|
3
|
+
import { apiRouter, pagesRouter } from "../routing/pages-router.js";
|
|
4
|
+
import { VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
|
|
5
|
+
import { classifyAppRoute, classifyPagesRoute, getAppRouteRenderEntryPath, hasNamedExport } from "./report.js";
|
|
6
|
+
import { appRouter } from "../routing/app-router.js";
|
|
7
|
+
import { normalizeStaticPathsEntry } from "../routing/route-pattern.js";
|
|
8
|
+
import { BLOCKED_PAGES, PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
|
|
9
|
+
import { loadNextConfig, resolveNextConfig } from "../config/next-config.js";
|
|
10
|
+
import { readPrerenderSecret } from "./server-manifest.js";
|
|
11
|
+
import { startProdServer } from "../server/prod-server.js";
|
|
12
|
+
import { buildUrlFromParams, resolveParentParams } from "./prerender.js";
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
//#region src/build/prerender-paths.ts
|
|
15
|
+
const PRERENDER_PATH_DISCOVERY_ENV = "__VINEXT_PRERENDER_PATH_DISCOVERY";
|
|
16
|
+
const PRERENDER_PATHS_MANIFEST = "vinext-prerender-paths.json";
|
|
17
|
+
const PATH_DISCOVERY_FETCH_TIMEOUT_MS = 3e4;
|
|
18
|
+
function readBuiltBuildId(serverDir) {
|
|
19
|
+
try {
|
|
20
|
+
const buildId = fs.readFileSync(path.join(serverDir, "BUILD_ID"), "utf-8").trim();
|
|
21
|
+
return buildId.length > 0 ? buildId : null;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return null;
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function addPath(paths, seen, pathname) {
|
|
28
|
+
if (seen.has(pathname)) return;
|
|
29
|
+
seen.add(pathname);
|
|
30
|
+
paths.push(pathname);
|
|
31
|
+
}
|
|
32
|
+
function warnDiscoveryFailure(route, error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34
|
+
console.warn(`[vinext] Warning: failed to discover warmup path(s) for ${route}: ${message}`);
|
|
35
|
+
}
|
|
36
|
+
async function fetchDiscoveryEndpoint(url, headers) {
|
|
37
|
+
const controller = new AbortController();
|
|
38
|
+
const timeout = setTimeout(() => controller.abort(), PATH_DISCOVERY_FETCH_TIMEOUT_MS);
|
|
39
|
+
try {
|
|
40
|
+
const res = await fetch(url, {
|
|
41
|
+
headers,
|
|
42
|
+
signal: controller.signal
|
|
43
|
+
});
|
|
44
|
+
const text = await res.text();
|
|
45
|
+
if (!res.ok || text === "null") return null;
|
|
46
|
+
return text;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error instanceof Error && error.name === "AbortError") throw new Error(`path discovery timed out after ${PATH_DISCOVERY_FETCH_TIMEOUT_MS}ms`);
|
|
49
|
+
throw error;
|
|
50
|
+
} finally {
|
|
51
|
+
clearTimeout(timeout);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function fileHasNamedExport(filePath, name) {
|
|
55
|
+
if (!filePath) return false;
|
|
56
|
+
try {
|
|
57
|
+
return hasNamedExport(fs.readFileSync(filePath, "utf-8"), name);
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function resolveConfiguredRouteDirs(root, routeRootConfig) {
|
|
63
|
+
if (!routeRootConfig) return {
|
|
64
|
+
appDir: findDir(root, "app", "src/app"),
|
|
65
|
+
pagesDir: findDir(root, "pages", "src/pages")
|
|
66
|
+
};
|
|
67
|
+
let baseDir;
|
|
68
|
+
if (routeRootConfig.appDir) {
|
|
69
|
+
baseDir = path.isAbsolute(routeRootConfig.appDir) ? routeRootConfig.appDir : path.resolve(root, routeRootConfig.appDir);
|
|
70
|
+
baseDir = toSlash(baseDir);
|
|
71
|
+
} else {
|
|
72
|
+
const hasRootApp = fs.existsSync(path.join(root, "app"));
|
|
73
|
+
const hasRootPages = fs.existsSync(path.join(root, "pages"));
|
|
74
|
+
const hasSrcApp = fs.existsSync(path.join(root, "src", "app"));
|
|
75
|
+
const hasSrcPages = fs.existsSync(path.join(root, "src", "pages"));
|
|
76
|
+
baseDir = hasRootApp || hasRootPages ? root : hasSrcApp || hasSrcPages ? path.join(root, "src") : root;
|
|
77
|
+
}
|
|
78
|
+
const appDir = path.join(baseDir, "app");
|
|
79
|
+
const pagesDir = path.join(baseDir, "pages");
|
|
80
|
+
return {
|
|
81
|
+
appDir: !routeRootConfig.disableAppRouter && fs.existsSync(appDir) ? appDir : null,
|
|
82
|
+
pagesDir: fs.existsSync(pagesDir) ? pagesDir : null
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function appRouteMayHaveGenerateStaticParams(route) {
|
|
86
|
+
if (fileHasNamedExport(route.pagePath, "generateStaticParams")) return true;
|
|
87
|
+
return route.layouts.some((layoutPath) => fileHasNamedExport(layoutPath, "generateStaticParams"));
|
|
88
|
+
}
|
|
89
|
+
async function shouldStartPathDiscoveryServer(options) {
|
|
90
|
+
if (options.appDir) {
|
|
91
|
+
if ((await appRouter(options.appDir, options.pageExtensions)).some((route) => route.isDynamic && appRouteMayHaveGenerateStaticParams(route))) return true;
|
|
92
|
+
}
|
|
93
|
+
if (options.pagesDir) {
|
|
94
|
+
if ((await pagesRouter(options.pagesDir, options.pageExtensions)).some((route) => route.isDynamic && fileHasNamedExport(route.filePath, "getStaticPaths"))) return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
async function withPrerenderEndpoints(fn) {
|
|
99
|
+
const previousPrerenderFlag = process.env.VINEXT_PRERENDER;
|
|
100
|
+
const previousPathDiscoveryFlag = process.env[PRERENDER_PATH_DISCOVERY_ENV];
|
|
101
|
+
process.env.VINEXT_PRERENDER = "1";
|
|
102
|
+
process.env[PRERENDER_PATH_DISCOVERY_ENV] = "1";
|
|
103
|
+
try {
|
|
104
|
+
return await fn();
|
|
105
|
+
} finally {
|
|
106
|
+
if (previousPrerenderFlag === void 0) delete process.env.VINEXT_PRERENDER;
|
|
107
|
+
else process.env.VINEXT_PRERENDER = previousPrerenderFlag;
|
|
108
|
+
if (previousPathDiscoveryFlag === void 0) delete process.env[PRERENDER_PATH_DISCOVERY_ENV];
|
|
109
|
+
else process.env[PRERENDER_PATH_DISCOVERY_ENV] = previousPathDiscoveryFlag;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function collectPagesPaths(options) {
|
|
113
|
+
const [pageRoutes, apiRoutes] = await Promise.all([pagesRouter(options.pagesDir, options.pageExtensions), apiRouter(options.pagesDir, options.pageExtensions)]);
|
|
114
|
+
const apiPatterns = new Set(apiRoutes.map((route) => route.pattern));
|
|
115
|
+
const paths = [];
|
|
116
|
+
const seen = /* @__PURE__ */ new Set();
|
|
117
|
+
for (const route of pageRoutes) {
|
|
118
|
+
if (apiPatterns.has(route.pattern)) continue;
|
|
119
|
+
if (BLOCKED_PAGES.includes(route.pattern)) continue;
|
|
120
|
+
if (route.pattern === "/404" || route.pattern === "/500" || route.pattern === "/_error") continue;
|
|
121
|
+
const { type } = classifyPagesRoute(route.filePath);
|
|
122
|
+
if (type === "api" || type === "ssr") continue;
|
|
123
|
+
if (!route.isDynamic) {
|
|
124
|
+
addPath(paths, seen, route.pattern);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!fileHasNamedExport(route.filePath, "getStaticPaths")) continue;
|
|
128
|
+
if (!options.baseUrl) continue;
|
|
129
|
+
try {
|
|
130
|
+
const search = new URLSearchParams({ pattern: route.pattern });
|
|
131
|
+
const text = await fetchDiscoveryEndpoint(`${options.baseUrl}/__vinext/prerender/pages-static-paths?${search}`, options.secretHeaders);
|
|
132
|
+
if (text === null) continue;
|
|
133
|
+
const pathsResult = JSON.parse(text);
|
|
134
|
+
for (const item of pathsResult.paths ?? []) {
|
|
135
|
+
const normalized = normalizeStaticPathsEntry(item, route.pattern);
|
|
136
|
+
if ("error" in normalized) throw new Error(normalized.error);
|
|
137
|
+
addPath(paths, seen, buildUrlFromParams(route.pattern, normalized.params));
|
|
138
|
+
}
|
|
139
|
+
} catch (error) {
|
|
140
|
+
warnDiscoveryFailure(route.pattern, error);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return paths;
|
|
144
|
+
}
|
|
145
|
+
async function collectAppPaths(options) {
|
|
146
|
+
const routes = await appRouter(options.appDir, options.pageExtensions);
|
|
147
|
+
const paths = [];
|
|
148
|
+
const seen = /* @__PURE__ */ new Set();
|
|
149
|
+
const staticParamsCache = /* @__PURE__ */ new Map();
|
|
150
|
+
const staticParamsMap = new Proxy({}, {
|
|
151
|
+
get(_target, pattern) {
|
|
152
|
+
return async ({ params }) => {
|
|
153
|
+
if (!options.baseUrl) return null;
|
|
154
|
+
const cacheKey = `${pattern}\0${JSON.stringify(params)}`;
|
|
155
|
+
const cached = staticParamsCache.get(cacheKey);
|
|
156
|
+
if (cached !== void 0) return cached;
|
|
157
|
+
const request = (async () => {
|
|
158
|
+
const search = new URLSearchParams({ pattern });
|
|
159
|
+
if (Object.keys(params).length > 0) search.set("parentParams", JSON.stringify(params));
|
|
160
|
+
const text = await fetchDiscoveryEndpoint(`${options.baseUrl}/__vinext/prerender/static-params?${search}`, options.secretHeaders);
|
|
161
|
+
if (text === null) return null;
|
|
162
|
+
return JSON.parse(text);
|
|
163
|
+
})();
|
|
164
|
+
request.catch(() => staticParamsCache.delete(cacheKey));
|
|
165
|
+
staticParamsCache.set(cacheKey, request);
|
|
166
|
+
return request;
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
has() {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
for (const route of routes) {
|
|
174
|
+
const renderEntryPath = getAppRouteRenderEntryPath(route);
|
|
175
|
+
if (!renderEntryPath) continue;
|
|
176
|
+
const { type } = classifyAppRoute(renderEntryPath, route.routePath, route.isDynamic);
|
|
177
|
+
if (type === "api") continue;
|
|
178
|
+
if (type === "ssr" && !route.isDynamic) continue;
|
|
179
|
+
if (!route.isDynamic) {
|
|
180
|
+
addPath(paths, seen, route.pattern);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (!appRouteMayHaveGenerateStaticParams(route)) continue;
|
|
184
|
+
try {
|
|
185
|
+
const generateStaticParams = staticParamsMap[route.pattern];
|
|
186
|
+
if (typeof generateStaticParams !== "function") continue;
|
|
187
|
+
const parentParamSets = await resolveParentParams(route, staticParamsMap);
|
|
188
|
+
let paramSets;
|
|
189
|
+
if (parentParamSets.length > 0) {
|
|
190
|
+
paramSets = [];
|
|
191
|
+
for (const parentParams of parentParamSets) {
|
|
192
|
+
const childResults = await generateStaticParams({ params: parentParams });
|
|
193
|
+
if (childResults === null) {
|
|
194
|
+
paramSets = null;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
if (Array.isArray(childResults)) for (const childParams of childResults) paramSets.push({
|
|
198
|
+
...parentParams,
|
|
199
|
+
...childParams
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
const results = await generateStaticParams({ params: {} });
|
|
204
|
+
paramSets = Array.isArray(results) || results === null ? results : [];
|
|
205
|
+
}
|
|
206
|
+
if (!paramSets?.length) continue;
|
|
207
|
+
for (const params of paramSets) {
|
|
208
|
+
if (params === null || params === void 0) continue;
|
|
209
|
+
addPath(paths, seen, buildUrlFromParams(route.pattern, params));
|
|
210
|
+
}
|
|
211
|
+
} catch (error) {
|
|
212
|
+
warnDiscoveryFailure(route.pattern, error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return paths;
|
|
216
|
+
}
|
|
217
|
+
async function startPathDiscoveryServer(options) {
|
|
218
|
+
return startProdServer({
|
|
219
|
+
port: 0,
|
|
220
|
+
host: "127.0.0.1",
|
|
221
|
+
outDir: options.pagesBundlePath ? path.dirname(path.dirname(options.pagesBundlePath)) : path.dirname(options.serverDir),
|
|
222
|
+
rscEntryPath: options.rscBundlePath,
|
|
223
|
+
serverEntryPath: options.pagesBundlePath,
|
|
224
|
+
noCompression: true,
|
|
225
|
+
purpose: "prerender"
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
async function emitPrerenderPathManifest(options) {
|
|
229
|
+
const { root } = options;
|
|
230
|
+
const configuredRouteDirs = resolveConfiguredRouteDirs(root, options.routeRootConfig);
|
|
231
|
+
const appDir = options.appDir !== void 0 ? options.appDir : configuredRouteDirs.appDir;
|
|
232
|
+
const pagesDir = options.pagesDir !== void 0 ? options.pagesDir : configuredRouteDirs.pagesDir;
|
|
233
|
+
if (!appDir && !pagesDir) return null;
|
|
234
|
+
const defaultRscBundlePath = options.routeRootConfig?.rscOutDir ? path.join(path.resolve(root, options.routeRootConfig.rscOutDir), "index.js") : path.join(root, "dist", "server", "index.js");
|
|
235
|
+
const rscBundlePath = options.rscBundlePath ?? defaultRscBundlePath;
|
|
236
|
+
const pagesBundlePath = options.pagesBundlePath ?? path.join(root, "dist", "server", "entry.js");
|
|
237
|
+
const bundleServerDir = fs.existsSync(rscBundlePath) ? path.dirname(rscBundlePath) : path.dirname(pagesBundlePath);
|
|
238
|
+
const manifestDir = path.join(root, "dist", "server");
|
|
239
|
+
const config = options.nextConfig ? { ...options.nextConfig } : { ...await resolveNextConfig(await loadNextConfig(root, PHASE_PRODUCTION_BUILD), root) };
|
|
240
|
+
const builtBuildId = readBuiltBuildId(manifestDir) ?? readBuiltBuildId(bundleServerDir);
|
|
241
|
+
if (builtBuildId) config.buildId = builtBuildId;
|
|
242
|
+
const paths = [];
|
|
243
|
+
const seen = /* @__PURE__ */ new Set();
|
|
244
|
+
await withPrerenderEndpoints(async () => {
|
|
245
|
+
let prodServer = null;
|
|
246
|
+
if (await shouldStartPathDiscoveryServer({
|
|
247
|
+
appDir,
|
|
248
|
+
pagesDir,
|
|
249
|
+
pageExtensions: config.pageExtensions
|
|
250
|
+
})) try {
|
|
251
|
+
prodServer = await startPathDiscoveryServer({
|
|
252
|
+
serverDir: bundleServerDir,
|
|
253
|
+
pagesBundlePath: !appDir && pagesDir ? pagesBundlePath : void 0,
|
|
254
|
+
rscBundlePath: appDir ? rscBundlePath : void 0
|
|
255
|
+
});
|
|
256
|
+
} catch (error) {
|
|
257
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
258
|
+
console.warn(`[vinext] Warning: failed to start prerender path discovery server: ${message}`);
|
|
259
|
+
}
|
|
260
|
+
const baseUrl = prodServer ? `http://127.0.0.1:${prodServer.port}` : null;
|
|
261
|
+
const prerenderSecret = readPrerenderSecret(bundleServerDir) ?? readPrerenderSecret(manifestDir);
|
|
262
|
+
const secretHeaders = prerenderSecret ? { [VINEXT_PRERENDER_SECRET_HEADER]: prerenderSecret } : {};
|
|
263
|
+
try {
|
|
264
|
+
if (appDir) for (const pathname of await collectAppPaths({
|
|
265
|
+
appDir,
|
|
266
|
+
baseUrl,
|
|
267
|
+
pageExtensions: config.pageExtensions,
|
|
268
|
+
secretHeaders
|
|
269
|
+
})) addPath(paths, seen, pathname);
|
|
270
|
+
if (pagesDir) for (const pathname of await collectPagesPaths({
|
|
271
|
+
baseUrl,
|
|
272
|
+
pagesDir,
|
|
273
|
+
pageExtensions: config.pageExtensions,
|
|
274
|
+
secretHeaders
|
|
275
|
+
})) addPath(paths, seen, pathname);
|
|
276
|
+
} finally {
|
|
277
|
+
if (prodServer) await new Promise((resolve) => prodServer.server.close(() => resolve()));
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
const manifest = {
|
|
281
|
+
buildId: config.buildId,
|
|
282
|
+
trailingSlash: config.trailingSlash,
|
|
283
|
+
paths
|
|
284
|
+
};
|
|
285
|
+
fs.mkdirSync(manifestDir, { recursive: true });
|
|
286
|
+
fs.writeFileSync(path.join(manifestDir, PRERENDER_PATHS_MANIFEST), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
287
|
+
console.log(` Discovered ${paths.length} CDN warmup path(s).`);
|
|
288
|
+
return manifest;
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
export { PRERENDER_PATHS_MANIFEST, PRERENDER_PATH_DISCOVERY_ENV, emitPrerenderPathManifest };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import { fork } from "node:child_process";
|
|
@@ -50,7 +50,7 @@ const APPROX_BYTES_PER_WORKER = 768 * 1024 * 1024;
|
|
|
50
50
|
const WORKER_READY_TIMEOUT_MS = 6e4;
|
|
51
51
|
/** Best-effort close timeout so build cleanup is not blocked forever by a wedged child. */
|
|
52
52
|
const WORKER_CLOSE_TIMEOUT_MS = 5e3;
|
|
53
|
-
const PRERENDER_WORKER_TRANSPORT_ERROR_CODES = new Set([
|
|
53
|
+
const PRERENDER_WORKER_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
54
54
|
"ECONNREFUSED",
|
|
55
55
|
"ECONNRESET",
|
|
56
56
|
"EPIPE",
|
|
@@ -135,6 +135,17 @@ type PrerenderAppOptionsInternal = PrerenderAppOptions & {
|
|
|
135
135
|
* all '<' and '>' in the embedded JSON, preventing false </script> matches.
|
|
136
136
|
*/
|
|
137
137
|
declare function extractRscPayloadFromPrerenderedHtml(html: string): Uint8Array | null;
|
|
138
|
+
/**
|
|
139
|
+
* Build a URL path from a route pattern and params.
|
|
140
|
+
* "/posts/:id" + { id: "42" } → "/posts/42"
|
|
141
|
+
* "/docs/:slug+" + { slug: ["a", "b"] } → "/docs/a/b"
|
|
142
|
+
*
|
|
143
|
+
* Throws a descriptive error rather than a cryptic `Cannot read properties of
|
|
144
|
+
* undefined` if `params` itself is missing or required keys are absent — the
|
|
145
|
+
* caller (prerenderPages / prerenderApp) catches this and surfaces it as a
|
|
146
|
+
* per-route error result.
|
|
147
|
+
*/
|
|
148
|
+
declare function buildUrlFromParams(pattern: string, params: Record<string, string | string[]> | undefined | null): string;
|
|
138
149
|
/** Map of route patterns to generateStaticParams functions (or null/undefined). */
|
|
139
150
|
type StaticParamsMap = Record<string, ((opts: {
|
|
140
151
|
params: Record<string, string | string[]>;
|
|
@@ -207,4 +218,4 @@ declare function writePrerenderIndex(routes: PrerenderRouteResult[], outDir: str
|
|
|
207
218
|
trailingSlash?: boolean;
|
|
208
219
|
}): void;
|
|
209
220
|
//#endregion
|
|
210
|
-
export { PrerenderResult, PrerenderRouteResult, StaticParamsMap, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
|
|
221
|
+
export { PrerenderResult, PrerenderRouteResult, StaticParamsMap, buildUrlFromParams, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
|
package/dist/build/prerender.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { createValidFileMatcher, findFileWithExtensions } from "../routing/file-matcher.js";
|
|
2
3
|
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
|
|
3
4
|
import { VINEXT_PRERENDER_CACHE_LIFE_HEADER } from "../server/headers.js";
|
|
@@ -17,7 +18,6 @@ import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths
|
|
|
17
18
|
import { startProdServer } from "../server/prod-server.js";
|
|
18
19
|
import { prerenderPoolAvailable, resolvePrerenderPoolSize, startPrerenderServerPool } from "./prerender-server-pool.js";
|
|
19
20
|
import fs from "node:fs";
|
|
20
|
-
import path from "node:path";
|
|
21
21
|
import os from "node:os";
|
|
22
22
|
//#region src/build/prerender.ts
|
|
23
23
|
/**
|
|
@@ -1000,4 +1000,4 @@ function writePrerenderIndex(routes, outDir, options) {
|
|
|
1000
1000
|
fs.writeFileSync(path.join(outDir, "vinext-prerender.json"), JSON.stringify(index, null, 2), "utf-8");
|
|
1001
1001
|
}
|
|
1002
1002
|
//#endregion
|
|
1003
|
-
export { extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
|
|
1003
|
+
export { buildUrlFromParams, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/build/preview-credentials.d.ts
|
|
2
|
+
type PreviewBuildCredentials = {
|
|
3
|
+
id: string;
|
|
4
|
+
signingKey: string;
|
|
5
|
+
encryptionKey: string;
|
|
6
|
+
};
|
|
7
|
+
declare function createPreviewBuildCredentials(): PreviewBuildCredentials;
|
|
8
|
+
declare function getPreviewBuildCredentials(): PreviewBuildCredentials | undefined;
|
|
9
|
+
declare function runWithPreviewBuildCredentials<T>(callback: () => T): T;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { PreviewBuildCredentials, createPreviewBuildCredentials, getPreviewBuildCredentials, runWithPreviewBuildCredentials };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
//#region src/build/preview-credentials.ts
|
|
4
|
+
const previewBuildCredentialsStorage = new AsyncLocalStorage();
|
|
5
|
+
function createPreviewBuildCredentials() {
|
|
6
|
+
return {
|
|
7
|
+
id: randomBytes(16).toString("hex"),
|
|
8
|
+
signingKey: randomBytes(32).toString("hex"),
|
|
9
|
+
encryptionKey: randomBytes(32).toString("hex")
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function getPreviewBuildCredentials() {
|
|
13
|
+
return previewBuildCredentialsStorage.getStore();
|
|
14
|
+
}
|
|
15
|
+
function runWithPreviewBuildCredentials(callback) {
|
|
16
|
+
return previewBuildCredentialsStorage.run(createPreviewBuildCredentials(), callback);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { createPreviewBuildCredentials, getPreviewBuildCredentials, runWithPreviewBuildCredentials };
|
package/dist/build/report.d.ts
CHANGED
|
@@ -130,9 +130,6 @@ declare function formatBuildReport(rows: RouteRow[], routerLabel?: string): stri
|
|
|
130
130
|
/**
|
|
131
131
|
* Scans the project at `root`, classifies all routes, and prints the
|
|
132
132
|
* Next.js-style build report to stdout.
|
|
133
|
-
*
|
|
134
|
-
* `root` must be forward-slash — it is passed to `findDir`. The caller (the
|
|
135
|
-
* `vinext build` entry in cli.ts) normalizes it.
|
|
136
133
|
*/
|
|
137
134
|
declare function printBuildReport(options: {
|
|
138
135
|
root: string;
|
package/dist/build/report.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { findDir } from "../utils/project.js";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import { parseSync } from "vite";
|
|
@@ -415,7 +416,7 @@ function classifyLayoutSegmentConfig(code) {
|
|
|
415
416
|
* API routes (files under pages/api/) are always `api`.
|
|
416
417
|
*/
|
|
417
418
|
function classifyPagesRoute(filePath) {
|
|
418
|
-
if (filePath
|
|
419
|
+
if (toSlash(filePath).includes("/pages/api/")) return { type: "api" };
|
|
419
420
|
let code;
|
|
420
421
|
try {
|
|
421
422
|
code = fs.readFileSync(filePath, "utf8");
|
|
@@ -569,9 +570,6 @@ function formatBuildReport(rows, routerLabel = "app") {
|
|
|
569
570
|
/**
|
|
570
571
|
* Scans the project at `root`, classifies all routes, and prints the
|
|
571
572
|
* Next.js-style build report to stdout.
|
|
572
|
-
*
|
|
573
|
-
* `root` must be forward-slash — it is passed to `findDir`. The caller (the
|
|
574
|
-
* `vinext build` entry in cli.ts) normalizes it.
|
|
575
573
|
*/
|
|
576
574
|
async function printBuildReport(options) {
|
|
577
575
|
const { root } = options;
|
|
@@ -3,13 +3,8 @@ import { PrerenderResult, PrerenderRouteResult } from "./prerender.js";
|
|
|
3
3
|
|
|
4
4
|
//#region src/build/run-prerender.d.ts
|
|
5
5
|
type RunPrerenderOptions = {
|
|
6
|
-
/** Project root directory. */root: string;
|
|
7
|
-
|
|
8
|
-
* Override next.config values. Merged on top of the config loaded from disk.
|
|
9
|
-
* Intended for tests that need to exercise a specific config (e.g. output: 'export')
|
|
10
|
-
* without writing a next.config file.
|
|
11
|
-
*/
|
|
12
|
-
nextConfigOverride?: Partial<ResolvedNextConfig>;
|
|
6
|
+
/** Project root directory. */root: string; /** Fully resolved Next.js config. Loaded from disk when omitted. */
|
|
7
|
+
nextConfig?: ResolvedNextConfig;
|
|
13
8
|
/**
|
|
14
9
|
* Override the path to the Pages Router server bundle.
|
|
15
10
|
* Defaults to `<root>/dist/server/entry.js`.
|
|
@@ -58,10 +53,6 @@ type RunPrerenderOptions = {
|
|
|
58
53
|
declare function assertNoFatalPrerenderRoutes(routes: readonly PrerenderRouteResult[]): void;
|
|
59
54
|
/**
|
|
60
55
|
* Statically generate routes and return the prerender result.
|
|
61
|
-
*
|
|
62
|
-
* `options.root` must be forward-slash — it is passed to `findDir` and flows
|
|
63
|
-
* into the route model. The caller (the `vinext build` entry in cli.ts)
|
|
64
|
-
* normalizes it.
|
|
65
56
|
*/
|
|
66
57
|
declare function runPrerender(options: RunPrerenderOptions): Promise<PrerenderResult | null>;
|
|
67
58
|
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { findDir } from "../utils/project.js";
|
|
2
3
|
import { apiRouter, pagesRouter } from "../routing/pages-router.js";
|
|
3
4
|
import { appRouter } from "../routing/app-router.js";
|
|
@@ -8,7 +9,6 @@ import { rememberCurrentServerEntryImportMtime, startProdServer } from "../serve
|
|
|
8
9
|
import { prerenderApp, prerenderPages, writePrerenderIndex } from "./prerender.js";
|
|
9
10
|
import { injectPregeneratedConcretePaths } from "./inject-pregenerated-paths.js";
|
|
10
11
|
import fs from "node:fs";
|
|
11
|
-
import path from "node:path";
|
|
12
12
|
//#region src/build/run-prerender.ts
|
|
13
13
|
/**
|
|
14
14
|
* Shared prerender runner used by both `vinext build` (cli.ts) and
|
|
@@ -98,10 +98,6 @@ function assertNoFatalPrerenderRoutes(routes) {
|
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
100
|
* Statically generate routes and return the prerender result.
|
|
101
|
-
*
|
|
102
|
-
* `options.root` must be forward-slash — it is passed to `findDir` and flows
|
|
103
|
-
* into the route model. The caller (the `vinext build` entry in cli.ts)
|
|
104
|
-
* normalizes it.
|
|
105
101
|
*/
|
|
106
102
|
async function runPrerender(options) {
|
|
107
103
|
const { root } = options;
|
|
@@ -113,11 +109,7 @@ async function runPrerender(options) {
|
|
|
113
109
|
const manifestDir = path.join(root, "dist", "server");
|
|
114
110
|
const rscBundlePath = options.rscBundlePath ?? path.join(root, "dist", "server", "index.js");
|
|
115
111
|
const serverDir = path.dirname(rscBundlePath);
|
|
116
|
-
const
|
|
117
|
-
const config = options.nextConfigOverride ? {
|
|
118
|
-
...loadedConfig,
|
|
119
|
-
...options.nextConfigOverride
|
|
120
|
-
} : { ...loadedConfig };
|
|
112
|
+
const config = options.nextConfig ? { ...options.nextConfig } : { ...await resolveNextConfig(await loadNextConfig(root), root) };
|
|
121
113
|
const builtBuildId = readBuiltBuildId(serverDir);
|
|
122
114
|
if (builtBuildId) config.buildId = builtBuildId;
|
|
123
115
|
const mode = config.output === "export" ? "export" : "default";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { readJsonFile } from "../utils/safe-json-file.js";
|
|
2
|
-
import path from "node:path";
|
|
3
3
|
//#region src/build/server-manifest.ts
|
|
4
4
|
/**
|
|
5
5
|
* Shared utilities for reading/writing vinext-server.json.
|
|
@@ -9,6 +9,10 @@ type BundleBackfillChunk = {
|
|
|
9
9
|
importedAssets?: Set<string>;
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Realpath with NATIVE separators (backslashes on Windows). Callers apply
|
|
14
|
+
* `toSlash` where the result becomes a module id / manifest key.
|
|
15
|
+
*/
|
|
12
16
|
declare function tryRealpathSync(candidate: string): string | null;
|
|
13
17
|
declare function relativeWithinRoot(root: string, moduleId: string): string | null;
|
|
14
18
|
declare function augmentSsrManifestFromBundle(ssrManifest: Record<string, string[]>, bundle: Record<string, BundleBackfillChunk | {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
1
2
|
import { collapseDuplicateBase, manifestFileWithBase } from "../utils/manifest-paths.js";
|
|
2
3
|
import fs from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
4
|
//#region src/build/ssr-manifest.ts
|
|
5
|
+
/**
|
|
6
|
+
* Realpath with NATIVE separators (backslashes on Windows). Callers apply
|
|
7
|
+
* `toSlash` where the result becomes a module id / manifest key.
|
|
8
|
+
*/
|
|
5
9
|
function tryRealpathSync(candidate) {
|
|
6
10
|
try {
|
|
7
11
|
return fs.realpathSync.native(candidate);
|
|
@@ -13,26 +17,26 @@ function isWindowsAbsolutePath(candidate) {
|
|
|
13
17
|
return /^[a-zA-Z]:[\\/]/.test(candidate) || candidate.startsWith("\\\\");
|
|
14
18
|
}
|
|
15
19
|
function relativeWithinRoot(root, moduleId) {
|
|
16
|
-
const relativeId =
|
|
20
|
+
const relativeId = isWindowsAbsolutePath(root) || isWindowsAbsolutePath(moduleId) ? path.win32.relative(root, moduleId) : path.relative(root, moduleId);
|
|
17
21
|
if (!relativeId || relativeId === ".." || relativeId.startsWith("../")) return null;
|
|
18
22
|
return relativeId;
|
|
19
23
|
}
|
|
20
24
|
function normalizeManifestModuleId(moduleId, root) {
|
|
21
|
-
const normalizedId = moduleId
|
|
25
|
+
const normalizedId = toSlash(moduleId);
|
|
22
26
|
if (normalizedId.startsWith("\0")) return normalizedId;
|
|
23
27
|
if (normalizedId.startsWith("node_modules/") || normalizedId.includes("/node_modules/")) return normalizedId;
|
|
24
28
|
if (!isWindowsAbsolutePath(moduleId) && !path.isAbsolute(moduleId)) {
|
|
25
29
|
if (!normalizedId.startsWith(".") && !normalizedId.includes("../")) return normalizedId;
|
|
26
30
|
}
|
|
27
|
-
const rootCandidates = new Set([root]);
|
|
31
|
+
const rootCandidates = /* @__PURE__ */ new Set([root]);
|
|
28
32
|
const realRoot = tryRealpathSync(root);
|
|
29
|
-
if (realRoot) rootCandidates.add(realRoot);
|
|
33
|
+
if (realRoot) rootCandidates.add(toSlash(realRoot));
|
|
30
34
|
const moduleCandidates = /* @__PURE__ */ new Set();
|
|
31
35
|
if (isWindowsAbsolutePath(moduleId) || path.isAbsolute(moduleId)) moduleCandidates.add(moduleId);
|
|
32
36
|
else moduleCandidates.add(path.resolve(root, moduleId));
|
|
33
37
|
for (const candidate of moduleCandidates) {
|
|
34
38
|
const realCandidate = tryRealpathSync(candidate);
|
|
35
|
-
if (realCandidate) moduleCandidates.add(realCandidate);
|
|
39
|
+
if (realCandidate) moduleCandidates.add(toSlash(realCandidate));
|
|
36
40
|
}
|
|
37
41
|
for (const rootCandidate of rootCandidates) for (const moduleCandidate of moduleCandidates) {
|
|
38
42
|
const relativeId = relativeWithinRoot(rootCandidate, moduleCandidate);
|