vinext 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/client-build-config.d.ts +11 -2
- package/dist/build/client-build-config.js +17 -6
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +42 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/pages-router-link-navigation.d.ts +33 -7
- package/dist/client/pages-router-link-navigation.js +32 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/vinext-next-data.js +2 -0
- package/dist/client/window-next.d.ts +2 -1
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -1
- package/dist/config/config-matchers.js +87 -16
- package/dist/config/next-config.d.ts +46 -4
- package/dist/config/next-config.js +147 -48
- package/dist/config/tsconfig-paths.js +14 -1
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +200 -112
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +65 -5
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +66 -20
- package/dist/entries/pages-server-entry.js +47 -31
- package/dist/index.js +417 -102
- package/dist/plugins/dynamic-preload-metadata.js +2 -4
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/fonts.js +5 -4
- package/dist/plugins/optimize-imports.d.ts +2 -1
- package/dist/plugins/optimize-imports.js +11 -9
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/strip-server-exports.d.ts +9 -7
- package/dist/plugins/strip-server-exports.js +493 -46
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/routing/app-route-graph.d.ts +2 -1
- package/dist/routing/app-route-graph.js +46 -16
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +22 -1
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +20 -11
- package/dist/server/app-browser-entry.js +175 -91
- package/dist/server/app-browser-error.d.ts +10 -6
- package/dist/server/app-browser-error.js +43 -8
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +5 -3
- package/dist/server/app-browser-navigation-controller.js +23 -2
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.d.ts +1 -1
- package/dist/server/app-browser-state.js +19 -11
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.d.ts +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -0
- package/dist/server/app-fallback-renderer.js +3 -1
- package/dist/server/app-optimistic-routing.js +2 -2
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +27 -14
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +62 -1
- package/dist/server/app-page-dispatch.d.ts +26 -0
- package/dist/server/app-page-dispatch.js +149 -92
- package/dist/server/app-page-element-builder.d.ts +1 -0
- package/dist/server/app-page-element-builder.js +5 -2
- package/dist/server/app-page-execution.d.ts +6 -1
- package/dist/server/app-page-execution.js +21 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +12 -1
- package/dist/server/app-page-render.js +42 -4
- package/dist/server/app-page-request.d.ts +2 -0
- package/dist/server/app-page-request.js +2 -1
- package/dist/server/app-page-route-wiring.d.ts +3 -1
- package/dist/server/app-page-route-wiring.js +14 -5
- package/dist/server/app-page-stream.d.ts +15 -3
- package/dist/server/app-page-stream.js +11 -5
- package/dist/server/app-pages-bridge.d.ts +23 -1
- package/dist/server/app-pages-bridge.js +26 -17
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +28 -0
- package/dist/server/app-rsc-handler.js +195 -59
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +8 -2
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +84 -39
- package/dist/server/before-interactive-head.d.ts +17 -0
- package/dist/server/before-interactive-head.js +35 -0
- package/dist/server/cache-control.js +4 -0
- package/dist/server/csp.js +1 -4
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +321 -83
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/middleware-matcher.js +12 -3
- package/dist/server/middleware-runtime.d.ts +3 -4
- package/dist/server/middleware-runtime.js +2 -0
- package/dist/server/navigation-planner.d.ts +135 -41
- package/dist/server/navigation-planner.js +138 -0
- package/dist/server/navigation-trace.d.ts +9 -1
- package/dist/server/navigation-trace.js +9 -1
- package/dist/server/operation-token.d.ts +40 -0
- package/dist/server/operation-token.js +85 -0
- package/dist/server/pages-api-route.d.ts +6 -0
- package/dist/server/pages-api-route.js +13 -2
- package/dist/server/pages-asset-tags.d.ts +2 -1
- package/dist/server/pages-asset-tags.js +6 -2
- package/dist/server/pages-data-route.d.ts +9 -2
- package/dist/server/pages-data-route.js +18 -6
- package/dist/server/pages-dev-module-url.d.ts +4 -0
- package/dist/server/pages-dev-module-url.js +15 -0
- package/dist/server/pages-document-initial-props.d.ts +4 -15
- package/dist/server/pages-document-initial-props.js +27 -56
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-i18n.js +2 -2
- package/dist/server/pages-node-compat.js +2 -2
- package/dist/server/pages-page-data.d.ts +11 -2
- package/dist/server/pages-page-data.js +207 -34
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +62 -23
- package/dist/server/pages-page-response.d.ts +4 -1
- package/dist/server/pages-page-response.js +11 -8
- package/dist/server/pages-readiness.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +8 -7
- package/dist/server/pages-request-pipeline.js +126 -47
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +3 -1
- package/dist/server/prod-server.js +50 -13
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/server/static-file-cache.js +16 -4
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/before-interactive-context.d.ts +14 -3
- package/dist/shims/cache-runtime.js +3 -2
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/document.d.ts +15 -20
- package/dist/shims/document.js +5 -8
- package/dist/shims/dynamic-preload-chunks.js +6 -4
- package/dist/shims/error-boundary.d.ts +2 -0
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +3 -2
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +45 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/headers.js +29 -4
- package/dist/shims/image.js +9 -2
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.js +8 -17
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
- package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +47 -19
- package/dist/shims/metadata.js +4 -4
- package/dist/shims/navigation.d.ts +8 -2
- package/dist/shims/navigation.js +63 -31
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +18 -3
- package/dist/shims/router.js +512 -142
- package/dist/shims/script.js +8 -4
- package/dist/shims/server.d.ts +16 -1
- package/dist/shims/server.js +44 -12
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/has-trailing-comma.d.ts +24 -0
- package/dist/utils/has-trailing-comma.js +62 -0
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +7 -1
- package/dist/utils/path.js +9 -1
- package/dist/utils/text-stream.d.ts +1 -1
- package/dist/utils/text-stream.js +2 -2
- package/dist/utils/vite-version.d.ts +12 -1
- package/dist/utils/vite-version.js +9 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
package/dist/deploy.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ensureESModule as ensureESModule$1, renameCJSConfigs as renameCJSConfigs$1 } from "./utils/project.js";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
2
3
|
|
|
3
4
|
//#region src/deploy.d.ts
|
|
4
5
|
type DeployOptions = {
|
|
@@ -151,21 +152,39 @@ type WranglerDeployArgs = {
|
|
|
151
152
|
args: string[];
|
|
152
153
|
env: string | undefined;
|
|
153
154
|
};
|
|
155
|
+
declare function validateWranglerEnvName(env: string): string;
|
|
154
156
|
declare function buildWranglerDeployArgs(options: Pick<DeployOptions, "preview" | "env">): WranglerDeployArgs;
|
|
155
157
|
/**
|
|
156
|
-
* Resolve
|
|
158
|
+
* Resolve Wrangler's JavaScript CLI entrypoint in node_modules.
|
|
157
159
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
+
* Invoking the JavaScript file through `process.execPath` avoids the `.cmd`
|
|
161
|
+
* shim and command shell that package managers create on Windows.
|
|
162
|
+
*/
|
|
163
|
+
declare function resolveWranglerBin(root: string, resolvePackageJson?: (root: string) => string | null): string;
|
|
164
|
+
declare function buildNodeCliInvocation(scriptPath: string, args: string[], nodeExecutable?: string): {
|
|
165
|
+
file: string;
|
|
166
|
+
args: string[];
|
|
167
|
+
};
|
|
168
|
+
declare function buildWranglerInvocation(root: string, options: Pick<DeployOptions, "preview" | "env">, nodeExecutable?: string): {
|
|
169
|
+
file: string;
|
|
170
|
+
args: string[];
|
|
171
|
+
env: string | undefined;
|
|
172
|
+
};
|
|
173
|
+
declare function runWranglerDeploy(root: string, options: Pick<DeployOptions, "preview" | "env">, execute?: typeof execFileSync): string;
|
|
174
|
+
/**
|
|
175
|
+
* Read the prerender manifest and inject pregenerated concrete paths into the
|
|
176
|
+
* App Router Worker bundle so the PPR fallback-shell guard is populated at
|
|
177
|
+
* module init time without calling `seedMemoryCacheFromPrerender`.
|
|
178
|
+
*
|
|
179
|
+
* The paths are injected as `globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS`
|
|
180
|
+
* wrapped in replaceable marker comments, and consumed by
|
|
181
|
+
* `initPregeneratedPathsFromGlobals` in the generated RSC entry.
|
|
160
182
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* bare-name shebang file fails with ENOENT even though the file exists. So on
|
|
165
|
-
* Windows we prefer the `.CMD` shim and only fall back to the bare name for a
|
|
166
|
-
* clearer error message if neither is present.
|
|
183
|
+
* Idempotent: repeated calls strip the previous injection before writing the
|
|
184
|
+
* new one. If the manifest is missing, corrupt, or empty, any prior injection
|
|
185
|
+
* is stripped and nothing new is written — failing closed to empty.
|
|
167
186
|
*/
|
|
168
|
-
declare function
|
|
187
|
+
declare function injectPregeneratedConcretePaths(root: string): void;
|
|
169
188
|
declare function deploy(options: DeployOptions): Promise<void>;
|
|
170
189
|
//#endregion
|
|
171
|
-
export { buildWranglerDeployArgs, deploy, detectProject, ensureESModule, formatMissingCacheAdapterError, formatMissingCloudflarePluginError, generateAppRouterViteConfig, generateAppRouterWorkerEntry, generatePagesRouterViteConfig, generatePagesRouterWorkerEntry, generateWranglerConfig, getFilesToGenerate, getMissingDeps, hasWranglerConfig, isPackageResolvable, parseDeployArgs, renameCJSConfigs, resolveWranglerBin, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, withCloudflareEnv, workerEntryHasCacheHandler };
|
|
190
|
+
export { buildNodeCliInvocation, buildWranglerDeployArgs, buildWranglerInvocation, deploy, detectProject, ensureESModule, formatMissingCacheAdapterError, formatMissingCloudflarePluginError, generateAppRouterViteConfig, generateAppRouterWorkerEntry, generatePagesRouterViteConfig, generatePagesRouterWorkerEntry, generateWranglerConfig, getFilesToGenerate, getMissingDeps, hasWranglerConfig, injectPregeneratedConcretePaths, isPackageResolvable, parseDeployArgs, renameCJSConfigs, resolveWranglerBin, runWranglerDeploy, validateWranglerEnvName, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, withCloudflareEnv, workerEntryHasCacheHandler };
|
package/dist/deploy.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { detectPackageManager as detectPackageManager$1, ensureESModule as ensureESModule$1, findInNodeModules, renameCJSConfigs as renameCJSConfigs$1 } from "./utils/project.js";
|
|
2
2
|
import { parsePositiveIntegerArg } from "./cli-args.js";
|
|
3
|
+
import { escapeRegExp } from "./utils/regex.js";
|
|
3
4
|
import { loadNextConfig, resolveNextConfig } from "./config/next-config.js";
|
|
4
5
|
import { getReactUpgradeDeps } from "./init.js";
|
|
5
6
|
import { runTPR } from "./cloudflare/tpr.js";
|
|
7
|
+
import { buildPregeneratedConcretePathTable, readPrerenderManifest } from "./server/prerender-manifest.js";
|
|
6
8
|
import { runPrerender } from "./build/run-prerender.js";
|
|
7
9
|
import { loadDotenv } from "./config/dotenv.js";
|
|
8
10
|
import { createRequire } from "node:module";
|
|
@@ -123,14 +125,33 @@ function detectProject(root) {
|
|
|
123
125
|
} catch {}
|
|
124
126
|
let projectName = path.basename(root);
|
|
125
127
|
if (pkg?.name && typeof pkg.name === "string") projectName = pkg.name.replace(/^@[^/]+\//, "").toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
126
|
-
const hasISR = detectISR(root, isAppRouter);
|
|
127
128
|
const hasTypeModule = pkg?.type === "module";
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
let hasISR = false;
|
|
130
|
+
let hasMDX = detectMDXFromConfig(root);
|
|
131
|
+
if (isAppRouter) {
|
|
132
|
+
const appDir = resolveProjectDir(root, "app");
|
|
133
|
+
if (appDir) {
|
|
134
|
+
const found = scanTreeForDetection(appDir, {
|
|
135
|
+
isr: true,
|
|
136
|
+
mdx: !hasMDX
|
|
137
|
+
});
|
|
138
|
+
hasISR = found.isr;
|
|
139
|
+
hasMDX = hasMDX || found.mdx;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (hasPages && !hasMDX) {
|
|
143
|
+
const pagesDir = resolveProjectDir(root, "pages");
|
|
144
|
+
if (pagesDir) hasMDX = scanTreeForDetection(pagesDir, {
|
|
145
|
+
isr: false,
|
|
146
|
+
mdx: true
|
|
147
|
+
}).mdx;
|
|
148
|
+
}
|
|
149
|
+
const allDeps = {
|
|
130
150
|
...pkg?.dependencies,
|
|
131
151
|
...pkg?.devDependencies
|
|
132
152
|
};
|
|
133
|
-
const
|
|
153
|
+
const hasCodeHike = "codehike" in allDeps;
|
|
154
|
+
const nativeModulesToStub = detectNativeModules(allDeps);
|
|
134
155
|
return {
|
|
135
156
|
root,
|
|
136
157
|
isAppRouter,
|
|
@@ -149,35 +170,69 @@ function detectProject(root) {
|
|
|
149
170
|
nativeModulesToStub
|
|
150
171
|
};
|
|
151
172
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
/** Matches `export const revalidate = …` (ISR opt-in) in App Router source. */
|
|
174
|
+
const ISR_REVALIDATE_PATTERN = /export\s+const\s+revalidate\s*=/;
|
|
175
|
+
/** Source extensions whose contents are scanned for the ISR pattern. */
|
|
176
|
+
const ISR_SCANNABLE_EXTENSION = /\.(ts|tsx|js|jsx)$/;
|
|
177
|
+
/**
|
|
178
|
+
* Resolve a project subdirectory (`app`/`pages`), preferring the root-level
|
|
179
|
+
* location and falling back to the `src/` variant. Returns null when neither
|
|
180
|
+
* exists.
|
|
181
|
+
*/
|
|
182
|
+
function resolveProjectDir(root, name) {
|
|
183
|
+
const rootDir = path.join(root, name);
|
|
184
|
+
if (fs.existsSync(rootDir)) return rootDir;
|
|
185
|
+
const srcDir = path.join(root, "src", name);
|
|
186
|
+
if (fs.existsSync(srcDir)) return srcDir;
|
|
187
|
+
return null;
|
|
162
188
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Recursively walk `dir` once, evaluating the requested detection predicates
|
|
191
|
+
* per entry. Each flag short-circuits independently: an `.mdx` file sets `mdx`;
|
|
192
|
+
* a scannable source file containing `export const revalidate` sets `isr`. The
|
|
193
|
+
* walk stops as soon as every requested flag is satisfied, so callers that only
|
|
194
|
+
* want one signal don't pay for the other.
|
|
195
|
+
*
|
|
196
|
+
* Replaces the previous pair of single-purpose recursive walkers
|
|
197
|
+
* (`scanDirForPattern` + `scanDirForExtension`) that traversed the same tree
|
|
198
|
+
* twice. Detection semantics are unchanged: same dirs skipped (dotfiles,
|
|
199
|
+
* node_modules), same extension and content tests.
|
|
200
|
+
*/
|
|
201
|
+
function scanTreeForDetection(dir, want) {
|
|
202
|
+
const found = {
|
|
203
|
+
isr: false,
|
|
204
|
+
mdx: false
|
|
205
|
+
};
|
|
206
|
+
const walk = (current) => {
|
|
207
|
+
let entries;
|
|
208
|
+
try {
|
|
209
|
+
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
210
|
+
} catch {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
for (const entry of entries) {
|
|
214
|
+
if ((!want.isr || found.isr) && (!want.mdx || found.mdx)) return;
|
|
215
|
+
const fullPath = path.join(current, entry.name);
|
|
216
|
+
if (entry.isDirectory()) {
|
|
217
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
218
|
+
walk(fullPath);
|
|
219
|
+
} else if (entry.isFile()) {
|
|
220
|
+
if (want.mdx && !found.mdx && entry.name.endsWith(".mdx")) found.mdx = true;
|
|
221
|
+
if (want.isr && !found.isr && ISR_SCANNABLE_EXTENSION.test(entry.name)) try {
|
|
222
|
+
if (ISR_REVALIDATE_PATTERN.test(fs.readFileSync(fullPath, "utf-8"))) found.isr = true;
|
|
223
|
+
} catch {}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
walk(dir);
|
|
228
|
+
return found;
|
|
175
229
|
}
|
|
176
230
|
/**
|
|
177
|
-
* Detect
|
|
178
|
-
*
|
|
231
|
+
* Detect MDX usage declared in next.config (`pageExtensions` including "mdx" or
|
|
232
|
+
* an `@next/mdx` import). Filesystem `.mdx` detection is handled separately by
|
|
233
|
+
* the shared app/pages tree walk in `detectProject`.
|
|
179
234
|
*/
|
|
180
|
-
function
|
|
235
|
+
function detectMDXFromConfig(root) {
|
|
181
236
|
for (const f of [
|
|
182
237
|
"next.config.ts",
|
|
183
238
|
"next.config.mts",
|
|
@@ -191,26 +246,6 @@ function detectMDX(root, isAppRouter, hasPages) {
|
|
|
191
246
|
if (/pageExtensions.*mdx/i.test(content) || /@next\/mdx/.test(content)) return true;
|
|
192
247
|
} catch {}
|
|
193
248
|
}
|
|
194
|
-
const dirs = [];
|
|
195
|
-
if (isAppRouter) {
|
|
196
|
-
const appDir = fs.existsSync(path.join(root, "app")) ? path.join(root, "app") : path.join(root, "src", "app");
|
|
197
|
-
dirs.push(appDir);
|
|
198
|
-
}
|
|
199
|
-
if (hasPages) {
|
|
200
|
-
const pagesDir = fs.existsSync(path.join(root, "pages")) ? path.join(root, "pages") : path.join(root, "src", "pages");
|
|
201
|
-
dirs.push(pagesDir);
|
|
202
|
-
}
|
|
203
|
-
for (const dir of dirs) if (fs.existsSync(dir) && scanDirForExtension(dir, ".mdx")) return true;
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
|
-
function scanDirForExtension(dir, ext) {
|
|
207
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
208
|
-
for (const entry of entries) {
|
|
209
|
-
const fullPath = path.join(dir, entry.name);
|
|
210
|
-
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
211
|
-
if (scanDirForExtension(fullPath, ext)) return true;
|
|
212
|
-
} else if (entry.isFile() && entry.name.endsWith(ext)) return true;
|
|
213
|
-
}
|
|
214
249
|
return false;
|
|
215
250
|
}
|
|
216
251
|
/** Known native Node modules that can't run in Workers */
|
|
@@ -222,21 +257,12 @@ const NATIVE_MODULES_TO_STUB = [
|
|
|
222
257
|
"sharp"
|
|
223
258
|
];
|
|
224
259
|
/**
|
|
225
|
-
* Detect native Node modules in
|
|
260
|
+
* Detect native Node modules in the project's merged dependency map that need
|
|
261
|
+
* stubbing for Workers. Accepts the already-built `allDeps` (dependencies +
|
|
262
|
+
* devDependencies) so package.json is not re-read or re-parsed.
|
|
226
263
|
*/
|
|
227
|
-
function detectNativeModules(
|
|
228
|
-
|
|
229
|
-
if (!fs.existsSync(pkgPath)) return [];
|
|
230
|
-
try {
|
|
231
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
232
|
-
const allDeps = {
|
|
233
|
-
...pkg.dependencies,
|
|
234
|
-
...pkg.devDependencies
|
|
235
|
-
};
|
|
236
|
-
return NATIVE_MODULES_TO_STUB.filter((mod) => mod in allDeps);
|
|
237
|
-
} catch {
|
|
238
|
-
return [];
|
|
239
|
-
}
|
|
264
|
+
function detectNativeModules(allDeps) {
|
|
265
|
+
return NATIVE_MODULES_TO_STUB.filter((mod) => mod in allDeps);
|
|
240
266
|
}
|
|
241
267
|
/** @see {@link _ensureESModule} */
|
|
242
268
|
const ensureESModule = ensureESModule$1;
|
|
@@ -280,6 +306,17 @@ import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isI
|
|
|
280
306
|
import type { ImageConfig } from "vinext/server/image-optimization";
|
|
281
307
|
import handler from "vinext/server/app-router-entry";
|
|
282
308
|
|
|
309
|
+
const imageConfig: ImageConfig = {
|
|
310
|
+
deviceSizes: JSON.parse(
|
|
311
|
+
process.env.__VINEXT_IMAGE_DEVICE_SIZES ?? JSON.stringify(DEFAULT_DEVICE_SIZES),
|
|
312
|
+
),
|
|
313
|
+
imageSizes: JSON.parse(
|
|
314
|
+
process.env.__VINEXT_IMAGE_SIZES ?? JSON.stringify(DEFAULT_IMAGE_SIZES),
|
|
315
|
+
),
|
|
316
|
+
qualities: JSON.parse(process.env.__VINEXT_IMAGE_QUALITIES ?? "null") ?? undefined,
|
|
317
|
+
dangerouslyAllowSVG: process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_SVG === "true",
|
|
318
|
+
};
|
|
319
|
+
|
|
283
320
|
interface Env {
|
|
284
321
|
ASSETS: Fetcher;
|
|
285
322
|
IMAGES: {
|
|
@@ -310,14 +347,17 @@ export default {
|
|
|
310
347
|
// The parseImageParams validation inside handleImageOptimization
|
|
311
348
|
// normalizes backslashes and validates the origin hasn't changed.
|
|
312
349
|
if (isImageOptimizationPath(url.pathname)) {
|
|
313
|
-
const allowedWidths = [
|
|
350
|
+
const allowedWidths = [
|
|
351
|
+
...(imageConfig.deviceSizes ?? DEFAULT_DEVICE_SIZES),
|
|
352
|
+
...(imageConfig.imageSizes ?? DEFAULT_IMAGE_SIZES),
|
|
353
|
+
];
|
|
314
354
|
return handleImageOptimization(request, {
|
|
315
355
|
fetchAsset: (path) => env.ASSETS.fetch(new Request(new URL(path, request.url))),
|
|
316
356
|
transformImage: async (body, { width, format, quality }) => {
|
|
317
357
|
const result = await env.IMAGES.input(body).transform(width > 0 ? { width } : {}).output({ format, quality });
|
|
318
358
|
return result.response();
|
|
319
359
|
},
|
|
320
|
-
}, allowedWidths);
|
|
360
|
+
}, allowedWidths, imageConfig);
|
|
321
361
|
}
|
|
322
362
|
|
|
323
363
|
// Delegate everything else to vinext, forwarding ctx so that
|
|
@@ -334,17 +374,17 @@ function generatePagesRouterWorkerEntry() {
|
|
|
334
374
|
* Cloudflare Worker entry point -- auto-generated by vinext deploy.
|
|
335
375
|
* Edit freely or delete to regenerate on next deploy.
|
|
336
376
|
*/
|
|
337
|
-
import { runPagesRequest, wrapMiddlewareWithBasePath } from "vinext/server/pages-request-pipeline";
|
|
377
|
+
import { fetchWorkerFilesystemRoute, runPagesRequest, wrapMiddlewareWithBasePath } from "vinext/server/pages-request-pipeline";
|
|
338
378
|
import type { PagesPipelineDeps } from "vinext/server/pages-request-pipeline";
|
|
339
379
|
import { handleImageOptimization, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath } from "vinext/server/image-optimization";
|
|
340
380
|
import type { ImageConfig } from "vinext/server/image-optimization";
|
|
341
|
-
import { cloneRequestWithHeaders, filterInternalHeaders, isOpenRedirectShaped } from "vinext/server/request-pipeline";
|
|
381
|
+
import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, isOpenRedirectShaped } from "vinext/server/request-pipeline";
|
|
342
382
|
import { notFoundStaticAssetResponse } from "vinext/server/http-error-responses";
|
|
343
383
|
import { assetPrefixPathname, isNextStaticPath } from "vinext/utils/asset-prefix";
|
|
344
384
|
import { hasBasePath, stripBasePath } from "vinext/utils/base-path";
|
|
345
385
|
|
|
346
386
|
// @ts-expect-error -- virtual module resolved by vinext at build time
|
|
347
|
-
import { renderPage, handleApiRoute, runMiddleware, vinextConfig, matchPageRoute } from "virtual:vinext-server-entry";
|
|
387
|
+
import { renderPage, handleApiRoute, runMiddleware, normalizeDataRequest, vinextConfig, matchPageRoute } from "virtual:vinext-server-entry";
|
|
348
388
|
// @ts-expect-error -- virtual module resolved by vinext at build time
|
|
349
389
|
import { registerConfiguredCacheAdapters } from "virtual:vinext-cache-adapters";
|
|
350
390
|
|
|
@@ -373,6 +413,7 @@ const configRedirects = vinextConfig?.redirects ?? [];
|
|
|
373
413
|
const configRewrites = vinextConfig?.rewrites ?? { beforeFiles: [], afterFiles: [], fallback: [] };
|
|
374
414
|
const configHeaders = vinextConfig?.headers ?? [];
|
|
375
415
|
const imageConfig: ImageConfig | undefined = vinextConfig?.images ? {
|
|
416
|
+
qualities: vinextConfig.images.qualities,
|
|
376
417
|
dangerouslyAllowSVG: vinextConfig.images.dangerouslyAllowSVG,
|
|
377
418
|
dangerouslyAllowLocalIP: vinextConfig.images.dangerouslyAllowLocalIP,
|
|
378
419
|
contentDispositionType: vinextConfig.images.contentDispositionType,
|
|
@@ -407,11 +448,6 @@ export default {
|
|
|
407
448
|
return notFoundStaticAssetResponse();
|
|
408
449
|
}
|
|
409
450
|
|
|
410
|
-
// Capture x-nextjs-data before filterInternalHeaders strips it -- the
|
|
411
|
-
// middleware redirect protocol needs to know whether the inbound request
|
|
412
|
-
// was a _next/data fetch to emit x-nextjs-redirect instead of a 3xx.
|
|
413
|
-
const isDataRequest = request.headers.get("x-nextjs-data") === "1";
|
|
414
|
-
|
|
415
451
|
// Strip internal headers from inbound requests so they cannot be
|
|
416
452
|
// forged to influence routing or impersonate internal state.
|
|
417
453
|
// Request.headers is immutable in Workers, so build a clean copy.
|
|
@@ -430,15 +466,26 @@ export default {
|
|
|
430
466
|
if (stripped !== pathname) {
|
|
431
467
|
const strippedUrl = new URL(request.url);
|
|
432
468
|
strippedUrl.pathname = stripped;
|
|
433
|
-
request =
|
|
469
|
+
request = cloneRequestWithUrl(request, strippedUrl.toString());
|
|
434
470
|
pathname = stripped;
|
|
435
471
|
}
|
|
436
472
|
}
|
|
437
473
|
|
|
474
|
+
const dataNorm = normalizeDataRequest(request);
|
|
475
|
+
if (dataNorm.notFoundResponse) return dataNorm.notFoundResponse;
|
|
476
|
+
const isDataReq = dataNorm.isDataReq;
|
|
477
|
+
if (isDataReq) {
|
|
478
|
+
request = dataNorm.request;
|
|
479
|
+
pathname = dataNorm.normalizedPathname;
|
|
480
|
+
}
|
|
481
|
+
|
|
438
482
|
// ── Image optimization via Cloudflare Images binding ──────────
|
|
439
483
|
// Checked after basePath stripping so /<basePath>/_next/image works.
|
|
440
484
|
if (isImageOptimizationPath(pathname)) {
|
|
441
|
-
const allowedWidths = [
|
|
485
|
+
const allowedWidths = [
|
|
486
|
+
...(vinextConfig?.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES),
|
|
487
|
+
...(vinextConfig?.images?.imageSizes ?? DEFAULT_IMAGE_SIZES),
|
|
488
|
+
];
|
|
442
489
|
return handleImageOptimization(request, {
|
|
443
490
|
fetchAsset: (path) => env.ASSETS.fetch(new Request(new URL(path, request.url))),
|
|
444
491
|
transformImage: async (body, { width, format, quality }) => {
|
|
@@ -460,12 +507,8 @@ export default {
|
|
|
460
507
|
configRewrites,
|
|
461
508
|
configHeaders,
|
|
462
509
|
hadBasePath,
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
// only for renderPage options and shouldDeferErrorPageOnMiss -- false
|
|
466
|
-
// is correct here.
|
|
467
|
-
isDataReq: false,
|
|
468
|
-
isDataRequest,
|
|
510
|
+
isDataReq,
|
|
511
|
+
isDataRequest: isDataReq,
|
|
469
512
|
ctx,
|
|
470
513
|
matchPageRoute: typeof matchPageRoute === "function" ? matchPageRoute : null,
|
|
471
514
|
// Pass the original (pre-basePath-stripping) URL to middleware so that
|
|
@@ -483,6 +526,14 @@ export default {
|
|
|
483
526
|
handleApi: typeof handleApiRoute === "function"
|
|
484
527
|
? (req, apiUrl) => handleApiRoute(req, apiUrl, ctx)
|
|
485
528
|
: null,
|
|
529
|
+
serveFilesystemRoute: async (requestPathname, _stagedHeaders, phase) => {
|
|
530
|
+
return fetchWorkerFilesystemRoute(
|
|
531
|
+
request,
|
|
532
|
+
requestPathname,
|
|
533
|
+
phase,
|
|
534
|
+
(assetRequest) => env.ASSETS.fetch(assetRequest),
|
|
535
|
+
);
|
|
536
|
+
},
|
|
486
537
|
};
|
|
487
538
|
|
|
488
539
|
const result = await runPagesRequest(request, deps);
|
|
@@ -797,58 +848,97 @@ async function runBuild(info, env) {
|
|
|
797
848
|
await (await createBuilder({ root: info.root })).buildApp();
|
|
798
849
|
});
|
|
799
850
|
}
|
|
851
|
+
function validateWranglerEnvName(env) {
|
|
852
|
+
if (env.includes("\0")) throw new Error("Wrangler environment names cannot contain null bytes.");
|
|
853
|
+
return env;
|
|
854
|
+
}
|
|
800
855
|
function buildWranglerDeployArgs(options) {
|
|
801
856
|
const args = ["deploy"];
|
|
802
857
|
const env = options.env || (options.preview ? "preview" : void 0);
|
|
803
|
-
if (env) args.push("--env", env);
|
|
858
|
+
if (env) args.push("--env", validateWranglerEnvName(env));
|
|
804
859
|
return {
|
|
805
860
|
args,
|
|
806
861
|
env
|
|
807
862
|
};
|
|
808
863
|
}
|
|
809
864
|
/**
|
|
810
|
-
* Resolve
|
|
865
|
+
* Resolve Wrangler's JavaScript CLI entrypoint in node_modules.
|
|
811
866
|
*
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
* On Windows, `node_modules/.bin/` contains both a Unix shebang script (no
|
|
816
|
-
* extension) and a `.CMD` shim. Node's `execFileSync` uses CreateProcess(),
|
|
817
|
-
* which only resolves PATHEXT extensions (`.cmd`, `.exe`, ...) — spawning the
|
|
818
|
-
* bare-name shebang file fails with ENOENT even though the file exists. So on
|
|
819
|
-
* Windows we prefer the `.CMD` shim and only fall back to the bare name for a
|
|
820
|
-
* clearer error message if neither is present.
|
|
867
|
+
* Invoking the JavaScript file through `process.execPath` avoids the `.cmd`
|
|
868
|
+
* shim and command shell that package managers create on Windows.
|
|
821
869
|
*/
|
|
822
|
-
function resolveWranglerBin(root,
|
|
823
|
-
|
|
824
|
-
".
|
|
825
|
-
|
|
826
|
-
".
|
|
827
|
-
] : [".bin/wrangler"];
|
|
828
|
-
for (const candidate of candidates) {
|
|
829
|
-
const found = findInNodeModules(root, candidate);
|
|
830
|
-
if (found) return found;
|
|
870
|
+
function resolveWranglerBin(root, resolvePackageJson = (projectRoot) => {
|
|
871
|
+
try {
|
|
872
|
+
return createRequire(path.join(projectRoot, "package.json")).resolve("wrangler/package.json");
|
|
873
|
+
} catch {
|
|
874
|
+
return findInNodeModules(projectRoot, "wrangler/package.json");
|
|
831
875
|
}
|
|
832
|
-
|
|
876
|
+
}) {
|
|
877
|
+
const packageJsonPath = resolvePackageJson(root);
|
|
878
|
+
if (packageJsonPath) {
|
|
879
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
880
|
+
const bin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.wrangler;
|
|
881
|
+
if (bin) return path.resolve(path.dirname(packageJsonPath), bin);
|
|
882
|
+
}
|
|
883
|
+
return path.join(root, "node_modules", "wrangler", "bin", "wrangler.js");
|
|
833
884
|
}
|
|
834
|
-
function
|
|
885
|
+
function buildNodeCliInvocation(scriptPath, args, nodeExecutable = process.execPath) {
|
|
886
|
+
return {
|
|
887
|
+
file: nodeExecutable,
|
|
888
|
+
args: [scriptPath, ...args]
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
function buildWranglerInvocation(root, options, nodeExecutable = process.execPath) {
|
|
835
892
|
const wranglerBin = resolveWranglerBin(root);
|
|
893
|
+
const { args, env } = buildWranglerDeployArgs(options);
|
|
894
|
+
return {
|
|
895
|
+
...buildNodeCliInvocation(wranglerBin, args, nodeExecutable),
|
|
896
|
+
env
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
function runWranglerDeploy(root, options, execute = execFileSync) {
|
|
836
900
|
const execOpts = {
|
|
837
901
|
cwd: root,
|
|
838
902
|
stdio: "pipe",
|
|
839
903
|
encoding: "utf-8",
|
|
840
|
-
shell:
|
|
904
|
+
shell: false
|
|
841
905
|
};
|
|
842
|
-
const { args, env } =
|
|
906
|
+
const { file, args, env } = buildWranglerInvocation(root, options);
|
|
843
907
|
if (env) console.log(`\n Deploying to env: ${env}...`);
|
|
844
908
|
else console.log("\n Deploying to production...");
|
|
845
|
-
const output =
|
|
909
|
+
const output = execute(file, args, execOpts);
|
|
846
910
|
const urlMatch = output.match(/https:\/\/[^\s]+\.workers\.dev[^\s]*/);
|
|
847
911
|
const deployedUrl = urlMatch ? urlMatch[0] : null;
|
|
848
912
|
if (output.trim()) for (const line of output.trim().split("\n")) console.log(` ${line}`);
|
|
849
913
|
return deployedUrl ?? "(URL not detected in wrangler output)";
|
|
850
914
|
}
|
|
915
|
+
const VINEXT_PREGEN_START = "/* __VINEXT_PREGENERATED_CONCRETE_PATHS_START__ */";
|
|
916
|
+
const VINEXT_PREGEN_END = "/* __VINEXT_PREGENERATED_CONCRETE_PATHS_END__ */";
|
|
917
|
+
const VINEXT_PREGEN_RE = new RegExp(`${escapeRegExp(VINEXT_PREGEN_START)}[\\s\\S]*?${escapeRegExp(VINEXT_PREGEN_END)}\\n?`, "g");
|
|
918
|
+
/**
|
|
919
|
+
* Read the prerender manifest and inject pregenerated concrete paths into the
|
|
920
|
+
* App Router Worker bundle so the PPR fallback-shell guard is populated at
|
|
921
|
+
* module init time without calling `seedMemoryCacheFromPrerender`.
|
|
922
|
+
*
|
|
923
|
+
* The paths are injected as `globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS`
|
|
924
|
+
* wrapped in replaceable marker comments, and consumed by
|
|
925
|
+
* `initPregeneratedPathsFromGlobals` in the generated RSC entry.
|
|
926
|
+
*
|
|
927
|
+
* Idempotent: repeated calls strip the previous injection before writing the
|
|
928
|
+
* new one. If the manifest is missing, corrupt, or empty, any prior injection
|
|
929
|
+
* is stripped and nothing new is written — failing closed to empty.
|
|
930
|
+
*/
|
|
931
|
+
function injectPregeneratedConcretePaths(root) {
|
|
932
|
+
const workerEntry = path.resolve(root, "dist", "server", "index.js");
|
|
933
|
+
if (!fs.existsSync(workerEntry)) return;
|
|
934
|
+
let code = fs.readFileSync(workerEntry, "utf-8");
|
|
935
|
+
code = code.replace(VINEXT_PREGEN_RE, "");
|
|
936
|
+
const table = buildPregeneratedConcretePathTable(readPrerenderManifest(path.join(root, "dist", "server", "vinext-prerender.json")) ?? {});
|
|
937
|
+
if (table.length > 0) code = `${VINEXT_PREGEN_START}\nglobalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS = ${JSON.stringify(table)};\n${VINEXT_PREGEN_END}\n` + code;
|
|
938
|
+
fs.writeFileSync(workerEntry, code);
|
|
939
|
+
}
|
|
851
940
|
async function deploy(options) {
|
|
941
|
+
const deployEnv = validateWranglerEnvName(options.env || (options.preview ? "preview" : "production"));
|
|
852
942
|
const root = path.resolve(options.root);
|
|
853
943
|
loadDotenv({
|
|
854
944
|
root,
|
|
@@ -905,7 +995,7 @@ async function deploy(options) {
|
|
|
905
995
|
console.log("\n Dry run complete. Files generated but no build or deploy performed.\n");
|
|
906
996
|
return;
|
|
907
997
|
}
|
|
908
|
-
if (!options.skipBuild) await runBuild(info,
|
|
998
|
+
if (!options.skipBuild) await runBuild(info, deployEnv === "production" && !options.env ? void 0 : deployEnv);
|
|
909
999
|
else console.log("\n Skipping build (--skip-build)");
|
|
910
1000
|
{
|
|
911
1001
|
const nextConfig = await resolveNextConfig(await loadNextConfig(info.root), info.root);
|
|
@@ -922,6 +1012,7 @@ async function deploy(options) {
|
|
|
922
1012
|
concurrency: options.prerenderConcurrency
|
|
923
1013
|
});
|
|
924
1014
|
}
|
|
1015
|
+
injectPregeneratedConcretePaths(root);
|
|
925
1016
|
}
|
|
926
1017
|
if (options.experimentalTPR) {
|
|
927
1018
|
console.log();
|
|
@@ -933,13 +1024,10 @@ async function deploy(options) {
|
|
|
933
1024
|
});
|
|
934
1025
|
if (tprResult.skipped) console.log(` TPR: Skipped (${tprResult.skipped})`);
|
|
935
1026
|
}
|
|
936
|
-
const url = runWranglerDeploy(root, {
|
|
937
|
-
preview: options.preview ?? false,
|
|
938
|
-
env: options.env
|
|
939
|
-
});
|
|
1027
|
+
const url = runWranglerDeploy(root, { env: deployEnv === "production" && !options.env ? void 0 : deployEnv });
|
|
940
1028
|
console.log("\n ─────────────────────────────────────────");
|
|
941
1029
|
console.log(` Deployed to: ${url}`);
|
|
942
1030
|
console.log(" ─────────────────────────────────────────\n");
|
|
943
1031
|
}
|
|
944
1032
|
//#endregion
|
|
945
|
-
export { buildWranglerDeployArgs, deploy, detectProject, ensureESModule, formatMissingCacheAdapterError, formatMissingCloudflarePluginError, generateAppRouterViteConfig, generateAppRouterWorkerEntry, generatePagesRouterViteConfig, generatePagesRouterWorkerEntry, generateWranglerConfig, getFilesToGenerate, getMissingDeps, hasWranglerConfig, isPackageResolvable, parseDeployArgs, renameCJSConfigs, resolveWranglerBin, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, withCloudflareEnv, workerEntryHasCacheHandler };
|
|
1033
|
+
export { buildNodeCliInvocation, buildWranglerDeployArgs, buildWranglerInvocation, deploy, detectProject, ensureESModule, formatMissingCacheAdapterError, formatMissingCloudflarePluginError, generateAppRouterViteConfig, generateAppRouterWorkerEntry, generatePagesRouterViteConfig, generatePagesRouterWorkerEntry, generateWranglerConfig, getFilesToGenerate, getMissingDeps, hasWranglerConfig, injectPregeneratedConcretePaths, isPackageResolvable, parseDeployArgs, renameCJSConfigs, resolveWranglerBin, runWranglerDeploy, validateWranglerEnvName, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, withCloudflareEnv, workerEntryHasCacheHandler };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { NextRewrite } from "../config/next-config.js";
|
|
1
2
|
import { AppRoute, RouteManifest } from "../routing/app-route-graph.js";
|
|
2
|
-
import { VinextLinkPrefetchRoute } from "../client/vinext-next-data.js";
|
|
3
|
+
import { VinextLinkPrefetchRoute, VinextPagesLinkPrefetchRoute } from "../client/vinext-next-data.js";
|
|
3
4
|
|
|
4
5
|
//#region src/entries/app-browser-entry.d.ts
|
|
5
6
|
/**
|
|
@@ -9,7 +10,11 @@ import { VinextLinkPrefetchRoute } from "../client/vinext-next-data.js";
|
|
|
9
10
|
* embedded RSC payload and handles client-side navigation by re-fetching
|
|
10
11
|
* RSC streams.
|
|
11
12
|
*/
|
|
12
|
-
declare function generateBrowserEntry(routes?: readonly AppRoute[], routeManifest?: RouteManifest | null
|
|
13
|
+
declare function generateBrowserEntry(routes?: readonly AppRoute[], routeManifest?: RouteManifest | null, pagesPrefetchRoutes?: readonly VinextPagesLinkPrefetchRoute[], rewrites?: {
|
|
14
|
+
afterFiles: NextRewrite[];
|
|
15
|
+
beforeFiles: NextRewrite[];
|
|
16
|
+
fallback: NextRewrite[];
|
|
17
|
+
}): string;
|
|
13
18
|
/**
|
|
14
19
|
* Filter for routes that should appear in the `__VINEXT_LINK_PREFETCH_ROUTES__`
|
|
15
20
|
* manifest. Exported so the Pages Router client entry can reuse it when
|
|
@@ -17,7 +22,8 @@ declare function generateBrowserEntry(routes?: readonly AppRoute[], routeManifes
|
|
|
17
22
|
* `pages-client-entry.ts`.
|
|
18
23
|
*/
|
|
19
24
|
declare function isLinkPrefetchRoute(route: AppRoute): boolean;
|
|
25
|
+
declare function toDocumentOnlyAppRoute(route: AppRoute): VinextLinkPrefetchRoute;
|
|
20
26
|
/** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
|
|
21
27
|
declare function toLinkPrefetchRoute(route: AppRoute): VinextLinkPrefetchRoute;
|
|
22
28
|
//#endregion
|
|
23
|
-
export { generateBrowserEntry, isLinkPrefetchRoute, toLinkPrefetchRoute };
|
|
29
|
+
export { generateBrowserEntry, isLinkPrefetchRoute, toDocumentOnlyAppRoute, toLinkPrefetchRoute };
|
|
@@ -7,13 +7,23 @@ import { resolveClientRuntimeModule, resolveRuntimeEntryModule } from "./runtime
|
|
|
7
7
|
* embedded RSC payload and handles client-side navigation by re-fetching
|
|
8
8
|
* RSC streams.
|
|
9
9
|
*/
|
|
10
|
-
function generateBrowserEntry(routes = [], routeManifest = null
|
|
10
|
+
function generateBrowserEntry(routes = [], routeManifest = null, pagesPrefetchRoutes = [], rewrites = {
|
|
11
|
+
afterFiles: [],
|
|
12
|
+
beforeFiles: [],
|
|
13
|
+
fallback: []
|
|
14
|
+
}) {
|
|
11
15
|
const entryPath = resolveRuntimeEntryModule("app-browser-entry");
|
|
12
16
|
const navigationRuntimePath = resolveClientRuntimeModule("navigation-runtime");
|
|
13
|
-
const prefetchRoutes = routes.
|
|
17
|
+
const prefetchRoutes = routes.map((route) => isLinkPrefetchRoute(route) ? toLinkPrefetchRoute(route) : toDocumentOnlyAppRoute(route));
|
|
14
18
|
return `import { registerNavigationRuntimeBootstrap } from ${JSON.stringify(navigationRuntimePath)};
|
|
15
19
|
|
|
16
20
|
window.__VINEXT_LINK_PREFETCH_ROUTES__ = ${JSON.stringify(prefetchRoutes)};
|
|
21
|
+
// Pages route manifest for hybrid ownership decisions. In a hybrid
|
|
22
|
+
// app+pages build the user can land on an App page, so the App browser
|
|
23
|
+
// entry must also expose the Pages manifest (the Pages client entry does
|
|
24
|
+
// the same — whichever entry runs first emits both globals).
|
|
25
|
+
window.__VINEXT_PAGES_LINK_PREFETCH_ROUTES__ = ${JSON.stringify(pagesPrefetchRoutes)};
|
|
26
|
+
window.__VINEXT_CLIENT_REWRITES__ = ${JSON.stringify(rewrites)};
|
|
17
27
|
registerNavigationRuntimeBootstrap({
|
|
18
28
|
routeManifest: ${buildRouteManifestExpression(routeManifest)}
|
|
19
29
|
});
|
|
@@ -29,6 +39,14 @@ function isLinkPrefetchRoute(route) {
|
|
|
29
39
|
if (route.pagePath !== null) return true;
|
|
30
40
|
return route.routePath === null && route.layouts.length > 0;
|
|
31
41
|
}
|
|
42
|
+
function toDocumentOnlyAppRoute(route) {
|
|
43
|
+
return {
|
|
44
|
+
canPrefetchLoadingShell: false,
|
|
45
|
+
documentOnly: true,
|
|
46
|
+
patternParts: [...route.patternParts],
|
|
47
|
+
isDynamic: route.isDynamic
|
|
48
|
+
};
|
|
49
|
+
}
|
|
32
50
|
/** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
|
|
33
51
|
function toLinkPrefetchRoute(route) {
|
|
34
52
|
return {
|
|
@@ -62,4 +80,4 @@ function buildMapExpression(map) {
|
|
|
62
80
|
return `new Map(${JSON.stringify(Array.from(map.entries()))})`;
|
|
63
81
|
}
|
|
64
82
|
//#endregion
|
|
65
|
-
export { generateBrowserEntry, isLinkPrefetchRoute, toLinkPrefetchRoute };
|
|
83
|
+
export { generateBrowserEntry, isLinkPrefetchRoute, toDocumentOnlyAppRoute, toLinkPrefetchRoute };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
|
|
2
2
|
import { AppRoute } from "../routing/app-route-graph.js";
|
|
3
3
|
import { MetadataFileRoute } from "../server/metadata-routes.js";
|
|
4
|
+
import { ImageConfig } from "../server/image-optimization.js";
|
|
4
5
|
|
|
5
6
|
//#region src/entries/app-rsc-entry.d.ts
|
|
6
7
|
/**
|
|
@@ -45,6 +46,7 @@ type AppRouterConfig = {
|
|
|
45
46
|
inlineCss?: boolean; /** Enables Next.js Cache Components semantics for App Router document HTML. */
|
|
46
47
|
cacheComponents?: boolean; /** Internationalization routing config for middleware matcher locale handling. */
|
|
47
48
|
i18n?: NextI18nConfig | null;
|
|
49
|
+
imageConfig?: ImageConfig;
|
|
48
50
|
/**
|
|
49
51
|
* Absolute path to `app/global-not-found.{tsx,ts,js,jsx}` when present.
|
|
50
52
|
* When provided, route-miss 404s render this module standalone (it owns its
|