vinext 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -9
- package/dist/build/client-build-config.d.ts +10 -0
- package/dist/build/client-build-config.js +18 -2
- package/dist/build/pages-client-assets-module.d.ts +8 -0
- package/dist/build/pages-client-assets-module.js +21 -1
- package/dist/build/prerender-paths.js +5 -3
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/ssr-manifest.d.ts +2 -0
- package/dist/build/ssr-manifest.js +6 -2
- package/dist/check.js +7 -6
- package/dist/cli.js +2 -1
- package/dist/client/client-redirect-matcher.d.ts +14 -0
- package/dist/client/client-redirect-matcher.js +37 -0
- package/dist/client/client-redirects.d.ts +27 -0
- package/dist/client/client-redirects.js +28 -0
- package/dist/client/client-rewrites.d.ts +2 -1
- package/dist/client/client-rewrites.js +1 -1
- package/dist/config/config-matchers.d.ts +26 -11
- package/dist/config/config-matchers.js +78 -81
- package/dist/config/destination-params.d.ts +47 -0
- package/dist/config/destination-params.js +116 -0
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +3 -0
- package/dist/entries/app-rsc-entry.d.ts +4 -0
- package/dist/entries/app-rsc-entry.js +20 -6
- package/dist/entries/pages-client-entry.js +3 -1
- package/dist/entries/pages-server-entry.js +13 -37
- package/dist/index.d.ts +3 -1
- package/dist/index.js +134 -43
- package/dist/init-cloudflare.d.ts +9 -0
- package/dist/init-cloudflare.js +107 -31
- package/dist/init-platform.d.ts +4 -0
- package/dist/init-platform.js +27 -2
- package/dist/init.d.ts +1 -0
- package/dist/init.js +67 -3
- package/dist/plugins/ast-scope.d.ts +7 -0
- package/dist/plugins/ast-scope.js +59 -3
- package/dist/plugins/cache-flight-codec.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +9 -8
- package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +3 -4
- package/dist/plugins/middleware-server-only.d.ts +5 -4
- package/dist/plugins/middleware-server-only.js +8 -5
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
- package/dist/plugins/rsc-scan-glob-imports.js +50 -0
- package/dist/plugins/strip-server-exports.js +262 -98
- package/dist/plugins/transform-result.d.ts +9 -5
- package/dist/plugins/transitive-externals.js +1 -1
- package/dist/plugins/typeof-window.d.ts +2 -2
- package/dist/plugins/use-cache-callable.js +8 -2
- package/dist/plugins/worker-server-only-imports.d.ts +20 -0
- package/dist/plugins/worker-server-only-imports.js +31 -0
- package/dist/plugins/worker-use-server.d.ts +25 -0
- package/dist/plugins/worker-use-server.js +129 -0
- package/dist/server/api-handler.d.ts +1 -0
- package/dist/server/api-handler.js +2 -1
- package/dist/server/app-browser-action-result.d.ts +1 -1
- package/dist/server/app-browser-action-result.js +9 -2
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-middleware.d.ts +11 -0
- package/dist/server/app-middleware.js +17 -2
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +1 -1
- package/dist/server/app-page-dispatch.d.ts +3 -1
- package/dist/server/app-page-dispatch.js +4 -3
- package/dist/server/app-page-ppr-runtime.js +1 -1
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-request.js +53 -15
- package/dist/server/app-page-route-wiring.js +2 -2
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -3
- package/dist/server/app-prerender-endpoints.js +9 -6
- package/dist/server/app-request-stage-dispatch.js +6 -2
- package/dist/server/app-request-stage-independent-entry.js +25 -5
- package/dist/server/app-response-stage-entry.js +10 -2
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +5 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +45 -24
- package/dist/server/app-router-entry.js +24 -5
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.js +20 -16
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +85 -35
- package/dist/server/app-rsc-response-stage.js +4 -2
- package/dist/server/app-segment-config.d.ts +2 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +61 -22
- package/dist/server/app-ssr-entry.js +2 -1
- package/dist/server/app-worker-stages.d.ts +5 -0
- package/dist/server/app-worker-stages.js +1 -1
- package/dist/server/cacheability-request.js +2 -2
- package/dist/server/client-build-files.d.ts +16 -0
- package/dist/server/client-build-files.js +36 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/dev-server.js +38 -27
- package/dist/server/dev-stack-sourcemap.js +18 -23
- package/dist/server/document-initial-head.d.ts +0 -11
- package/dist/server/document-initial-head.js +1 -1
- package/dist/server/forwarded-middleware-context.d.ts +5 -0
- package/dist/server/forwarded-middleware-context.js +22 -0
- package/dist/server/headers.d.ts +4 -1
- package/dist/server/headers.js +4 -1
- package/dist/server/http-conditional.d.ts +11 -0
- package/dist/server/http-conditional.js +10 -1
- package/dist/server/http-error-responses.d.ts +1 -1
- package/dist/server/image-optimization.d.ts +38 -0
- package/dist/server/image-optimization.js +93 -4
- package/dist/server/isr-cache.d.ts +10 -0
- package/dist/server/isr-cache.js +41 -6
- package/dist/server/metadata-route-response.js +9 -8
- package/dist/server/middleware-matcher.d.ts +2 -0
- package/dist/server/middleware-matcher.js +23 -2
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +33 -20
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +3 -1
- package/dist/server/multi-stage.d.ts +11 -0
- package/dist/server/normalize-path.d.ts +0 -13
- package/dist/server/normalize-path.js +1 -34
- package/dist/server/pages-api-route.d.ts +3 -2
- package/dist/server/pages-api-route.js +4 -3
- package/dist/server/pages-cache-tag.d.ts +12 -0
- package/dist/server/pages-cache-tag.js +19 -0
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-data-route.d.ts +10 -0
- package/dist/server/pages-data-route.js +19 -2
- package/dist/server/pages-document-asset-props.d.ts +5 -1
- package/dist/server/pages-document-asset-props.js +13 -5
- package/dist/server/pages-document-splice.d.ts +19 -0
- package/dist/server/pages-document-splice.js +55 -0
- package/dist/server/pages-i18n.d.ts +12 -1
- package/dist/server/pages-i18n.js +18 -4
- package/dist/server/pages-node-compat.d.ts +16 -5
- package/dist/server/pages-node-compat.js +20 -12
- package/dist/server/pages-page-data.d.ts +32 -24
- package/dist/server/pages-page-data.js +50 -120
- package/dist/server/pages-page-handler.d.ts +0 -6
- package/dist/server/pages-page-handler.js +188 -126
- package/dist/server/pages-page-response.d.ts +12 -6
- package/dist/server/pages-page-response.js +41 -34
- package/dist/server/pages-request-pipeline.d.ts +10 -2
- package/dist/server/pages-request-pipeline.js +37 -18
- package/dist/server/pages-request-stage-entry.d.ts +6 -0
- package/dist/server/pages-request-stage-entry.js +71 -12
- package/dist/server/pages-response-stage-entry.js +4 -0
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/pages-router-entry.js +4 -3
- package/dist/server/prerender-manifest.d.ts +3 -3
- package/dist/server/prerender-manifest.js +4 -3
- package/dist/server/prerender-work-unit-setup.js +4 -0
- package/dist/server/prod-server.d.ts +12 -0
- package/dist/server/prod-server.js +199 -69
- package/dist/server/proper-error.d.ts +4 -0
- package/dist/server/proper-error.js +31 -0
- package/dist/server/request-pipeline.d.ts +4 -1
- package/dist/server/request-pipeline.js +3 -2
- package/dist/server/revalidation-request.d.ts +1 -0
- package/dist/server/revalidation-request.js +1 -1
- package/dist/server/rsc-stream-hints.js +31 -2
- package/dist/server/seed-cache.d.ts +1 -0
- package/dist/server/seed-cache.js +5 -4
- package/dist/server/server-reference-loader.d.ts +4 -0
- package/dist/server/server-reference-loader.js +29 -0
- package/dist/server/socket-error-backstop.d.ts +9 -1
- package/dist/server/socket-error-backstop.js +46 -17
- package/dist/server/static-file-signal.d.ts +15 -4
- package/dist/server/static-file-signal.js +46 -12
- package/dist/server/worker-image-optimization.d.ts +34 -0
- package/dist/server/worker-image-optimization.js +86 -0
- package/dist/server/worker-stages.d.ts +1 -1
- package/dist/server/worker-stages.js +2 -2
- package/dist/server/worker-utils.d.ts +8 -3
- package/dist/server/worker-utils.js +12 -7
- package/dist/shims/app-router-scroll.js +4 -1
- package/dist/shims/app-router-tree-context.d.ts +5 -0
- package/dist/shims/app-router-tree-context.js +27 -0
- package/dist/shims/cache-callable-runtime.d.ts +4 -2
- package/dist/shims/cache-callable-runtime.js +21 -12
- package/dist/shims/cache-handler.js +1 -9
- package/dist/shims/cache-runtime.d.ts +6 -1
- package/dist/shims/cache-runtime.js +2 -1
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +40 -13
- package/dist/shims/cdn-cache.d.ts +8 -0
- package/dist/shims/cdn-cache.js +17 -1
- package/dist/shims/disable-smooth-scroll.d.ts +3 -0
- package/dist/shims/disable-smooth-scroll.js +36 -0
- package/dist/shims/document-placeholders.d.ts +19 -0
- package/dist/shims/document-placeholders.js +45 -0
- package/dist/shims/document.js +21 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
- package/dist/shims/dynamic-preload-chunks.js +13 -9
- package/dist/shims/dynamic.d.ts +1 -1
- package/dist/shims/dynamic.js +60 -8
- package/dist/shims/fetch-cache-state.d.ts +66 -0
- package/dist/shims/fetch-cache-state.js +92 -0
- package/dist/shims/fetch-cache.d.ts +3 -67
- package/dist/shims/fetch-cache.js +160 -125
- package/dist/shims/head.d.ts +10 -6
- package/dist/shims/head.js +15 -13
- package/dist/shims/image.js +2 -1
- package/dist/shims/internal/work-store-scope.d.ts +5 -0
- package/dist/shims/internal/work-store-scope.js +24 -0
- package/dist/shims/navigation.js +31 -5
- package/dist/shims/request-context.d.ts +2 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/router.js +12 -20
- package/dist/shims/server.d.ts +16 -0
- package/dist/shims/server.js +24 -4
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/url-utils.d.ts +2 -0
- package/dist/shims/url-utils.js +3 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/hash.d.ts +7 -0
- package/dist/utils/hash.js +11 -1
- package/dist/utils/package-name.d.ts +6 -0
- package/dist/utils/package-name.js +12 -1
- package/dist/utils/plugin-rsc-version.d.ts +4 -0
- package/dist/utils/plugin-rsc-version.js +15 -0
- package/dist/utils/prerender-output-paths.js +15 -4
- package/dist/utils/public-file-path.d.ts +10 -2
- package/dist/utils/public-file-path.js +13 -9
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.d.ts +3 -0
- package/dist/utils/react-version.js +1 -1
- package/package.json +7 -3
package/dist/init-cloudflare.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from "./deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { detectProject } from "./utils/project.js";
|
|
3
|
+
import { validateWorkerName } from "./init-platform.js";
|
|
3
4
|
import { isUnknownRecord } from "./utils/record.js";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import fs from "node:fs";
|
|
@@ -13,6 +14,10 @@ const DEFAULT_CLOUDFLARE_INIT_OPTIONS = {
|
|
|
13
14
|
imageOptimization: "cloudflare-images"
|
|
14
15
|
};
|
|
15
16
|
const DEFAULT_VERSION_METADATA_BINDING = "CF_VERSION_METADATA";
|
|
17
|
+
const BUILD_OUTPUT_EXCLUSIONS = ["!/_next/static/*", "!/*/_next/static/*"];
|
|
18
|
+
const DEFAULT_RUN_WORKER_FIRST = ["/*", ...BUILD_OUTPUT_EXCLUSIONS];
|
|
19
|
+
const HTML_HANDLING = "none";
|
|
20
|
+
const STATIC_ASSETS_CACHE_ROUTE = "/_vinext/static-cache/*";
|
|
16
21
|
const RESPONSE_STORE_WRANGLER_CONFIG = "wrangler.response-store.jsonc";
|
|
17
22
|
const RESPONSE_STORE_BINDING = "RESPONSE_STORE";
|
|
18
23
|
const RESPONSE_STORE_ENTRYPOINT = "ResponseStoreService";
|
|
@@ -26,6 +31,7 @@ const CACHE_METADATA_EXPORT = {
|
|
|
26
31
|
};
|
|
27
32
|
const CTX_EXPORTS_DEFAULT_DATE = "2025-11-17";
|
|
28
33
|
function validateCloudflarePlatformSetup(context, cloudflare) {
|
|
34
|
+
if (cloudflare.name !== void 0) validateWorkerName(cloudflare.name);
|
|
29
35
|
if (!cloudflare.legacyWrangler) {
|
|
30
36
|
const existingWrangler = [
|
|
31
37
|
"wrangler.toml",
|
|
@@ -54,7 +60,10 @@ function validateCloudflarePlatformSetup(context, cloudflare) {
|
|
|
54
60
|
const wranglerPath = ["wrangler.jsonc", "wrangler.json"].map((fileName) => path.join(context.root, fileName)).find((candidate) => fs.existsSync(candidate));
|
|
55
61
|
const wranglerCode = wranglerPath ? fs.readFileSync(wranglerPath, "utf-8") : void 0;
|
|
56
62
|
if (!wranglerCode && cloudflare.cdnCache === "response-store" && (cloudflare.responseStoreMode ?? "service-binding") === "service-binding" && fs.existsSync(path.join(context.root, RESPONSE_STORE_WRANGLER_CONFIG))) readResponseStoreServiceName(context.root, {});
|
|
57
|
-
const updatedWranglerCode = wranglerCode ? updateWranglerConfigForCloudflare(wranglerCode, cloudflare, {
|
|
63
|
+
const updatedWranglerCode = wranglerCode ? updateWranglerConfigForCloudflare(wranglerCode, cloudflare, {
|
|
64
|
+
root: context.root,
|
|
65
|
+
isStaticExport: context.isStaticExport
|
|
66
|
+
}) : void 0;
|
|
58
67
|
const imagesBinding = updatedWranglerCode ? getWranglerImagesBinding(updatedWranglerCode) : "IMAGES";
|
|
59
68
|
const assetsBinding = updatedWranglerCode ? getWranglerAssetsBinding(updatedWranglerCode) : "ASSETS";
|
|
60
69
|
const assetsDirectory = updatedWranglerCode ? getWranglerAssetsDirectory(updatedWranglerCode) : "dist/client";
|
|
@@ -74,10 +83,13 @@ function validateCloudflarePlatformSetup(context, cloudflare) {
|
|
|
74
83
|
}
|
|
75
84
|
function setupCloudflarePlatform(context, cloudflare) {
|
|
76
85
|
if (!cloudflare.legacyWrangler) return setupCfPlatform(context, cloudflare);
|
|
77
|
-
const projectInfo =
|
|
86
|
+
const projectInfo = detectCloudflareProject(context.root, cloudflare);
|
|
78
87
|
const wranglerPath = ["wrangler.jsonc", "wrangler.json"].map((fileName) => path.join(context.root, fileName)).find((candidate) => fs.existsSync(candidate));
|
|
79
88
|
const wranglerCode = wranglerPath ? fs.readFileSync(wranglerPath, "utf-8") : void 0;
|
|
80
|
-
const updatedWranglerCode = wranglerCode ? updateWranglerConfigForCloudflare(wranglerCode, cloudflare, {
|
|
89
|
+
const updatedWranglerCode = wranglerCode ? updateWranglerConfigForCloudflare(wranglerCode, cloudflare, {
|
|
90
|
+
root: context.root,
|
|
91
|
+
isStaticExport: context.isStaticExport
|
|
92
|
+
}) : void 0;
|
|
81
93
|
const imagesBinding = updatedWranglerCode ? getWranglerImagesBinding(updatedWranglerCode) : "IMAGES";
|
|
82
94
|
const assetsBinding = updatedWranglerCode ? getWranglerAssetsBinding(updatedWranglerCode) : "ASSETS";
|
|
83
95
|
const assetsDirectory = updatedWranglerCode ? getWranglerAssetsDirectory(updatedWranglerCode) : "dist/client";
|
|
@@ -112,7 +124,10 @@ function setupCloudflarePlatform(context, cloudflare) {
|
|
|
112
124
|
}
|
|
113
125
|
const generatedPlatformFiles = [];
|
|
114
126
|
if (!wranglerPath) {
|
|
115
|
-
fs.writeFileSync(path.join(context.root, "wrangler.jsonc"), generateWranglerConfig(
|
|
127
|
+
fs.writeFileSync(path.join(context.root, "wrangler.jsonc"), generateWranglerConfig({
|
|
128
|
+
...projectInfo,
|
|
129
|
+
isStaticExport: context.isStaticExport
|
|
130
|
+
}, cloudflare, context.today), "utf-8");
|
|
116
131
|
generatedPlatformFiles.push("wrangler.jsonc");
|
|
117
132
|
} else if (wranglerCode && updatedWranglerCode) {
|
|
118
133
|
if (updatedWranglerCode !== wranglerCode) {
|
|
@@ -139,8 +154,23 @@ function setupCloudflarePlatform(context, cloudflare) {
|
|
|
139
154
|
preservedExistingGenerateScopedName
|
|
140
155
|
};
|
|
141
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* The existing config that keeps its own Worker name, if `--name` was given.
|
|
159
|
+
* Init doesn't rename the Worker in an existing config, so callers warn instead.
|
|
160
|
+
*/
|
|
161
|
+
function findConfigKeepingWorkerName(root, cloudflare) {
|
|
162
|
+
if (cloudflare.name === void 0) return void 0;
|
|
163
|
+
return (cloudflare.legacyWrangler ? ["wrangler.jsonc", "wrangler.json"] : ["cloudflare.config.ts"]).find((name) => fs.existsSync(path.join(root, name)));
|
|
164
|
+
}
|
|
165
|
+
function detectCloudflareProject(root, cloudflare) {
|
|
166
|
+
const projectInfo = detectProject(root);
|
|
167
|
+
return cloudflare.name ? {
|
|
168
|
+
...projectInfo,
|
|
169
|
+
projectName: cloudflare.name
|
|
170
|
+
} : projectInfo;
|
|
171
|
+
}
|
|
142
172
|
function setupCfPlatform(context, cloudflare) {
|
|
143
|
-
const projectInfo =
|
|
173
|
+
const projectInfo = detectCloudflareProject(context.root, cloudflare);
|
|
144
174
|
const serviceBinding = cloudflare.cdnCache === "response-store" && (cloudflare.responseStoreMode ?? "service-binding") === "service-binding";
|
|
145
175
|
let generatedViteConfig = false;
|
|
146
176
|
let preservedExistingGenerateScopedName = false;
|
|
@@ -168,7 +198,10 @@ function setupCfPlatform(context, cloudflare) {
|
|
|
168
198
|
const configPath = path.join(context.root, "cloudflare.config.ts");
|
|
169
199
|
const generatedPlatformFiles = [];
|
|
170
200
|
if (!fs.existsSync(configPath)) {
|
|
171
|
-
fs.writeFileSync(configPath, generateTypedCloudflareConfig(
|
|
201
|
+
fs.writeFileSync(configPath, generateTypedCloudflareConfig({
|
|
202
|
+
...projectInfo,
|
|
203
|
+
isStaticExport: context.isStaticExport
|
|
204
|
+
}, cloudflare, context.today));
|
|
172
205
|
generatedPlatformFiles.push("cloudflare.config.ts");
|
|
173
206
|
}
|
|
174
207
|
const nextSteps = [];
|
|
@@ -215,6 +248,12 @@ export const responseStoreServiceBinding = responseStore.serviceBindingWorker;
|
|
|
215
248
|
...options.imageOptimization === "cloudflare-images" ? ["IMAGES: bindings.images()"] : [],
|
|
216
249
|
...options.dataCache === "kv" ? ["VINEXT_KV_CACHE: bindings.kv()"] : []
|
|
217
250
|
];
|
|
251
|
+
const routing = defaultAssetRouting(info, options);
|
|
252
|
+
const assetLines = [
|
|
253
|
+
...routing.htmlHandling ? [`htmlHandling: ${JSON.stringify(routing.htmlHandling)}`] : [],
|
|
254
|
+
"notFoundHandling: \"none\"",
|
|
255
|
+
...routing.runWorkerFirst ? [`runWorkerFirst: [${routing.runWorkerFirst.map((pattern) => JSON.stringify(pattern)).join(", ")}]`] : []
|
|
256
|
+
];
|
|
218
257
|
return `${imports.join("\n")}
|
|
219
258
|
|
|
220
259
|
${shared}export default defineConfig({
|
|
@@ -223,7 +262,9 @@ ${shared}export default defineConfig({
|
|
|
223
262
|
entrypoint: ${JSON.stringify(resolveWorkerEntry(info.root))},
|
|
224
263
|
compatibilityDate: ${JSON.stringify(today)},
|
|
225
264
|
compatibilityFlags: ["nodejs_compat"],
|
|
226
|
-
assets: {
|
|
265
|
+
assets: {
|
|
266
|
+
${assetLines.join(",\n ")},
|
|
267
|
+
},
|
|
227
268
|
env: {
|
|
228
269
|
${envBindings.join(",\n ")},
|
|
229
270
|
},
|
|
@@ -242,8 +283,21 @@ function resolveWorkerEntry(root) {
|
|
|
242
283
|
if (fs.existsSync(path.join(root, "worker", "index.js"))) return "./worker/index.js";
|
|
243
284
|
return "vinext/server/fetch-handler";
|
|
244
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Next.js runs no middleware for a static export, and an export with
|
|
288
|
+
* `trailingSlash` relies on the default html_handling to serve `/about/` from
|
|
289
|
+
* `about/index.html`, so export apps keep asset-first serving.
|
|
290
|
+
*/
|
|
291
|
+
function defaultAssetRouting(info, options) {
|
|
292
|
+
if (!info.isStaticExport) return {
|
|
293
|
+
htmlHandling: HTML_HANDLING,
|
|
294
|
+
runWorkerFirst: DEFAULT_RUN_WORKER_FIRST
|
|
295
|
+
};
|
|
296
|
+
return options.cdnCache === "static-assets" ? { runWorkerFirst: [STATIC_ASSETS_CACHE_ROUTE] } : {};
|
|
297
|
+
}
|
|
245
298
|
function generateWranglerConfig(info, options = DEFAULT_CLOUDFLARE_INIT_OPTIONS, today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0]) {
|
|
246
299
|
const workerEntry = resolveWorkerEntry(info.root);
|
|
300
|
+
const routing = defaultAssetRouting(info, options);
|
|
247
301
|
const config = {
|
|
248
302
|
$schema: "node_modules/wrangler/config-schema.json",
|
|
249
303
|
name: info.projectName,
|
|
@@ -252,15 +306,13 @@ function generateWranglerConfig(info, options = DEFAULT_CLOUDFLARE_INIT_OPTIONS,
|
|
|
252
306
|
main: workerEntry,
|
|
253
307
|
assets: {
|
|
254
308
|
directory: "dist/client",
|
|
309
|
+
...routing.htmlHandling ? { html_handling: routing.htmlHandling } : {},
|
|
255
310
|
not_found_handling: "none",
|
|
256
311
|
binding: "ASSETS",
|
|
257
|
-
...
|
|
312
|
+
...routing.runWorkerFirst ? { run_worker_first: routing.runWorkerFirst } : {}
|
|
258
313
|
}
|
|
259
314
|
};
|
|
260
|
-
if (options.cdnCache === "workers-cache") {
|
|
261
|
-
config.cache = { enabled: true };
|
|
262
|
-
config.version_metadata = { binding: DEFAULT_VERSION_METADATA_BINDING };
|
|
263
|
-
}
|
|
315
|
+
if (options.cdnCache === "workers-cache") config.version_metadata = { binding: DEFAULT_VERSION_METADATA_BINDING };
|
|
264
316
|
if (options.imageOptimization === "cloudflare-images") config.images = { binding: "IMAGES" };
|
|
265
317
|
if (options.dataCache === "kv") config.kv_namespaces = [{ binding: "VINEXT_KV_CACHE" }];
|
|
266
318
|
const code = `${JSON.stringify(config, null, 2)}\n`;
|
|
@@ -305,6 +357,19 @@ function stripJsonComments(code) {
|
|
|
305
357
|
}
|
|
306
358
|
return output.replace(/,\s*([}\]])/g, "$1");
|
|
307
359
|
}
|
|
360
|
+
/** Offset of the first JSONC token in `code`, after whitespace and comments. */
|
|
361
|
+
function skipJsonWhitespaceAndComments(code) {
|
|
362
|
+
let index = 0;
|
|
363
|
+
while (index < code.length) if (/\s/.test(code[index])) index++;
|
|
364
|
+
else if (code.startsWith("//", index)) {
|
|
365
|
+
const lineEnd = code.indexOf("\n", index);
|
|
366
|
+
index = lineEnd === -1 ? code.length : lineEnd;
|
|
367
|
+
} else if (code.startsWith("/*", index)) {
|
|
368
|
+
const commentEnd = code.indexOf("*/", index + 2);
|
|
369
|
+
index = commentEnd === -1 ? code.length : commentEnd + 2;
|
|
370
|
+
} else break;
|
|
371
|
+
return index;
|
|
372
|
+
}
|
|
308
373
|
function findTopLevelJsonProperty(code, name) {
|
|
309
374
|
let depth = 0;
|
|
310
375
|
let inString = false;
|
|
@@ -457,7 +522,7 @@ function readResponseStoreServiceName(root, appConfig) {
|
|
|
457
522
|
const durableBindings = isUnknownRecord(responseStoreConfig.durable_objects) ? responseStoreConfig.durable_objects.bindings : void 0;
|
|
458
523
|
const hasCacheMetadata = Array.isArray(durableBindings) && durableBindings.some((binding) => isUnknownRecord(binding) && binding.name === CACHE_METADATA_BINDING && binding.class_name === CACHE_METADATA_CLASS && binding.script_name === void 0);
|
|
459
524
|
const hasNoMigrations = responseStoreConfig.migrations === void 0 || Array.isArray(responseStoreConfig.migrations) && responseStoreConfig.migrations.length === 0;
|
|
460
|
-
if (!isUnknownRecord(responseStoreConfig.cache) || responseStoreConfig.cache.enabled !==
|
|
525
|
+
if (responseStoreConfig.cache !== void 0 && (!isUnknownRecord(responseStoreConfig.cache) || typeof responseStoreConfig.cache.enabled !== "boolean") || !isUnknownRecord(responseStoreExport) || !isUnknownRecord(responseStoreExport.cache) || responseStoreExport.cache.enabled !== true || !hasCacheBodies || !hasCacheMetadata || !isCacheMetadataExport(cacheMetadataExport) || !hasNoMigrations) throw new Error(`${RESPONSE_STORE_WRANGLER_CONFIG} is missing required Response Store bindings.`);
|
|
461
526
|
const compatibilityFlags = responseStoreConfig.compatibility_flags;
|
|
462
527
|
if (compatibilityFlags !== void 0 && (!Array.isArray(compatibilityFlags) || compatibilityFlags.some((flag) => typeof flag !== "string"))) throw new Error(`${RESPONSE_STORE_WRANGLER_CONFIG} has invalid compatibility flags.`);
|
|
463
528
|
const flags = compatibilityFlags ?? [];
|
|
@@ -481,7 +546,7 @@ function configureResponseStoreWrangler(code, config, mode, root) {
|
|
|
481
546
|
if (cache !== void 0 && !isUnknownRecord(cache)) throw new Error("The existing Wrangler config has an invalid cache value.");
|
|
482
547
|
code = setTopLevelJsonProperty(code, "cache", {
|
|
483
548
|
...cache,
|
|
484
|
-
enabled:
|
|
549
|
+
enabled: false
|
|
485
550
|
});
|
|
486
551
|
const exportsConfig = config.exports;
|
|
487
552
|
if (exportsConfig !== void 0 && !isUnknownRecord(exportsConfig)) throw new Error("The existing Wrangler config has an invalid exports value.");
|
|
@@ -593,7 +658,7 @@ function generateResponseStoreWranglerConfig(appWranglerCode, root) {
|
|
|
593
658
|
compatibility_flags: compatibilityFlags,
|
|
594
659
|
workers_dev: false,
|
|
595
660
|
preview_urls: false,
|
|
596
|
-
cache: { enabled:
|
|
661
|
+
cache: { enabled: false },
|
|
597
662
|
exports: {
|
|
598
663
|
default: {
|
|
599
664
|
type: "worker",
|
|
@@ -629,15 +694,25 @@ function updateWranglerConfigForCloudflare(code, options, context = {}) {
|
|
|
629
694
|
const workerEntry = resolveWorkerEntry(context.root ?? process.cwd());
|
|
630
695
|
output = appendTopLevelJsonProperty(output, ` "main": ${JSON.stringify(workerEntry)}`);
|
|
631
696
|
}
|
|
632
|
-
if (!findTopLevelJsonProperty(output, "assets"))
|
|
697
|
+
if (!findTopLevelJsonProperty(output, "assets")) {
|
|
698
|
+
const routing = defaultAssetRouting(context, {});
|
|
699
|
+
const assets = JSON.stringify({
|
|
700
|
+
directory: "dist/client",
|
|
701
|
+
...routing.htmlHandling ? { html_handling: routing.htmlHandling } : {},
|
|
702
|
+
not_found_handling: "none",
|
|
703
|
+
binding: "ASSETS",
|
|
704
|
+
...routing.runWorkerFirst ? { run_worker_first: routing.runWorkerFirst } : {}
|
|
705
|
+
}, null, 2).replaceAll("\n", "\n ");
|
|
706
|
+
output = appendTopLevelJsonProperty(output, ` "assets": ${assets}`);
|
|
707
|
+
}
|
|
633
708
|
if (options.cdnCache === "static-assets") {
|
|
634
709
|
const assetsProperty = findTopLevelJsonProperty(output, "assets");
|
|
635
710
|
const assets = JSON.parse(stripJsonComments(output.slice(assetsProperty.valueStart, assetsProperty.valueEnd)));
|
|
636
711
|
if (!assets || typeof assets !== "object" || Array.isArray(assets)) throw new Error("The existing Wrangler config has an invalid assets value.");
|
|
637
712
|
const workerFirst = assets.run_worker_first;
|
|
638
713
|
if (workerFirst !== void 0 && typeof workerFirst !== "boolean" && !Array.isArray(workerFirst)) throw new Error("The existing Wrangler config has an invalid assets.run_worker_first value.");
|
|
639
|
-
if (Array.isArray(workerFirst) && workerFirst.some((pattern) => typeof pattern !== "string" || pattern.startsWith("!"))) throw new Error(
|
|
640
|
-
const protectedRouting = workerFirst === true ? true : [.../* @__PURE__ */ new Set([...Array.isArray(workerFirst) ? workerFirst : [],
|
|
714
|
+
if (Array.isArray(workerFirst) && workerFirst.some((pattern) => typeof pattern !== "string" || pattern.startsWith("!") && !BUILD_OUTPUT_EXCLUSIONS.includes(pattern))) throw new Error(`Static Assets cache requires run_worker_first without exclusion patterns other than ${BUILD_OUTPUT_EXCLUSIONS.join(" and ")}. Use an array of positive path patterns, optionally with those exclusions.`);
|
|
715
|
+
const protectedRouting = workerFirst === true ? true : Array.isArray(workerFirst) && workerFirst.includes("/*") ? workerFirst : [.../* @__PURE__ */ new Set([...Array.isArray(workerFirst) ? workerFirst : [], STATIC_ASSETS_CACHE_ROUTE])];
|
|
641
716
|
if (typeof assets.directory !== "string" || assets.directory.length === 0 || typeof assets.binding !== "string" || assets.binding.length === 0 || JSON.stringify(workerFirst) !== JSON.stringify(protectedRouting)) {
|
|
642
717
|
const updatedAssets = JSON.stringify({
|
|
643
718
|
...assets,
|
|
@@ -649,18 +724,6 @@ function updateWranglerConfigForCloudflare(code, options, context = {}) {
|
|
|
649
724
|
}
|
|
650
725
|
}
|
|
651
726
|
if (options.cdnCache === "workers-cache") {
|
|
652
|
-
const cacheProperty = findTopLevelJsonProperty(output, "cache");
|
|
653
|
-
if (!cacheProperty) output = appendTopLevelJsonProperty(output, " \"cache\": { \"enabled\": true }");
|
|
654
|
-
else {
|
|
655
|
-
const cache = JSON.parse(stripJsonComments(output.slice(cacheProperty.valueStart, cacheProperty.valueEnd)));
|
|
656
|
-
if (!cache || cache.enabled !== true) {
|
|
657
|
-
const updatedCache = JSON.stringify({
|
|
658
|
-
...cache,
|
|
659
|
-
enabled: true
|
|
660
|
-
});
|
|
661
|
-
output = `${output.slice(0, cacheProperty.valueStart)}${updatedCache}${output.slice(cacheProperty.valueEnd)}`;
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
727
|
const versionMetadataProperty = findTopLevelJsonProperty(output, "version_metadata");
|
|
665
728
|
if (!versionMetadataProperty) output = appendTopLevelJsonProperty(output, ` "version_metadata": { "binding": "${DEFAULT_VERSION_METADATA_BINDING}" }`);
|
|
666
729
|
else {
|
|
@@ -668,6 +731,19 @@ function updateWranglerConfigForCloudflare(code, options, context = {}) {
|
|
|
668
731
|
if (!versionMetadata || typeof versionMetadata.binding !== "string" || versionMetadata.binding.length === 0) output = `${output.slice(0, versionMetadataProperty.valueStart)}{ "binding": "${DEFAULT_VERSION_METADATA_BINDING}" }${output.slice(versionMetadataProperty.valueEnd)}`;
|
|
669
732
|
}
|
|
670
733
|
}
|
|
734
|
+
if (options.cdnCache !== "response-store") {
|
|
735
|
+
const cacheProperty = findTopLevelJsonProperty(output, "cache");
|
|
736
|
+
if (cacheProperty) {
|
|
737
|
+
const cacheCode = output.slice(cacheProperty.valueStart, cacheProperty.valueEnd);
|
|
738
|
+
const cache = JSON.parse(stripJsonComments(cacheCode));
|
|
739
|
+
const enabledProperty = findTopLevelJsonProperty(cacheCode, "enabled");
|
|
740
|
+
const enabledToken = enabledProperty ? enabledProperty.valueStart + skipJsonWhitespaceAndComments(cacheCode.slice(enabledProperty.valueStart, enabledProperty.valueEnd)) : -1;
|
|
741
|
+
if (isUnknownRecord(cache) && cache.enabled === true && cacheCode.startsWith("true", enabledToken)) {
|
|
742
|
+
const enabledStart = cacheProperty.valueStart + enabledToken;
|
|
743
|
+
output = `${output.slice(0, enabledStart)}false${output.slice(enabledStart + 4)}`;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
671
747
|
if (options.imageOptimization === "cloudflare-images") {
|
|
672
748
|
const imagesProperty = findTopLevelJsonProperty(output, "images");
|
|
673
749
|
if (!imagesProperty) output = appendTopLevelJsonProperty(output, " \"images\": { \"binding\": \"IMAGES\" }");
|
|
@@ -1540,4 +1616,4 @@ function usesCommonJsViteConfig(filePath, code) {
|
|
|
1540
1616
|
return parseViteConfig(filePath, code).body.some((statement) => statement.type === "ExpressionStatement" && statement.expression.type === "AssignmentExpression" && statement.expression.left.type === "MemberExpression" && statement.expression.left.object.type === "Identifier" && statement.expression.left.object.name === "module" && statement.expression.left.property.type === "Identifier" && statement.expression.left.property.name === "exports");
|
|
1541
1617
|
}
|
|
1542
1618
|
//#endregion
|
|
1543
|
-
export { compactResourceName, cssModulesConfigSource, generateAppRouterViteConfig, generatePagesRouterViteConfig, generateResponseStoreWranglerConfig, generateWranglerConfig, getWranglerImagesBinding, getWranglerVersionMetadataBinding, setupCloudflarePlatform, updateViteConfigForCloudflare, updateViteConfigForCssModules, updateWranglerConfigForCloudflare, usesCommonJsViteConfig, validateCloudflarePlatformSetup };
|
|
1619
|
+
export { compactResourceName, cssModulesConfigSource, findConfigKeepingWorkerName, generateAppRouterViteConfig, generatePagesRouterViteConfig, generateResponseStoreWranglerConfig, generateWranglerConfig, getWranglerImagesBinding, getWranglerVersionMetadataBinding, setupCloudflarePlatform, updateViteConfigForCloudflare, updateViteConfigForCssModules, updateWranglerConfigForCloudflare, usesCommonJsViteConfig, validateCloudflarePlatformSetup };
|
package/dist/init-platform.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export type CloudflareInitOptions = {
|
|
|
13
13
|
warmCdnCache?: boolean;
|
|
14
14
|
legacyWrangler?: boolean;
|
|
15
15
|
prerender?: boolean;
|
|
16
|
+
/** Worker name for generated config, instead of one derived from package.json. */
|
|
17
|
+
name?: string;
|
|
16
18
|
};
|
|
17
19
|
export declare const INIT_PLATFORMS: {
|
|
18
20
|
cloudflare: {
|
|
@@ -38,6 +40,8 @@ export type ResolvedInitOptions = {
|
|
|
38
40
|
};
|
|
39
41
|
export declare function isAgentEnvironment(env?: Record<string, string | undefined>): boolean;
|
|
40
42
|
export declare function parsePlatformArg(args: string[]): InitPlatform | undefined;
|
|
43
|
+
export declare function parseNameArg(args: string[]): string | undefined;
|
|
44
|
+
export declare function validateWorkerName(value: string): void;
|
|
41
45
|
export declare function parseDataCacheArg(args: string[]): InitDataCache | undefined;
|
|
42
46
|
export declare function parseCdnCacheArg(args: string[]): InitCdnCache | undefined;
|
|
43
47
|
export declare function parseImageOptimizationArg(args: string[]): InitImageOptimization | undefined;
|
package/dist/init-platform.js
CHANGED
|
@@ -31,6 +31,28 @@ function parsePlatformArg(args) {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
const WORKER_NAME_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
35
|
+
const WORKER_NAME_MAX_LENGTH = 63;
|
|
36
|
+
function parseNameArg(args) {
|
|
37
|
+
for (let index = 0; index < args.length; index++) {
|
|
38
|
+
const arg = args[index];
|
|
39
|
+
let value;
|
|
40
|
+
if (arg === "--name") {
|
|
41
|
+
value = args[index + 1];
|
|
42
|
+
if (!value || value.startsWith("-")) throw new Error("--name requires a Worker name.");
|
|
43
|
+
} else if (arg.startsWith("--name=")) {
|
|
44
|
+
value = arg.slice(7);
|
|
45
|
+
if (!value) throw new Error("--name requires a Worker name.");
|
|
46
|
+
}
|
|
47
|
+
if (value) {
|
|
48
|
+
validateWorkerName(value);
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function validateWorkerName(value) {
|
|
54
|
+
if (value.length > WORKER_NAME_MAX_LENGTH || !WORKER_NAME_PATTERN.test(value)) throw new Error(`Invalid --name value "${value}". Worker names must be at most ${WORKER_NAME_MAX_LENGTH} characters of lowercase letters, numbers, and dashes, and cannot start or end with a dash.`);
|
|
55
|
+
}
|
|
34
56
|
function parseChoiceArg(args, flag, choices, displayedChoices = choices) {
|
|
35
57
|
for (let index = 0; index < args.length; index++) {
|
|
36
58
|
const arg = args[index];
|
|
@@ -115,10 +137,12 @@ async function resolveInitPlatform(args, options = {}) {
|
|
|
115
137
|
}
|
|
116
138
|
async function resolveInitOptions(args, options = {}) {
|
|
117
139
|
const legacyWrangler = parseBooleanArg(args, "--legacy-wrangler-cloudflare-init", void 0, "--legacy-wrangler-cloudflare-init expects true or false when using the \"--legacy-wrangler-cloudflare-init=value\" form.");
|
|
140
|
+
const name = parseNameArg(args);
|
|
118
141
|
const platform = legacyWrangler && !parsePlatformArg(args) ? "cloudflare" : await resolveInitPlatform(args, options);
|
|
119
142
|
const platformOptions = await INIT_PLATFORMS[platform].options(args, options);
|
|
120
143
|
const explicitWarmCdnCache = parseWarmCdnCacheArg(args);
|
|
121
144
|
if (legacyWrangler && platform !== "cloudflare") throw new Error("--legacy-wrangler-cloudflare-init requires --platform=cloudflare.");
|
|
145
|
+
if (name && platform !== "cloudflare") throw new Error("--name requires --platform=cloudflare.");
|
|
122
146
|
const explicitPrerender = parsePrerenderArg(args);
|
|
123
147
|
if (platform === "cloudflare" && platformOptions?.cdnCache === "static-assets" && explicitPrerender === false) throw new Error("--no-prerender cannot be used with --cdn-cache=static-assets, which requires build-time prerendering.");
|
|
124
148
|
const supportsWarmCdnCache = platformOptions?.cdnCache === "response-store" || platformOptions?.cdnCache === "workers-cache";
|
|
@@ -134,7 +158,8 @@ async function resolveInitOptions(args, options = {}) {
|
|
|
134
158
|
...platformOptions,
|
|
135
159
|
warmCdnCache,
|
|
136
160
|
...legacyWrangler ? { legacyWrangler } : {},
|
|
137
|
-
...prerender ? { prerender: true } : {}
|
|
161
|
+
...prerender ? { prerender: true } : {},
|
|
162
|
+
...name ? { name } : {}
|
|
138
163
|
} : void 0
|
|
139
164
|
};
|
|
140
165
|
}
|
|
@@ -314,4 +339,4 @@ async function resolveCloudflareInitOptions(args, options = {}) {
|
|
|
314
339
|
}
|
|
315
340
|
}
|
|
316
341
|
//#endregion
|
|
317
|
-
export { INIT_PLATFORMS, isAgentEnvironment, parseCdnCacheArg, parseDataCacheArg, parseImageOptimizationArg, parsePlatformArg, parsePrerenderArg, parseResponseStoreModeArg, parseWarmCdnCacheArg, resolveCloudflareInitOptions, resolveInitOptions, resolveInitPlatform, resolveInitPrerender, resolveInitWarmCdnCache };
|
|
342
|
+
export { INIT_PLATFORMS, isAgentEnvironment, parseCdnCacheArg, parseDataCacheArg, parseImageOptimizationArg, parseNameArg, parsePlatformArg, parsePrerenderArg, parseResponseStoreModeArg, parseWarmCdnCacheArg, resolveCloudflareInitOptions, resolveInitOptions, resolveInitPlatform, resolveInitPrerender, resolveInitWarmCdnCache, validateWorkerName };
|
package/dist/init.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export declare function addScripts(root: string, port?: number | false, platform
|
|
|
64
64
|
warmCdnCache?: boolean;
|
|
65
65
|
legacyWrangler?: boolean;
|
|
66
66
|
scriptNames?: "namespaced" | "standard";
|
|
67
|
+
workerName?: string;
|
|
67
68
|
}): string[];
|
|
68
69
|
export type InitDependencyGroups = {
|
|
69
70
|
dependencies: string[];
|
package/dist/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path, { toSlash } from "./deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { detectPackageManager, detectPackageManagerName, detectProject, ensureESModule, findViteConfigPath, hasViteConfig, renameCJSConfigs } from "./utils/project.js";
|
|
3
|
-
import { compactResourceName, cssModulesConfigSource, setupCloudflarePlatform, updateViteConfigForCssModules, usesCommonJsViteConfig, validateCloudflarePlatformSetup } from "./init-cloudflare.js";
|
|
3
|
+
import { compactResourceName, cssModulesConfigSource, findConfigKeepingWorkerName, setupCloudflarePlatform, updateViteConfigForCssModules, usesCommonJsViteConfig, validateCloudflarePlatformSetup } from "./init-cloudflare.js";
|
|
4
4
|
import { getReactUpgradeDeps } from "./utils/react-version.js";
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import { spawn, spawnSync } from "node:child_process";
|
|
@@ -123,7 +123,7 @@ function addScripts(root, port, platform = "node", options = {}) {
|
|
|
123
123
|
if (platform === "cloudflare") {
|
|
124
124
|
addScript("deploy", !options.legacyWrangler ? options.warmCdnCache ? "vinext-cloudflare deploy --warm-cache" : "vinext-cloudflare deploy" : options.warmCdnCache ? "vinext-cloudflare deploy --config dist/server/wrangler.json --warm-cache" : "vinext-cloudflare deploy --config dist/server/wrangler.json");
|
|
125
125
|
if (options.deployResponseStore && !pkg.scripts["deploy:response-store"]) {
|
|
126
|
-
pkg.scripts["deploy:response-store"] = !options.legacyWrangler ? `cf deploy --prebuilt --mode production --worker ${compactResourceName(detectProject(root).projectName, "-response-store", 63)}` : "wrangler deploy --config wrangler.response-store.jsonc";
|
|
126
|
+
pkg.scripts["deploy:response-store"] = !options.legacyWrangler ? `cf deploy --prebuilt --mode production --worker ${compactResourceName(options.workerName ?? detectProject(root).projectName, "-response-store", 63)}` : "wrangler deploy --config wrangler.response-store.jsonc";
|
|
127
127
|
added.push("deploy:response-store");
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -302,6 +302,64 @@ function updateGitignore(root, platform = "node", legacyWrangler = false) {
|
|
|
302
302
|
fs.writeFileSync(gitignorePath, content + separator + missingEntries.join("\n") + "\n", "utf-8");
|
|
303
303
|
return true;
|
|
304
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Read `output` from the Next.js config as `vinext build` does: an inline
|
|
307
|
+
* `vinext({ nextConfig })` in the Vite config wins over next.config, and both
|
|
308
|
+
* are evaluated with NODE_ENV set to production and `.env.production` loaded as
|
|
309
|
+
* the build loads it. The Vite config is read as written, without running
|
|
310
|
+
* plugin `config` hooks, so a plugin that changes `root`, `envDir` or `mode` is
|
|
311
|
+
* not seen. A config that cannot load here keeps the Worker-first default.
|
|
312
|
+
* The loader is imported lazily because it needs Vite, which create-vinext-app
|
|
313
|
+
* runs without.
|
|
314
|
+
*/
|
|
315
|
+
async function resolvesToStaticExport(root, viteConfigPath) {
|
|
316
|
+
let configModule;
|
|
317
|
+
let dotenvModule;
|
|
318
|
+
try {
|
|
319
|
+
[configModule, dotenvModule] = await Promise.all([import("./config/next-config.js"), import("./config/dotenv.js")]);
|
|
320
|
+
} catch {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
const { findVinextNextConfigInPlugins, loadNextConfig, PHASE_PRODUCTION_BUILD, resolveNextConfigInput } = configModule;
|
|
324
|
+
const savedEnv = { ...process.env };
|
|
325
|
+
Reflect.set(process.env, "NODE_ENV", "production");
|
|
326
|
+
try {
|
|
327
|
+
dotenvModule.loadDotenv({
|
|
328
|
+
root,
|
|
329
|
+
mode: "production"
|
|
330
|
+
});
|
|
331
|
+
let mode = "production";
|
|
332
|
+
let inline = null;
|
|
333
|
+
let configRoot = root;
|
|
334
|
+
let envDir;
|
|
335
|
+
if (viteConfigPath) try {
|
|
336
|
+
const { loadConfigFromFile } = await import("vite");
|
|
337
|
+
const loaded = await loadConfigFromFile({
|
|
338
|
+
command: "build",
|
|
339
|
+
mode: "production",
|
|
340
|
+
isSsrBuild: false,
|
|
341
|
+
isPreview: false
|
|
342
|
+
}, viteConfigPath, root, "silent");
|
|
343
|
+
if (typeof loaded?.config.mode === "string") mode = loaded.config.mode;
|
|
344
|
+
if (typeof loaded?.config.root === "string") configRoot = path.resolve(root, loaded.config.root);
|
|
345
|
+
const configuredEnvDir = loaded?.config.envDir;
|
|
346
|
+
if (configuredEnvDir === false) envDir = false;
|
|
347
|
+
else if (typeof configuredEnvDir === "string") envDir = path.resolve(root, configuredEnvDir);
|
|
348
|
+
inline = await findVinextNextConfigInPlugins(loaded?.config.plugins);
|
|
349
|
+
} catch {}
|
|
350
|
+
if (envDir !== false) dotenvModule.loadDotenv({
|
|
351
|
+
root: envDir ?? configRoot,
|
|
352
|
+
mode
|
|
353
|
+
});
|
|
354
|
+
Reflect.set(process.env, "NODE_ENV", "production");
|
|
355
|
+
return (inline ? await resolveNextConfigInput(inline, PHASE_PRODUCTION_BUILD) : await loadNextConfig(configRoot, PHASE_PRODUCTION_BUILD))?.output === "export";
|
|
356
|
+
} catch {
|
|
357
|
+
return false;
|
|
358
|
+
} finally {
|
|
359
|
+
for (const key of Object.keys(process.env)) if (!Object.hasOwn(savedEnv, key)) delete process.env[key];
|
|
360
|
+
Object.assign(process.env, savedEnv);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
305
363
|
function setupNodePlatform(context) {
|
|
306
364
|
if (context.viteConfigExists && !context.force) {
|
|
307
365
|
if (context.hasCssModules && context.existingViteConfigPath) {
|
|
@@ -389,14 +447,17 @@ async function init(options) {
|
|
|
389
447
|
const hasCssModules = !options.skipCssModules && scanCssModuleFiles(root);
|
|
390
448
|
const pmName = detectPackageManagerName(root);
|
|
391
449
|
const shouldInstall = options.install ?? true;
|
|
450
|
+
const isStaticExport = platform === "cloudflare" && await resolvesToStaticExport(root, existingViteConfigPath);
|
|
392
451
|
if (platform === "cloudflare") validateCloudflarePlatformSetup({
|
|
393
452
|
root,
|
|
394
453
|
isAppRouter: isApp,
|
|
395
454
|
existingViteConfigPath,
|
|
396
455
|
hasCssModules,
|
|
456
|
+
isStaticExport,
|
|
397
457
|
today: options._today
|
|
398
458
|
}, cloudflareOptions);
|
|
399
459
|
else if (hasCssModules && existingViteConfigPath && !options.force) updateViteConfigForCssModules(existingViteConfigPath, fs.readFileSync(existingViteConfigPath, "utf-8"));
|
|
460
|
+
const configKeepingWorkerName = platform === "cloudflare" ? findConfigKeepingWorkerName(root, cloudflareOptions) : void 0;
|
|
400
461
|
if (!options.skipCheck) {
|
|
401
462
|
console.log(" Running compatibility check...\n");
|
|
402
463
|
const { runCheck, formatReport } = await import("./check.js");
|
|
@@ -417,7 +478,8 @@ async function init(options) {
|
|
|
417
478
|
deployResponseStore,
|
|
418
479
|
warmCdnCache: options.cloudflare?.warmCdnCache ?? false,
|
|
419
480
|
legacyWrangler: options.cloudflare?.legacyWrangler,
|
|
420
|
-
scriptNames: options.scriptNames
|
|
481
|
+
scriptNames: options.scriptNames,
|
|
482
|
+
workerName: configKeepingWorkerName ? void 0 : options.cloudflare?.name
|
|
421
483
|
});
|
|
422
484
|
const setupContext = {
|
|
423
485
|
root,
|
|
@@ -428,6 +490,7 @@ async function init(options) {
|
|
|
428
490
|
force: options.force ?? false,
|
|
429
491
|
prerender: options.prerender,
|
|
430
492
|
hasCssModules,
|
|
493
|
+
isStaticExport,
|
|
431
494
|
today: options._today
|
|
432
495
|
};
|
|
433
496
|
const platformSetup = platform === "cloudflare" ? setupCloudflarePlatform(setupContext, cloudflareOptions) : setupNodePlatform(setupContext);
|
|
@@ -513,6 +576,7 @@ async function init(options) {
|
|
|
513
576
|
if (skippedViteConfig) console.log(` ${terminalStyle.yellow("-")} Skipped vite.config.ts (already exists, use --force to overwrite)`);
|
|
514
577
|
if (updatedGitignore) console.log(` ${terminalStyle.green("✓")} Added vinext output directories to .gitignore`);
|
|
515
578
|
if (hasCssModules) console.log(` ${terminalStyle.green("✓")} Configured vite-css-modules for CSS Modules`);
|
|
579
|
+
if (configKeepingWorkerName) console.log(` ${terminalStyle.yellow("!")} Kept the Worker name in the existing ${configKeepingWorkerName}; --name was not applied, so update it there if it should be "${cloudflareOptions.name}"`);
|
|
516
580
|
if (platformSetup.preservedExistingGenerateScopedName) console.log(` ${terminalStyle.yellow("!")} Preserved existing css.modules.generateScopedName; verify it produces identical class names in SSR and client builds`);
|
|
517
581
|
const nextSteps = [...platformSetup.nextSteps];
|
|
518
582
|
if (dependencyInstallNeedsApproval) nextSteps.push("Dependency installation is incomplete because pnpm blocked dependency build scripts:", "1. Review and approve the required build scripts:", " pnpm approve-builds", "2. Finish installing dependencies:", " pnpm install");
|
|
@@ -11,4 +11,11 @@ export declare function collectDirectScopeBindings(node: ESTree.Node, scope: Ast
|
|
|
11
11
|
export declare function collectLoopScopeBindings(node: ESTree.ForStatement | ESTree.ForInStatement | ESTree.ForOfStatement, scope: AstScope, onVariableDeclarator?: (declaration: ESTree.VariableDeclaration, declarator: ESTree.VariableDeclarator) => void): void;
|
|
12
12
|
export declare function collectSwitchScopeBindings(node: ESTree.SwitchStatement, scope: AstScope, onVariableDeclarator?: (declaration: ESTree.VariableDeclaration, declarator: ESTree.VariableDeclarator) => void): void;
|
|
13
13
|
export declare function collectVarScopeBindings(node: ESTree.Node, scope: AstScope, root?: boolean): void;
|
|
14
|
+
/** The nearest scope declaring `name`, or `null` for an unbound (global) name. */
|
|
15
|
+
export declare function findAstBindingScope(scope: AstScope, name: string): AstScope | null;
|
|
16
|
+
/**
|
|
17
|
+
* Visit every node with the scope it is evaluated in. The root scope holds the
|
|
18
|
+
* program's own bindings, including every `var` outside a function.
|
|
19
|
+
*/
|
|
20
|
+
export declare function walkAstScopes(root: ESTree.Program, visitor: (node: ESTree.Node, scope: AstScope) => void): AstScope;
|
|
14
21
|
//#endregion
|
|
@@ -23,7 +23,7 @@ function collectDirectScopeBindings(node, scope, onVariableDeclarator) {
|
|
|
23
23
|
for (const specifier of declaration.specifiers) if (specifier.type !== "ImportSpecifier" || specifier.importKind !== "type") collectBindingNames(specifier.local, scope.bindings);
|
|
24
24
|
} else if (declaration.type === "TSImportEqualsDeclaration" && declaration.importKind !== "type") collectBindingNames(declaration.id, scope.bindings);
|
|
25
25
|
else if (declaration.type === "VariableDeclaration" && declaration.declare !== true) for (const declarator of declaration.declarations) {
|
|
26
|
-
collectBindingNames(declarator.id, scope.bindings);
|
|
26
|
+
if (declaration.kind !== "var") collectBindingNames(declarator.id, scope.bindings);
|
|
27
27
|
onVariableDeclarator?.(declaration, declarator);
|
|
28
28
|
}
|
|
29
29
|
else if ((declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") && declaration.declare !== true) collectBindingNames(declaration.id, scope.bindings);
|
|
@@ -34,7 +34,7 @@ function collectLoopScopeBindings(node, scope, onVariableDeclarator) {
|
|
|
34
34
|
const declarationValue = node.type === "ForStatement" ? node.init : node.left;
|
|
35
35
|
if (!declarationValue || declarationValue.type !== "VariableDeclaration" || declarationValue.declare === true) return;
|
|
36
36
|
for (const declarator of declarationValue.declarations) {
|
|
37
|
-
collectBindingNames(declarator.id, scope.bindings);
|
|
37
|
+
if (declarationValue.kind !== "var") collectBindingNames(declarator.id, scope.bindings);
|
|
38
38
|
onVariableDeclarator?.(declarationValue, declarator);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -46,5 +46,61 @@ function collectVarScopeBindings(node, scope, root = true) {
|
|
|
46
46
|
if (node.type === "VariableDeclaration" && node.kind === "var" && node.declare !== true) for (const declarator of node.declarations) collectBindingNames(declarator.id, scope.bindings);
|
|
47
47
|
forEachAstChild(node, (child) => collectVarScopeBindings(child, scope, false));
|
|
48
48
|
}
|
|
49
|
+
/** The nearest scope declaring `name`, or `null` for an unbound (global) name. */
|
|
50
|
+
function findAstBindingScope(scope, name) {
|
|
51
|
+
for (let current = scope; current; current = current.parent) if (current.bindings.has(name)) return current;
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Visit every node with the scope it is evaluated in. The root scope holds the
|
|
56
|
+
* program's own bindings, including every `var` outside a function.
|
|
57
|
+
*/
|
|
58
|
+
function walkAstScopes(root, visitor) {
|
|
59
|
+
const rootScope = createAstScope(null);
|
|
60
|
+
collectDirectScopeBindings(root, rootScope);
|
|
61
|
+
collectVarScopeBindings(root, rootScope);
|
|
62
|
+
function visit(node, parentScope) {
|
|
63
|
+
visitor(node, parentScope);
|
|
64
|
+
let scope = parentScope;
|
|
65
|
+
if (isFunctionNode(node)) {
|
|
66
|
+
const parameterScope = createAstScope(parentScope);
|
|
67
|
+
if (node.type === "FunctionExpression") collectBindingNames(node.id, parameterScope.bindings);
|
|
68
|
+
for (const parameter of node.params) collectBindingNames(parameter, parameterScope.bindings);
|
|
69
|
+
if (node.id) visit(node.id, node.type === "FunctionExpression" ? parameterScope : parentScope);
|
|
70
|
+
for (const parameter of node.params) visit(parameter, parameterScope);
|
|
71
|
+
if (!node.body) return;
|
|
72
|
+
const bodyScope = createAstScope(parameterScope);
|
|
73
|
+
collectDirectScopeBindings(node.body, bodyScope);
|
|
74
|
+
collectVarScopeBindings(node.body, bodyScope);
|
|
75
|
+
if (node.body.type === "BlockStatement") for (const statement of node.body.body) visit(statement, bodyScope);
|
|
76
|
+
else visit(node.body, bodyScope);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (node.type === "SwitchStatement") {
|
|
80
|
+
visit(node.discriminant, parentScope);
|
|
81
|
+
const switchScope = createAstScope(parentScope);
|
|
82
|
+
collectSwitchScopeBindings(node, switchScope);
|
|
83
|
+
for (const switchCase of node.cases) visit(switchCase, switchScope);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (node.type === "BlockStatement" || node.type === "StaticBlock" || node.type === "TSModuleBlock") {
|
|
87
|
+
scope = createAstScope(parentScope);
|
|
88
|
+
collectDirectScopeBindings(node, scope);
|
|
89
|
+
if (node.type === "StaticBlock" || node.type === "TSModuleBlock") collectVarScopeBindings(node, scope);
|
|
90
|
+
} else if (node.type === "CatchClause") {
|
|
91
|
+
scope = createAstScope(parentScope);
|
|
92
|
+
collectBindingNames(node.param, scope.bindings);
|
|
93
|
+
} else if (node.type === "ForStatement" || node.type === "ForInStatement" || node.type === "ForOfStatement") {
|
|
94
|
+
scope = createAstScope(parentScope);
|
|
95
|
+
collectLoopScopeBindings(node, scope);
|
|
96
|
+
} else if (node.type === "ClassExpression" && node.id) {
|
|
97
|
+
scope = createAstScope(parentScope);
|
|
98
|
+
collectBindingNames(node.id, scope.bindings);
|
|
99
|
+
}
|
|
100
|
+
forEachAstChild(node, (child) => visit(child, scope));
|
|
101
|
+
}
|
|
102
|
+
for (const statement of root.body) visit(statement, rootScope);
|
|
103
|
+
return rootScope;
|
|
104
|
+
}
|
|
49
105
|
//#endregion
|
|
50
|
-
export { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, createAstScope, hasAstBinding, isFunctionNode };
|
|
106
|
+
export { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, createAstScope, findAstBindingScope, hasAstBinding, isFunctionNode, walkAstScopes };
|
|
@@ -14,6 +14,6 @@ export declare function readFlightCodecVersion(id: string): string;
|
|
|
14
14
|
* minimum supported version.
|
|
15
15
|
* https://github.com/facebook/react/blob/v19.3.0/packages/react-client/src/ReactFlightReplyClient.js#L486
|
|
16
16
|
*/
|
|
17
|
-
export declare function patchCacheFlightCodec(code: string, id: string, version?: string): MagicStringTransformResult | null;
|
|
17
|
+
export declare function patchCacheFlightCodec(code: string, id: string, version?: string): MagicStringTransformResult<import("magic-string").SourceMap> | null;
|
|
18
18
|
export declare function cacheFlightCodecPlugin(): Plugin;
|
|
19
19
|
//#endregion
|
|
@@ -7,5 +7,5 @@ type TransformResult = {
|
|
|
7
7
|
};
|
|
8
8
|
type ResolveDynamicImport = (specifier: string, importer: string) => Promise<string | null>;
|
|
9
9
|
export declare function transformNextDynamicPreloadMetadata(code: string, id: string, root: string, resolveDynamicImport: ResolveDynamicImport): Promise<TransformResult | null>;
|
|
10
|
-
export declare function createDynamicPreloadMetadataPlugin(): Plugin;
|
|
10
|
+
export declare function createDynamicPreloadMetadataPlugin(getTranspiledPackages: () => readonly string[]): Plugin;
|
|
11
11
|
//#endregion
|