@qzsy/vinext 0.1.12 → 0.1.81
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 +19 -5
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +11 -4
- package/dist/build/report.d.ts +2 -1
- package/dist/build/report.js +2 -1
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +9 -0
- package/dist/build/standalone.js +2 -0
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +64 -28
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/cloudflare/deploy-config.d.ts +51 -0
- package/dist/cloudflare/deploy-config.js +153 -0
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.js +1 -1
- package/dist/cloudflare/project.d.ts +41 -0
- package/dist/cloudflare/project.js +243 -0
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/deploy.d.ts +2 -122
- package/dist/deploy.js +20 -793
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +70 -12
- package/dist/entries/app-rsc-manifest.js +8 -0
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +2 -1
- package/dist/entries/pages-server-entry.js +6 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +50 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +160 -160
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +1000 -0
- package/dist/init-platform.d.ts +38 -0
- package/dist/init-platform.js +150 -0
- package/dist/init.d.ts +14 -37
- package/dist/init.js +205 -95
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.js +3 -0
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +13 -2
- package/dist/routing/app-route-graph.js +116 -32
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/app-browser-action-result.d.ts +2 -1
- package/dist/server/app-browser-action-result.js +5 -1
- package/dist/server/app-browser-entry.js +17 -12
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.js +1 -0
- package/dist/server/app-browser-server-action-client.js +2 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -2
- package/dist/server/app-fallback-renderer.js +12 -7
- package/dist/server/app-middleware.d.ts +2 -3
- package/dist/server/app-middleware.js +3 -2
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +12 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +4 -1
- package/dist/server/app-page-dispatch.d.ts +11 -3
- package/dist/server/app-page-dispatch.js +55 -15
- package/dist/server/app-page-element-builder.d.ts +5 -1
- package/dist/server/app-page-element-builder.js +57 -20
- package/dist/server/app-page-head.d.ts +12 -0
- package/dist/server/app-page-head.js +42 -19
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +8 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +89 -13
- package/dist/server/app-page-route-wiring.d.ts +6 -1
- package/dist/server/app-page-route-wiring.js +31 -15
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-segment-state.js +2 -0
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.d.ts +12 -0
- package/dist/server/app-router-entry.js +22 -8
- package/dist/server/app-router-image-optimization.d.ts +37 -0
- package/dist/server/app-router-image-optimization.js +40 -0
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.js +27 -14
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +106 -33
- package/dist/server/app-ssr-entry.js +12 -1
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-response-headers.d.ts +19 -0
- package/dist/server/dev-response-headers.js +78 -0
- package/dist/server/dev-server.js +8 -15
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/headers.d.ts +7 -15
- package/dist/server/headers.js +6 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-page-data.d.ts +23 -1
- package/dist/server/pages-page-data.js +43 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +10 -4
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +47 -25
- package/dist/server/request-log.d.ts +5 -14
- package/dist/server/request-log.js +7 -1
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/server-action-logger.d.ts +39 -0
- package/dist/server/server-action-logger.js +104 -0
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image-optimization-url.d.ts +4 -0
- package/dist/shims/image-optimization-url.js +33 -1
- package/dist/shims/image.js +46 -13
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -5
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/link.js +23 -16
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.js +4 -2
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +2 -5
- package/dist/shims/router.js +41 -22
- package/dist/shims/server.js +3 -2
- package/dist/typegen.js +6 -5
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +9 -1
- package/dist/utils/project.js +21 -4
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +29 -23
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
import { collectBindingNames, forEachAstChild, hasRange, isAstRecord, isIdentifierNamed, nodeArray } from "./ast-utils.js";
|
|
2
|
+
import { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, hasAstBinding, isFunctionNode } from "./ast-scope.js";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { parseAst } from "vite";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import MagicString from "magic-string";
|
|
7
|
+
//#region src/plugins/ignore-dynamic-requests.ts
|
|
8
|
+
const DYNAMIC_REQUEST_ERROR = "Cannot find module as expression is too dynamic";
|
|
9
|
+
const MAX_CONSTANT_BINDING_DEPTH = 1500;
|
|
10
|
+
const VINEXT_SOURCE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
|
+
const PLUGIN_RSC_PATH = /[\\/]node_modules[\\/](?:\.pnpm[\\/][^/\\]+[\\/]node_modules[\\/])?@vitejs[\\/]plugin-rsc[\\/]/;
|
|
12
|
+
const TRANSFORMABLE_EXTENSIONS = new Set([
|
|
13
|
+
".js",
|
|
14
|
+
".jsx",
|
|
15
|
+
".mjs",
|
|
16
|
+
".cjs",
|
|
17
|
+
".ts",
|
|
18
|
+
".tsx",
|
|
19
|
+
".mts",
|
|
20
|
+
".cts"
|
|
21
|
+
]);
|
|
22
|
+
const TRANSPARENT_EXPRESSIONS = new Set([
|
|
23
|
+
"ChainExpression",
|
|
24
|
+
"ParenthesizedExpression",
|
|
25
|
+
"TSAsExpression",
|
|
26
|
+
"TSInstantiationExpression",
|
|
27
|
+
"TSNonNullExpression",
|
|
28
|
+
"TSSatisfiesExpression",
|
|
29
|
+
"TSTypeAssertion"
|
|
30
|
+
]);
|
|
31
|
+
function astNode(value) {
|
|
32
|
+
return isAstRecord(value) ? value : null;
|
|
33
|
+
}
|
|
34
|
+
function unwrapExpression(value) {
|
|
35
|
+
const node = astNode(value);
|
|
36
|
+
if (!node || !TRANSPARENT_EXPRESSIONS.has(node.type)) return node;
|
|
37
|
+
return unwrapExpression(node.expression);
|
|
38
|
+
}
|
|
39
|
+
function stringValue(node) {
|
|
40
|
+
if ((node.type === "Literal" || node.type === "StringLiteral") && typeof node.value === "string") return node.value;
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function isUnboundNumericGlobal(node, scope) {
|
|
44
|
+
return node.type === "Identifier" && typeof node.name === "string" && !hasAstBinding(scope, node.name) && (isIdentifierNamed(node, "NaN") || isIdentifierNamed(node, "Infinity"));
|
|
45
|
+
}
|
|
46
|
+
function staticStringValue(value, scope, resolution) {
|
|
47
|
+
const node = unwrapExpression(value);
|
|
48
|
+
if (!node) return null;
|
|
49
|
+
const valueString = stringValue(node);
|
|
50
|
+
if (valueString !== null) return valueString;
|
|
51
|
+
if (node.type === "TemplateLiteral" && nodeArray(node.expressions).length === 0) {
|
|
52
|
+
const quasiValue = astNode(nodeArray(node.quasis)[0])?.value;
|
|
53
|
+
const cooked = typeof quasiValue === "object" && quasiValue !== null ? Reflect.get(quasiValue, "cooked") : null;
|
|
54
|
+
const raw = typeof quasiValue === "object" && quasiValue !== null ? Reflect.get(quasiValue, "raw") : null;
|
|
55
|
+
return typeof cooked === "string" ? cooked : typeof raw === "string" ? raw : null;
|
|
56
|
+
}
|
|
57
|
+
if (node.type === "BinaryExpression" && node.operator === "+") {
|
|
58
|
+
const left = staticStringValue(node.left, scope, resolution);
|
|
59
|
+
const right = staticStringValue(node.right, scope, resolution);
|
|
60
|
+
return left === null || right === null ? null : left + right;
|
|
61
|
+
}
|
|
62
|
+
if (node.type === "ConditionalExpression") {
|
|
63
|
+
const truthiness = staticTruthiness(node.test, scope, resolution);
|
|
64
|
+
if (truthiness !== null) return staticStringValue(truthiness ? node.consequent : node.alternate, scope, resolution);
|
|
65
|
+
const consequent = staticStringValue(node.consequent, scope, resolution);
|
|
66
|
+
const alternate = staticStringValue(node.alternate, scope, resolution);
|
|
67
|
+
return consequent !== null && consequent === alternate ? consequent : null;
|
|
68
|
+
}
|
|
69
|
+
if (node.type === "SequenceExpression") return staticStringValue(nodeArray(node.expressions).at(-1), scope, resolution);
|
|
70
|
+
if (node.type === "Identifier" && typeof node.name === "string") return resolveConstantBinding(scope, node.name, resolution, null, staticStringValue);
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
function hasSignificantPathPart(value) {
|
|
74
|
+
const normalized = value.replaceAll("\\", "/");
|
|
75
|
+
return normalized !== "" && normalized !== "/";
|
|
76
|
+
}
|
|
77
|
+
function templateElementValue(quasi, raw) {
|
|
78
|
+
const value = quasi?.value;
|
|
79
|
+
if (typeof value !== "object" || value === null) return "";
|
|
80
|
+
const elementValue = Reflect.get(value, raw ? "raw" : "cooked");
|
|
81
|
+
return typeof elementValue === "string" ? elementValue : "";
|
|
82
|
+
}
|
|
83
|
+
function isUnboundStringRawTag(value, scope) {
|
|
84
|
+
const tag = unwrapExpression(value);
|
|
85
|
+
const object = tag?.type === "MemberExpression" ? unwrapExpression(tag.object) : null;
|
|
86
|
+
const property = tag?.type === "MemberExpression" ? unwrapExpression(tag.property) : null;
|
|
87
|
+
return tag?.type === "MemberExpression" && tag.computed !== true && isIdentifierNamed(object, "String") && !hasAstBinding(scope, "String") && isIdentifierNamed(property, "raw");
|
|
88
|
+
}
|
|
89
|
+
function hasDynamicRequestIgnoreDirective(code, requestNode, argumentNode) {
|
|
90
|
+
if (!hasRange(requestNode) || !hasRange(argumentNode)) return false;
|
|
91
|
+
const comments = [];
|
|
92
|
+
const callee = astNode(requestNode.callee);
|
|
93
|
+
let index = callee && hasRange(callee) ? callee.end : requestNode.type === "ImportExpression" ? requestNode.start + 6 : requestNode.start;
|
|
94
|
+
while (index < argumentNode.start) {
|
|
95
|
+
if (/\s/.test(code[index])) {
|
|
96
|
+
index++;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (code.startsWith("/*", index)) {
|
|
100
|
+
const end = code.indexOf("*/", index + 2);
|
|
101
|
+
if (end === -1 || end + 2 > argumentNode.start) return false;
|
|
102
|
+
index = end + 2;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (code.startsWith("//", index)) {
|
|
106
|
+
while (index < argumentNode.start && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
if (code[index] !== "(") return false;
|
|
112
|
+
index++;
|
|
113
|
+
while (index < argumentNode.start) {
|
|
114
|
+
if (/\s/.test(code[index])) {
|
|
115
|
+
index++;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (code.startsWith("/*", index)) {
|
|
119
|
+
const end = code.indexOf("*/", index + 2);
|
|
120
|
+
if (end === -1 || end + 2 > argumentNode.start) return false;
|
|
121
|
+
comments.push(code.slice(index + 2, end));
|
|
122
|
+
index = end + 2;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (code.startsWith("//", index)) {
|
|
126
|
+
let end = index + 2;
|
|
127
|
+
while (end < argumentNode.start && code[end] !== "\n" && code[end] !== "\r") end++;
|
|
128
|
+
comments.push(code.slice(index + 2, end));
|
|
129
|
+
index = end;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
let ignore;
|
|
135
|
+
for (const comment of comments) {
|
|
136
|
+
const text = comment.trim();
|
|
137
|
+
if (text === "@vite-ignore" && requestNode.type === "ImportExpression") {
|
|
138
|
+
ignore = true;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const separator = text.indexOf(":");
|
|
142
|
+
if (separator === -1) continue;
|
|
143
|
+
const directive = text.slice(0, separator).trim();
|
|
144
|
+
if (directive !== "webpackIgnore" && directive !== "turbopackIgnore") continue;
|
|
145
|
+
const value = text.slice(separator + 1).trim();
|
|
146
|
+
if (value === "true") ignore = true;
|
|
147
|
+
else if (value === "false") ignore = false;
|
|
148
|
+
}
|
|
149
|
+
return ignore === true;
|
|
150
|
+
}
|
|
151
|
+
function templateHasStaticPart(node, scope, resolution, useRaw = false) {
|
|
152
|
+
const quasis = nodeArray(node.quasis).filter(isAstRecord);
|
|
153
|
+
if (nodeArray(node.expressions).length === 0) return templateElementValue(quasis[0], useRaw).replaceAll("\\", "/") !== "/";
|
|
154
|
+
if (quasis.some((quasi) => hasSignificantPathPart(templateElementValue(quasi, useRaw)))) return true;
|
|
155
|
+
return nodeArray(node.expressions).some((expression) => {
|
|
156
|
+
const expressionNode = unwrapExpression(expression);
|
|
157
|
+
if (!expressionNode) return false;
|
|
158
|
+
return requestHasStaticPart(expressionNode, scope, resolution);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function stringRawTemplateHasStaticPart(node, scope, resolution) {
|
|
162
|
+
if (node.type !== "TaggedTemplateExpression") return null;
|
|
163
|
+
if (!isUnboundStringRawTag(node.tag, scope)) return null;
|
|
164
|
+
const quasi = astNode(node.quasi);
|
|
165
|
+
return quasi?.type === "TemplateLiteral" ? templateHasStaticPart(quasi, scope, resolution, true) : null;
|
|
166
|
+
}
|
|
167
|
+
function isLiteralExpression(value) {
|
|
168
|
+
const node = unwrapExpression(value);
|
|
169
|
+
return node?.type === "Literal" || node?.type === "StringLiteral";
|
|
170
|
+
}
|
|
171
|
+
function isNegativeNumericLiteral(value) {
|
|
172
|
+
const node = unwrapExpression(value);
|
|
173
|
+
if (node?.type !== "UnaryExpression" || node.operator !== "-") return false;
|
|
174
|
+
const argument = unwrapExpression(node.argument);
|
|
175
|
+
return argument?.type === "Literal" && typeof argument.value === "number";
|
|
176
|
+
}
|
|
177
|
+
function templateTruthiness(node, scope, resolution, useRaw = false) {
|
|
178
|
+
if (nodeArray(node.quasis).filter(isAstRecord).some((quasi) => templateElementValue(quasi, useRaw) !== "")) return true;
|
|
179
|
+
let hasUnknownExpression = false;
|
|
180
|
+
for (const expression of nodeArray(node.expressions)) {
|
|
181
|
+
const string = staticStringValue(expression, scope, resolution);
|
|
182
|
+
if (string !== null) {
|
|
183
|
+
if (string !== "") return true;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const expressionNode = unwrapExpression(expression);
|
|
187
|
+
if (isNegativeNumericLiteral(expressionNode) || staticTruthiness(expressionNode, scope, resolution) !== null) return true;
|
|
188
|
+
hasUnknownExpression = true;
|
|
189
|
+
}
|
|
190
|
+
return hasUnknownExpression ? null : false;
|
|
191
|
+
}
|
|
192
|
+
function staticTruthiness(value, scope, resolution = createConstantResolution()) {
|
|
193
|
+
const node = unwrapExpression(value);
|
|
194
|
+
if (!node) return null;
|
|
195
|
+
if (node.type === "Literal" || node.type === "StringLiteral") return Boolean(node.value);
|
|
196
|
+
if (isUnboundNumericGlobal(node, scope)) return true;
|
|
197
|
+
if (node.type === "TemplateLiteral") return templateTruthiness(node, scope, resolution);
|
|
198
|
+
if (node.type === "TaggedTemplateExpression" && isUnboundStringRawTag(node.tag, scope)) {
|
|
199
|
+
const quasi = astNode(node.quasi);
|
|
200
|
+
return quasi?.type === "TemplateLiteral" ? templateTruthiness(quasi, scope, resolution, true) : null;
|
|
201
|
+
}
|
|
202
|
+
if (node.type === "BinaryExpression" && node.operator === "+") {
|
|
203
|
+
const string = staticStringValue(node, scope, resolution);
|
|
204
|
+
return string === null ? null : Boolean(string);
|
|
205
|
+
}
|
|
206
|
+
if (isIdentifierNamed(node, "undefined") && !hasAstBinding(scope, "undefined")) return false;
|
|
207
|
+
if (node.type === "Identifier" && typeof node.name === "string") return resolveConstantBinding(scope, node.name, resolution, null, staticTruthiness);
|
|
208
|
+
if (node.type === "UnaryExpression") {
|
|
209
|
+
if (node.operator === "void") return isLiteralExpression(node.argument) ? false : null;
|
|
210
|
+
if (node.operator === "!") {
|
|
211
|
+
const argumentTruthiness = staticTruthiness(node.argument, scope, resolution);
|
|
212
|
+
return argumentTruthiness === null ? null : !argumentTruthiness;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (node.type === "ArrayExpression" || node.type === "ObjectExpression" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "ClassExpression") return true;
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
function staticNullishness(value, scope, resolution = createConstantResolution()) {
|
|
219
|
+
const node = unwrapExpression(value);
|
|
220
|
+
if (!node) return null;
|
|
221
|
+
if (node.type === "Literal" || node.type === "StringLiteral") return node.value === null;
|
|
222
|
+
if (isUnboundNumericGlobal(node, scope)) return false;
|
|
223
|
+
if (isIdentifierNamed(node, "undefined") && !hasAstBinding(scope, "undefined")) return true;
|
|
224
|
+
if (node.type === "Identifier" && typeof node.name === "string") return resolveConstantBinding(scope, node.name, resolution, null, staticNullishness);
|
|
225
|
+
if (node.type === "UnaryExpression") return node.operator === "void" && isLiteralExpression(node.argument) ? true : null;
|
|
226
|
+
if (node.type === "ArrayExpression" || node.type === "ObjectExpression" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression" || node.type === "ClassExpression" || node.type === "TemplateLiteral") return false;
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
function findConstantBinding(scope, name) {
|
|
230
|
+
for (let current = scope; current; current = current.parent) {
|
|
231
|
+
if (!current.bindings.has(name)) continue;
|
|
232
|
+
return current.constants.get(name) ?? null;
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
function createConstantResolution() {
|
|
237
|
+
return {
|
|
238
|
+
active: /* @__PURE__ */ new Set(),
|
|
239
|
+
steps: 0
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function resolveConstantBinding(scope, name, resolution, fallback, evaluate) {
|
|
243
|
+
const binding = findConstantBinding(scope, name);
|
|
244
|
+
if (!binding || resolution.steps >= MAX_CONSTANT_BINDING_DEPTH || resolution.active.has(binding)) return fallback;
|
|
245
|
+
resolution.steps++;
|
|
246
|
+
resolution.active.add(binding);
|
|
247
|
+
try {
|
|
248
|
+
return evaluate(binding.initializer, binding.scope, resolution);
|
|
249
|
+
} finally {
|
|
250
|
+
resolution.active.delete(binding);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function stringConcatHasStaticPart(node, scope, resolution) {
|
|
254
|
+
if (node.type !== "CallExpression") return null;
|
|
255
|
+
const callee = unwrapExpression(node.callee);
|
|
256
|
+
const property = callee?.type === "MemberExpression" ? unwrapExpression(callee.property) : null;
|
|
257
|
+
if (callee?.type !== "MemberExpression" || (callee.computed === true ? property === null || staticStringValue(property, scope, resolution) !== "concat" : !isIdentifierNamed(property, "concat"))) return null;
|
|
258
|
+
const receiver = unwrapExpression(callee.object);
|
|
259
|
+
if (!receiver || !isStaticStringExpression(receiver, scope, resolution)) return null;
|
|
260
|
+
if (requestHasStaticPart(receiver, scope, resolution)) return true;
|
|
261
|
+
return nodeArray(node.arguments).some((argument) => {
|
|
262
|
+
const argumentNode = unwrapExpression(argument);
|
|
263
|
+
return argumentNode ? requestHasStaticPart(argumentNode, scope, resolution) : false;
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
function isStaticStringExpression(value, scope, resolution) {
|
|
267
|
+
const node = unwrapExpression(value);
|
|
268
|
+
if (!node) return false;
|
|
269
|
+
if (stringValue(node) !== null || node.type === "TemplateLiteral") return true;
|
|
270
|
+
if (node.type === "Identifier" && typeof node.name === "string") return resolveConstantBinding(scope, node.name, resolution, false, isStaticStringExpression);
|
|
271
|
+
if (node.type === "BinaryExpression" && node.operator === "+") return additionContainsString(node, scope, resolution);
|
|
272
|
+
if (node.type === "ConditionalExpression") return isStaticStringExpression(node.consequent, scope, resolution) && isStaticStringExpression(node.alternate, scope, resolution);
|
|
273
|
+
if (node.type === "SequenceExpression") return isStaticStringExpression(nodeArray(node.expressions).at(-1), scope, resolution);
|
|
274
|
+
if (node.type === "CallExpression") return stringConcatHasStaticPart(node, scope, resolution) !== null;
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
function additionContainsString(value, scope, resolution) {
|
|
278
|
+
const node = unwrapExpression(value);
|
|
279
|
+
if (!node) return false;
|
|
280
|
+
if (stringValue(node) !== null || node.type === "TemplateLiteral") return true;
|
|
281
|
+
if (node.type === "Identifier" && typeof node.name === "string") return resolveConstantBinding(scope, node.name, resolution, false, additionContainsString);
|
|
282
|
+
if (node.type === "BinaryExpression" && node.operator === "+") return additionContainsString(node.left, scope, resolution) || additionContainsString(node.right, scope, resolution);
|
|
283
|
+
if (node.type === "ConditionalExpression") return additionContainsString(node.consequent, scope, resolution) && additionContainsString(node.alternate, scope, resolution);
|
|
284
|
+
if (node.type === "SequenceExpression") return additionContainsString(nodeArray(node.expressions).at(-1), scope, resolution);
|
|
285
|
+
return stringConcatHasStaticPart(node, scope, resolution) !== null;
|
|
286
|
+
}
|
|
287
|
+
function requestHasStaticPart(value, scope, resolution = createConstantResolution()) {
|
|
288
|
+
const node = unwrapExpression(value);
|
|
289
|
+
if (!node) return false;
|
|
290
|
+
const constantString = stringValue(node);
|
|
291
|
+
if (constantString !== null) return constantString.replaceAll("\\", "/") !== "/";
|
|
292
|
+
if (node.type === "Literal") return true;
|
|
293
|
+
if (isUnboundNumericGlobal(node, scope)) return true;
|
|
294
|
+
if (node.type === "TemplateLiteral") return templateHasStaticPart(node, scope, resolution);
|
|
295
|
+
const stringRawHasStaticPart = stringRawTemplateHasStaticPart(node, scope, resolution);
|
|
296
|
+
if (stringRawHasStaticPart !== null) return stringRawHasStaticPart;
|
|
297
|
+
const concatHasStaticPart = stringConcatHasStaticPart(node, scope, resolution);
|
|
298
|
+
if (concatHasStaticPart !== null) return concatHasStaticPart;
|
|
299
|
+
if (isIdentifierNamed(node, "undefined") && !hasAstBinding(scope, "undefined")) return true;
|
|
300
|
+
if (node.type === "Identifier" && typeof node.name === "string") return resolveConstantBinding(scope, node.name, resolution, false, requestHasStaticPart);
|
|
301
|
+
if (node.type === "UnaryExpression") {
|
|
302
|
+
if (node.operator === "void") return isLiteralExpression(node.argument);
|
|
303
|
+
if (isNegativeNumericLiteral(node)) return true;
|
|
304
|
+
return staticTruthiness(node, scope, resolution) !== null;
|
|
305
|
+
}
|
|
306
|
+
if (node.type === "BinaryExpression" && node.operator === "+") {
|
|
307
|
+
if (!additionContainsString(node, scope, resolution)) return false;
|
|
308
|
+
const left = unwrapExpression(node.left);
|
|
309
|
+
const right = unwrapExpression(node.right);
|
|
310
|
+
const leftString = left ? stringValue(left) : null;
|
|
311
|
+
const rightString = right ? stringValue(right) : null;
|
|
312
|
+
return leftString !== null && hasSignificantPathPart(leftString) || rightString !== null && hasSignificantPathPart(rightString) || leftString === null && requestHasStaticPart(left, scope, resolution) || rightString === null && requestHasStaticPart(right, scope, resolution);
|
|
313
|
+
}
|
|
314
|
+
if (node.type === "ConditionalExpression") {
|
|
315
|
+
const truthiness = staticTruthiness(node.test, scope, resolution);
|
|
316
|
+
return truthiness === null ? requestHasStaticPart(node.consequent, scope, resolution) || requestHasStaticPart(node.alternate, scope, resolution) : requestHasStaticPart(truthiness ? node.consequent : node.alternate, scope, resolution);
|
|
317
|
+
}
|
|
318
|
+
if (node.type === "LogicalExpression") {
|
|
319
|
+
const truthiness = staticTruthiness(node.left, scope, resolution);
|
|
320
|
+
if (node.operator === "&&" && truthiness !== null) return requestHasStaticPart(truthiness ? node.right : node.left, scope, resolution);
|
|
321
|
+
if (node.operator === "||" && truthiness !== null) return requestHasStaticPart(truthiness ? node.left : node.right, scope, resolution);
|
|
322
|
+
if (node.operator === "??") {
|
|
323
|
+
const nullishness = staticNullishness(node.left, scope, resolution);
|
|
324
|
+
if (nullishness !== null) return requestHasStaticPart(nullishness ? node.right : node.left, scope, resolution);
|
|
325
|
+
}
|
|
326
|
+
return requestHasStaticPart(node.left, scope, resolution) || requestHasStaticPart(node.right, scope, resolution);
|
|
327
|
+
}
|
|
328
|
+
if (node.type === "SequenceExpression") {
|
|
329
|
+
const expressions = nodeArray(node.expressions);
|
|
330
|
+
if (expressions.length === 0) return false;
|
|
331
|
+
return expressions.slice(0, -1).every((expression) => !expressionMayHaveSideEffects(expression, scope)) && requestHasStaticPart(expressions.at(-1), scope, resolution);
|
|
332
|
+
}
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
function expressionMayHaveSideEffects(value, scope) {
|
|
336
|
+
const node = unwrapExpression(value);
|
|
337
|
+
if (!node) return false;
|
|
338
|
+
if (node.type === "Literal" || node.type === "StringLiteral" || node.type === "Identifier" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") return false;
|
|
339
|
+
if (node.type === "TemplateLiteral") return nodeArray(node.expressions).some((expression) => expressionMayHaveSideEffects(expression, scope));
|
|
340
|
+
if (node.type === "UnaryExpression") return node.operator === "delete" || expressionMayHaveSideEffects(node.argument, scope);
|
|
341
|
+
if (node.type === "AwaitExpression") return expressionMayHaveSideEffects(node.argument, scope);
|
|
342
|
+
if (node.type === "BinaryExpression" || node.type === "LogicalExpression") return expressionMayHaveSideEffects(node.left, scope) || expressionMayHaveSideEffects(node.right, scope);
|
|
343
|
+
if (node.type === "ConditionalExpression") return expressionMayHaveSideEffects(node.test, scope) || expressionMayHaveSideEffects(node.consequent, scope) || expressionMayHaveSideEffects(node.alternate, scope);
|
|
344
|
+
if (node.type === "SequenceExpression") return nodeArray(node.expressions).some((expression) => expressionMayHaveSideEffects(expression, scope));
|
|
345
|
+
if (node.type === "ArrayExpression") return nodeArray(node.elements).some((element) => {
|
|
346
|
+
const elementNode = astNode(element);
|
|
347
|
+
return elementNode?.type === "SpreadElement" || expressionMayHaveSideEffects(elementNode, scope);
|
|
348
|
+
});
|
|
349
|
+
if (node.type === "ObjectExpression") return nodeArray(node.properties).some((property) => {
|
|
350
|
+
const propertyNode = astNode(property);
|
|
351
|
+
if (propertyNode?.type === "SpreadElement") return expressionMayHaveSideEffects(propertyNode.argument, scope);
|
|
352
|
+
if (propertyNode?.type !== "Property" || propertyNode.kind !== "init" || propertyNode.method === true) return true;
|
|
353
|
+
return expressionMayHaveSideEffects(propertyNode.computed ? propertyNode.key : null, scope) || expressionMayHaveSideEffects(propertyNode.value, scope);
|
|
354
|
+
});
|
|
355
|
+
if (node.type === "MemberExpression") return expressionMayHaveSideEffects(node.object, scope) || expressionMayHaveSideEffects(node.computed ? node.property : null, scope);
|
|
356
|
+
if (node.type === "TaggedTemplateExpression") {
|
|
357
|
+
if (isUnboundStringRawTag(node.tag, scope)) {
|
|
358
|
+
const quasi = astNode(node.quasi);
|
|
359
|
+
return quasi?.type !== "TemplateLiteral" || nodeArray(quasi.expressions).some((expression) => expressionMayHaveSideEffects(expression, scope));
|
|
360
|
+
}
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
if (node.type === "MetaProperty") return false;
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
function collectConstantBinding(declaration, declarator, scope) {
|
|
367
|
+
const identifier = astNode(declarator.id);
|
|
368
|
+
const initializer = astNode(declarator.init);
|
|
369
|
+
if (declaration.kind === "const" && identifier?.type === "Identifier" && typeof identifier.name === "string" && initializer) scope.constants.set(identifier.name, {
|
|
370
|
+
initializer,
|
|
371
|
+
scope
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
function collectDirectBindings(node, scope) {
|
|
375
|
+
collectDirectScopeBindings(node, scope, (declaration, declarator) => collectConstantBinding(declaration, declarator, scope));
|
|
376
|
+
if (node.type === "SwitchStatement") collectSwitchScopeBindings(node, scope, (declaration, declarator) => collectConstantBinding(declaration, declarator, scope));
|
|
377
|
+
}
|
|
378
|
+
function dynamicRequireReplacement() {
|
|
379
|
+
return `(() => { const error = new Error(${JSON.stringify(DYNAMIC_REQUEST_ERROR)}); error.code = "MODULE_NOT_FOUND"; throw error; })()`;
|
|
380
|
+
}
|
|
381
|
+
function dynamicImportReplacement() {
|
|
382
|
+
return `Promise.resolve().then(() => { const error = new Error(${JSON.stringify(DYNAMIC_REQUEST_ERROR)}); error.code = "MODULE_NOT_FOUND"; throw error; })`;
|
|
383
|
+
}
|
|
384
|
+
function transformVeryDynamicRequests(code, id) {
|
|
385
|
+
if (!code.includes("require") && !code.includes("import")) return null;
|
|
386
|
+
const extension = path.extname(id.split("?", 1)[0]);
|
|
387
|
+
const lang = extension === ".ts" || extension === ".mts" || extension === ".cts" ? "ts" : extension === ".tsx" ? "tsx" : extension === ".jsx" ? "jsx" : "js";
|
|
388
|
+
let ast;
|
|
389
|
+
try {
|
|
390
|
+
ast = parseAst(code, { lang });
|
|
391
|
+
} catch {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
const output = new MagicString(code);
|
|
395
|
+
let changed = false;
|
|
396
|
+
const root = astNode(ast);
|
|
397
|
+
if (!root) return null;
|
|
398
|
+
const rootScope = {
|
|
399
|
+
parent: null,
|
|
400
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
401
|
+
constants: /* @__PURE__ */ new Map()
|
|
402
|
+
};
|
|
403
|
+
collectDirectBindings(root, rootScope);
|
|
404
|
+
collectVarScopeBindings(root, rootScope);
|
|
405
|
+
function visit(node, parentScope) {
|
|
406
|
+
let scope = parentScope;
|
|
407
|
+
if (isFunctionNode(node)) {
|
|
408
|
+
const parameterScope = {
|
|
409
|
+
parent: parentScope,
|
|
410
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
411
|
+
constants: /* @__PURE__ */ new Map()
|
|
412
|
+
};
|
|
413
|
+
collectBindingNames(node.id, parameterScope.bindings);
|
|
414
|
+
for (const parameter of nodeArray(node.params)) collectBindingNames(parameter, parameterScope.bindings);
|
|
415
|
+
for (const parameter of nodeArray(node.params)) {
|
|
416
|
+
const parameterNode = astNode(parameter);
|
|
417
|
+
if (parameterNode) visit(parameterNode, parameterScope);
|
|
418
|
+
}
|
|
419
|
+
const body = astNode(node.body);
|
|
420
|
+
if (body) {
|
|
421
|
+
const bodyScope = {
|
|
422
|
+
parent: parameterScope,
|
|
423
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
424
|
+
constants: /* @__PURE__ */ new Map()
|
|
425
|
+
};
|
|
426
|
+
collectDirectBindings(body, bodyScope);
|
|
427
|
+
collectVarScopeBindings(body, bodyScope);
|
|
428
|
+
if (body.type === "BlockStatement") for (const statement of nodeArray(body.body)) {
|
|
429
|
+
const statementNode = astNode(statement);
|
|
430
|
+
if (statementNode) visit(statementNode, bodyScope);
|
|
431
|
+
}
|
|
432
|
+
else visit(body, bodyScope);
|
|
433
|
+
}
|
|
434
|
+
return;
|
|
435
|
+
} else if (node.type === "SwitchStatement") {
|
|
436
|
+
const discriminant = astNode(node.discriminant);
|
|
437
|
+
if (discriminant) visit(discriminant, parentScope);
|
|
438
|
+
const switchScope = {
|
|
439
|
+
parent: parentScope,
|
|
440
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
441
|
+
constants: /* @__PURE__ */ new Map()
|
|
442
|
+
};
|
|
443
|
+
collectDirectBindings(node, switchScope);
|
|
444
|
+
for (const switchCase of nodeArray(node.cases)) {
|
|
445
|
+
const switchCaseNode = astNode(switchCase);
|
|
446
|
+
if (switchCaseNode) visit(switchCaseNode, switchScope);
|
|
447
|
+
}
|
|
448
|
+
return;
|
|
449
|
+
} else if (node.type === "BlockStatement" && node !== root || node.type === "StaticBlock" || node.type === "TSModuleBlock") {
|
|
450
|
+
scope = {
|
|
451
|
+
parent: parentScope,
|
|
452
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
453
|
+
constants: /* @__PURE__ */ new Map()
|
|
454
|
+
};
|
|
455
|
+
collectDirectBindings(node, scope);
|
|
456
|
+
if (node.type === "StaticBlock" || node.type === "TSModuleBlock") collectVarScopeBindings(node, scope);
|
|
457
|
+
} else if (node.type === "CatchClause") {
|
|
458
|
+
scope = {
|
|
459
|
+
parent: parentScope,
|
|
460
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
461
|
+
constants: /* @__PURE__ */ new Map()
|
|
462
|
+
};
|
|
463
|
+
collectBindingNames(node.param, scope.bindings);
|
|
464
|
+
} else if (node.type === "ForStatement" || node.type === "ForInStatement" || node.type === "ForOfStatement") {
|
|
465
|
+
scope = {
|
|
466
|
+
parent: parentScope,
|
|
467
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
468
|
+
constants: /* @__PURE__ */ new Map()
|
|
469
|
+
};
|
|
470
|
+
collectLoopScopeBindings(node, scope, (declaration, declarator) => collectConstantBinding(declaration, declarator, scope));
|
|
471
|
+
} else if (node.type === "ClassExpression" && node.id) {
|
|
472
|
+
scope = {
|
|
473
|
+
parent: parentScope,
|
|
474
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
475
|
+
constants: /* @__PURE__ */ new Map()
|
|
476
|
+
};
|
|
477
|
+
collectBindingNames(node.id, scope.bindings);
|
|
478
|
+
}
|
|
479
|
+
if (node.type === "CallExpression" && hasRange(node)) {
|
|
480
|
+
const callee = unwrapExpression(node.callee);
|
|
481
|
+
const argumentsList = nodeArray(node.arguments);
|
|
482
|
+
if (isIdentifierNamed(callee, "require") && !hasAstBinding(scope, "require") && argumentsList.length === 1 && astNode(argumentsList[0])?.type !== "SpreadElement" && !hasDynamicRequestIgnoreDirective(code, node, argumentsList[0]) && !requestHasStaticPart(argumentsList[0], scope)) {
|
|
483
|
+
output.overwrite(node.start, node.end, dynamicRequireReplacement());
|
|
484
|
+
changed = true;
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if (node.type === "ImportExpression" && hasRange(node) && !hasDynamicRequestIgnoreDirective(code, node, node.source) && !requestHasStaticPart(node.source, scope)) {
|
|
489
|
+
output.overwrite(node.start, node.end, dynamicImportReplacement());
|
|
490
|
+
changed = true;
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
forEachAstChild(node, (child) => visit(child, scope));
|
|
494
|
+
}
|
|
495
|
+
for (const statement of nodeArray(root.body)) if (isAstRecord(statement)) visit(statement, rootScope);
|
|
496
|
+
if (!changed) return null;
|
|
497
|
+
return {
|
|
498
|
+
code: output.toString(),
|
|
499
|
+
map: output.generateMap({
|
|
500
|
+
hires: "boundary",
|
|
501
|
+
source: id
|
|
502
|
+
})
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
function createIgnoreDynamicRequestsPlugin(getTranspiledPackages = () => []) {
|
|
506
|
+
return {
|
|
507
|
+
name: "vinext:ignore-dynamic-requests",
|
|
508
|
+
enforce: "pre",
|
|
509
|
+
transform: {
|
|
510
|
+
filter: { id: { include: /\.(?:[cm]?[jt]s|[jt]sx)(?:\?.*)?$/ } },
|
|
511
|
+
handler(code, id) {
|
|
512
|
+
const cleanId = id.split("?", 1)[0];
|
|
513
|
+
if (!TRANSFORMABLE_EXTENSIONS.has(path.extname(cleanId))) return null;
|
|
514
|
+
if (!shouldTransformVeryDynamicRequests(this.environment, cleanId, getTranspiledPackages())) return null;
|
|
515
|
+
const absoluteId = path.resolve(cleanId);
|
|
516
|
+
if (absoluteId === VINEXT_SOURCE_ROOT || absoluteId.startsWith(`${VINEXT_SOURCE_ROOT}${path.sep}`) || PLUGIN_RSC_PATH.test(absoluteId)) return null;
|
|
517
|
+
return transformVeryDynamicRequests(code, id);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
function shouldTransformVeryDynamicRequests(environment, id, transpiledPackages) {
|
|
523
|
+
if (environment.config.consumer === "server") return true;
|
|
524
|
+
const normalizedId = id.replaceAll("\\", "/");
|
|
525
|
+
if (!normalizedId.includes("/node_modules/")) return false;
|
|
526
|
+
return !transpiledPackages.some((packageName) => normalizedId.includes(`/node_modules/${packageName}/`));
|
|
527
|
+
}
|
|
528
|
+
const _transformVeryDynamicRequests = transformVeryDynamicRequests;
|
|
529
|
+
//#endregion
|
|
530
|
+
export { _transformVeryDynamicRequests, createIgnoreDynamicRequestsPlugin };
|
|
@@ -2,8 +2,8 @@ import { Plugin } from "vite";
|
|
|
2
2
|
|
|
3
3
|
//#region src/plugins/middleware-server-only.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Allow `import 'server-only'` from
|
|
6
|
-
* from
|
|
5
|
+
* Allow `import 'server-only'` from neutral server targets (and any module
|
|
6
|
+
* reachable from them) in the SSR environment.
|
|
7
7
|
*
|
|
8
8
|
* Background: middleware runs server-side, so importing `server-only` is
|
|
9
9
|
* semantically correct. However, vinext bundles middleware into the SSR
|
|
@@ -13,9 +13,9 @@ import { Plugin } from "vite";
|
|
|
13
13
|
*
|
|
14
14
|
* 'server-only' cannot be imported in client build ('ssr' environment)
|
|
15
15
|
*
|
|
16
|
-
* Next.js solves this with webpack `issuerLayer` rules: middleware
|
|
17
|
-
*
|
|
18
|
-
* is aliased to a no-op while `client-only` still errors. See
|
|
16
|
+
* Next.js solves this with webpack `issuerLayer` rules: middleware,
|
|
17
|
+
* instrumentation, and Pages API routes sit in server-only or neutral layers
|
|
18
|
+
* where `server-only` is aliased to a no-op while `client-only` still errors. See
|
|
19
19
|
* packages/next/src/build/webpack-config.ts ("Alias server-only and
|
|
20
20
|
* client-only to proper exports based on bundling layers")
|
|
21
21
|
*
|
|
@@ -23,7 +23,8 @@ import { Plugin } from "vite";
|
|
|
23
23
|
* the behavior with import-chain taint tracking:
|
|
24
24
|
*
|
|
25
25
|
* 1. Seed a `tainted` set with the middleware entry path (and its
|
|
26
|
-
* canonical realpath)
|
|
26
|
+
* canonical realpath), and recognize other neutral server entry modules
|
|
27
|
+
* such as Pages API routes through `isNeutralServerModule`.
|
|
27
28
|
* 2. For every resolveId call from a tainted importer, resolve the import
|
|
28
29
|
* via `this.resolve(..., { skipSelf: true })` and add the resolved id
|
|
29
30
|
* to the tainted set. This propagates the taint along the import graph
|
|
@@ -47,6 +48,7 @@ import { Plugin } from "vite";
|
|
|
47
48
|
declare function createMiddlewareServerOnlyPlugin(options: {
|
|
48
49
|
getMiddlewarePath: () => string | null;
|
|
49
50
|
getCanonicalMiddlewarePath: () => string | null;
|
|
51
|
+
isNeutralServerModule?: (id: string) => boolean;
|
|
50
52
|
serverOnlyShimPath: string;
|
|
51
53
|
}): Plugin;
|
|
52
54
|
//#endregion
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { normalizePathSeparators } from "../utils/path.js";
|
|
2
2
|
//#region src/plugins/middleware-server-only.ts
|
|
3
3
|
/**
|
|
4
|
-
* Allow `import 'server-only'` from
|
|
5
|
-
* from
|
|
4
|
+
* Allow `import 'server-only'` from neutral server targets (and any module
|
|
5
|
+
* reachable from them) in the SSR environment.
|
|
6
6
|
*
|
|
7
7
|
* Background: middleware runs server-side, so importing `server-only` is
|
|
8
8
|
* semantically correct. However, vinext bundles middleware into the SSR
|
|
@@ -12,9 +12,9 @@ import { normalizePathSeparators } from "../utils/path.js";
|
|
|
12
12
|
*
|
|
13
13
|
* 'server-only' cannot be imported in client build ('ssr' environment)
|
|
14
14
|
*
|
|
15
|
-
* Next.js solves this with webpack `issuerLayer` rules: middleware
|
|
16
|
-
*
|
|
17
|
-
* is aliased to a no-op while `client-only` still errors. See
|
|
15
|
+
* Next.js solves this with webpack `issuerLayer` rules: middleware,
|
|
16
|
+
* instrumentation, and Pages API routes sit in server-only or neutral layers
|
|
17
|
+
* where `server-only` is aliased to a no-op while `client-only` still errors. See
|
|
18
18
|
* packages/next/src/build/webpack-config.ts ("Alias server-only and
|
|
19
19
|
* client-only to proper exports based on bundling layers")
|
|
20
20
|
*
|
|
@@ -22,7 +22,8 @@ import { normalizePathSeparators } from "../utils/path.js";
|
|
|
22
22
|
* the behavior with import-chain taint tracking:
|
|
23
23
|
*
|
|
24
24
|
* 1. Seed a `tainted` set with the middleware entry path (and its
|
|
25
|
-
* canonical realpath)
|
|
25
|
+
* canonical realpath), and recognize other neutral server entry modules
|
|
26
|
+
* such as Pages API routes through `isNeutralServerModule`.
|
|
26
27
|
* 2. For every resolveId call from a tainted importer, resolve the import
|
|
27
28
|
* via `this.resolve(..., { skipSelf: true })` and add the resolved id
|
|
28
29
|
* to the tainted set. This propagates the taint along the import graph
|
|
@@ -72,7 +73,7 @@ function createMiddlewareServerOnlyPlugin(options) {
|
|
|
72
73
|
async handler(id, importer, opts) {
|
|
73
74
|
if (this.environment?.name === "rsc") return;
|
|
74
75
|
if (!importer) return;
|
|
75
|
-
if (!isTainted(importer)) return;
|
|
76
|
+
if (!isTainted(importer) && !options.isNeutralServerModule?.(canonicalizeId(importer))) return;
|
|
76
77
|
if (id === "server-only") return {
|
|
77
78
|
id: options.serverOnlyShimPath,
|
|
78
79
|
moduleSideEffects: false
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { normalizePathSeparators } from "../utils/path.js";
|
|
2
1
|
import { escapeRegExp } from "../utils/regex.js";
|
|
2
|
+
import { normalizePathSeparators } from "../utils/path.js";
|
|
3
3
|
import { VIRTUAL_MODULE_ID_RE } from "../utils/virtual-module.js";
|
|
4
4
|
import { getAstName } from "./ast-utils.js";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
@@ -6,7 +6,7 @@ type EnvironmentLike = {
|
|
|
6
6
|
};
|
|
7
7
|
};
|
|
8
8
|
declare function getTypeofWindowReplacement(environment: EnvironmentLike): WindowType;
|
|
9
|
-
declare function replaceTypeofWindow(code: string, replacement: WindowType): {
|
|
9
|
+
declare function replaceTypeofWindow(code: string, replacement: WindowType, id?: string): {
|
|
10
10
|
code: string;
|
|
11
11
|
map: import("magic-string").SourceMap;
|
|
12
12
|
} | null;
|