vinext 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/build/output-root-externals.d.ts +21 -0
- package/dist/build/output-root-externals.js +40 -0
- package/dist/build/prerender-paths.js +1 -1
- package/dist/build/prerender.js +1 -1
- package/dist/check.js +5 -6
- package/dist/cli-dev-config.js +3 -3
- package/dist/cli.js +1 -1
- package/dist/config/config-matchers.js +12 -7
- package/dist/index.js +113 -94
- package/dist/init.d.ts +1 -1
- package/dist/init.js +86 -6
- package/dist/plugins/ast-utils.d.ts +53 -2
- package/dist/plugins/ast-utils.js +90 -2
- package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
- package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
- package/dist/plugins/commonjs-esm-facade.js +2 -2
- package/dist/plugins/css-module-imports.js +13 -20
- package/dist/plugins/dynamic-preload-metadata.js +2 -3
- package/dist/plugins/extensionless-dynamic-import.js +2 -3
- package/dist/plugins/fonts.d.ts +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +2 -3
- package/dist/plugins/import-meta-url.js +3 -4
- package/dist/plugins/instrumentation-client.js +3 -2
- package/dist/plugins/middleware-export-validation.js +2 -3
- package/dist/plugins/og-harfbuzz.js +2 -3
- package/dist/plugins/optimize-imports.js +3 -4
- package/dist/plugins/pages-node-externals.js +2 -3
- package/dist/plugins/remove-console.js +2 -18
- package/dist/plugins/require-condition-resolution.js +3 -3
- package/dist/plugins/require-context.js +2 -3
- package/dist/plugins/strip-server-exports.js +3 -4
- package/dist/plugins/styled-jsx.js +2 -3
- package/dist/plugins/use-cache-callable.d.ts +21 -2
- package/dist/plugins/use-cache-callable.js +76 -33
- package/dist/plugins/worker-image-imports.js +30 -33
- package/dist/plugins/worker-use-server.js +38 -14
- package/dist/server/api-handler.js +1 -1
- package/dist/server/app-action-forwarding.js +2 -2
- package/dist/server/app-browser-entry.js +3 -3
- package/dist/server/app-browser-interception-context.js +1 -1
- package/dist/server/app-browser-prefetch-response.js +2 -2
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-supplemental-refresh.js +1 -1
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-dispatch.js +1 -1
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-pages-bridge.js +1 -1
- package/dist/server/app-prerender-endpoints.js +1 -1
- package/dist/server/app-render-abort-error.d.ts +19 -0
- package/dist/server/app-render-abort-error.js +31 -1
- package/dist/server/app-request-stage-independent-entry.js +5 -5
- package/dist/server/app-response-stage-entry.js +2 -2
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-router-entry.js +5 -5
- package/dist/server/app-rsc-cache-busting.d.ts +16 -0
- package/dist/server/app-rsc-cache-busting.js +29 -12
- package/dist/server/app-rsc-handler.js +5 -5
- package/dist/server/app-rsc-request-normalization.js +3 -3
- package/dist/server/app-rsc-response-stage.js +2 -2
- package/dist/server/app-server-action-execution.js +1 -1
- package/dist/server/app-ssr-entry.js +5 -4
- package/dist/server/app-visited-response-cache.js +2 -2
- package/dist/server/config-headers.js +1 -1
- package/dist/server/defer-until-stream-consumed.d.ts +2 -1
- package/dist/server/defer-until-stream-consumed.js +3 -1
- package/dist/server/dev-server.js +1 -1
- package/dist/server/image-optimization.js +1 -0
- package/dist/server/metadata-route-response.js +2 -2
- package/dist/server/middleware-path-to-regexp.js +1 -1
- package/dist/server/middleware-runtime.js +5 -5
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/open-redirect.d.ts +11 -4
- package/dist/server/open-redirect.js +11 -4
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-data-route.js +2 -1
- package/dist/server/pages-page-data.js +1 -1
- package/dist/server/pages-page-handler.js +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-request-pipeline.js +5 -5
- package/dist/server/pages-request-stage-entry.js +4 -4
- package/dist/server/pages-revalidate.js +2 -2
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prod-server.js +5 -5
- package/dist/server/rsc-stream-hints.d.ts +1 -1
- package/dist/server/rsc-stream-hints.js +21 -3
- package/dist/server/worker-image-optimization.js +19 -6
- package/dist/shims/head.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +1 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +1 -0
- package/dist/shims/link-prefetch.js +5 -4
- package/dist/shims/link.js +2 -2
- package/dist/shims/navigation.js +4 -5
- package/dist/shims/router.js +9 -12
- package/dist/shims/server.d.ts +11 -4
- package/dist/shims/server.js +41 -5
- package/dist/shims/url-utils.d.ts +7 -0
- package/dist/shims/url-utils.js +12 -3
- package/dist/utils/domain-locale.js +1 -1
- package/dist/utils/plugin-rsc-version.d.ts +2 -0
- package/dist/utils/plugin-rsc-version.js +28 -2
- package/dist/utils/react-version.d.ts +7 -0
- package/dist/utils/react-version.js +39 -16
- package/package.json +6 -6
- package/dist/build/nitro-route-rules.d.ts +0 -47
- package/dist/build/nitro-route-rules.js +0 -79
- package/dist/plugins/cache-flight-codec.d.ts +0 -19
- package/dist/plugins/cache-flight-codec.js +0 -68
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { DYNAMIC_IMPORT_PRESCAN, SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, mayContainDynamicImport, scriptParserLanguage, stringLiteralValue, unwrapExpression } from "./ast-utils.js";
|
|
2
|
+
import { DYNAMIC_IMPORT_PRESCAN, SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, mayContainDynamicImport, parseProgram, scriptParserLanguage, stringLiteralValue, unwrapExpression } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
4
4
|
import { stripViteModuleQuery } from "../utils/path.js";
|
|
5
5
|
import { isForeignNodeModule } from "../utils/package-name.js";
|
|
6
6
|
import { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, hasAstBinding, isFunctionNode } from "./ast-scope.js";
|
|
7
7
|
import { createTransformCache } from "./transform-cache.js";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { parseAst } from "vite";
|
|
10
9
|
import MagicString from "magic-string";
|
|
11
10
|
//#region src/plugins/ignore-dynamic-requests.ts
|
|
12
11
|
const DYNAMIC_REQUEST_ERROR = "Cannot find module as expression is too dynamic";
|
|
@@ -411,7 +410,7 @@ function transformVeryDynamicRequests(code, id) {
|
|
|
411
410
|
const lang = scriptParserLanguage(id) ?? "js";
|
|
412
411
|
let ast;
|
|
413
412
|
try {
|
|
414
|
-
ast =
|
|
413
|
+
ast = parseProgram(code, { lang });
|
|
415
414
|
} catch {
|
|
416
415
|
return null;
|
|
417
416
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, scriptParserLanguage } from "./ast-utils.js";
|
|
2
|
+
import { SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, parseProgram, scriptParserLanguage } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
4
4
|
import { canonicalizeFilePath, isPathInsideOrEqual, stripViteModuleQuery } from "../utils/path.js";
|
|
5
5
|
import { VIRTUAL_MODULE_ID_RE } from "../utils/virtual-module.js";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
-
import { parseAst } from "vite";
|
|
9
8
|
import { randomUUID } from "node:crypto";
|
|
10
9
|
import MagicString from "magic-string";
|
|
11
10
|
//#region src/plugins/import-meta-url.ts
|
|
@@ -254,14 +253,14 @@ function finalizeEmittedModuleIdentity(code, emittedIdentitySentinels, fileName)
|
|
|
254
253
|
function rewriteModuleIdentity(code, options) {
|
|
255
254
|
let ast;
|
|
256
255
|
try {
|
|
257
|
-
ast =
|
|
256
|
+
ast = parseProgram(code, {
|
|
258
257
|
lang: scriptParserLanguage(options.id) ?? "jsx",
|
|
259
258
|
sourceType: options.cjsGlobalInitializers ? "commonjs" : void 0
|
|
260
259
|
});
|
|
261
260
|
} catch {
|
|
262
261
|
if (!options.cjsGlobalInitializers) return null;
|
|
263
262
|
try {
|
|
264
|
-
ast =
|
|
263
|
+
ast = parseProgram(code, { lang: scriptParserLanguage(options.id) ?? "jsx" });
|
|
265
264
|
} catch {
|
|
266
265
|
return null;
|
|
267
266
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { parseProgram } from "./ast-utils.js";
|
|
1
2
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
2
3
|
import { stripViteModuleQuery } from "../utils/path.js";
|
|
3
|
-
import { normalizePath
|
|
4
|
+
import { normalizePath } from "vite";
|
|
4
5
|
import MagicString from "magic-string";
|
|
5
6
|
//#region src/plugins/instrumentation-client.ts
|
|
6
7
|
function insertionPositionAfterDirectives(code) {
|
|
7
|
-
const ast =
|
|
8
|
+
const ast = parseProgram(code);
|
|
8
9
|
let insertPos = 0;
|
|
9
10
|
for (const node of ast.body) {
|
|
10
11
|
if (node.type !== "ExpressionStatement" || node.directive === void 0) break;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { getAstName, scriptParserLanguage } from "./ast-utils.js";
|
|
1
|
+
import { getAstName, parseProgram, scriptParserLanguage } from "./ast-utils.js";
|
|
2
2
|
import { createMiddlewareMissingExportError } from "../server/middleware-runtime.js";
|
|
3
|
-
import { parseAst } from "vite";
|
|
4
3
|
//#region src/plugins/middleware-export-validation.ts
|
|
5
4
|
function hasValidMiddlewareModuleExport(source, id, isProxy) {
|
|
6
|
-
const ast =
|
|
5
|
+
const ast = parseProgram(source, { lang: scriptParserLanguage(id) ?? "jsx" });
|
|
7
6
|
const expectedExport = isProxy ? "proxy" : "middleware";
|
|
8
7
|
for (const statement of ast.body) {
|
|
9
8
|
if (statement.type === "ExportDefaultDeclaration") return true;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { forEachAstChild, getAstName, staticStringValue } from "./ast-utils.js";
|
|
2
|
+
import { forEachAstChild, getAstName, parseProgram, staticStringValue } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
|
|
4
4
|
import { isFunctionNode } from "./ast-scope.js";
|
|
5
5
|
import { createTransformCache } from "./transform-cache.js";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import fs from "node:fs";
|
|
8
|
-
import { parseAst } from "vite";
|
|
9
8
|
import MagicString from "magic-string";
|
|
10
9
|
//#region src/plugins/og-harfbuzz.ts
|
|
11
10
|
/**
|
|
@@ -220,7 +219,7 @@ function patchHarfbuzzBundle(code, id, isBuild, callbackModuleDir, error) {
|
|
|
220
219
|
const ogEntry = toSlash(id.split("?", 1)[0]);
|
|
221
220
|
const isWorkerd = ogEntry.endsWith("/index.edge.js");
|
|
222
221
|
const fail = (reason) => error(`[vinext] Unsupported @vercel/og HarfBuzz bundle in ${ogEntry}: ${reason}. vinext must be updated to support this @vercel/og version.`);
|
|
223
|
-
const sites = findHarfbuzzPatchSites(
|
|
222
|
+
const sites = findHarfbuzzPatchSites(parseProgram(code, { lang: "js" }));
|
|
224
223
|
if (typeof sites === "string") return fail(sites);
|
|
225
224
|
const output = new MagicString(code);
|
|
226
225
|
for (const flag of sites.environmentFlags) output.overwrite(flag.start, flag.end, "false");
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { escapeRegExp } from "../utils/regex.js";
|
|
3
|
-
import { collectBindingNames, getAstName } from "./ast-utils.js";
|
|
3
|
+
import { collectBindingNames, getAstName, parseProgram } from "./ast-utils.js";
|
|
4
4
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
5
5
|
import { VIRTUAL_MODULE_ID_RE } from "../utils/virtual-module.js";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import fsp from "node:fs/promises";
|
|
8
|
-
import { parseAst } from "vite";
|
|
9
8
|
import MagicString from "magic-string";
|
|
10
9
|
//#region src/plugins/optimize-imports.ts
|
|
11
10
|
/**
|
|
@@ -234,7 +233,7 @@ async function buildExportMapFromFile(filePath, readFile, cache, visited, initia
|
|
|
234
233
|
if (!content) return /* @__PURE__ */ new Map();
|
|
235
234
|
let ast;
|
|
236
235
|
try {
|
|
237
|
-
ast =
|
|
236
|
+
ast = parseProgram(content);
|
|
238
237
|
} catch {
|
|
239
238
|
return /* @__PURE__ */ new Map();
|
|
240
239
|
}
|
|
@@ -456,7 +455,7 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
456
455
|
if (!hasOptimizedImportSource(code)) return null;
|
|
457
456
|
let ast;
|
|
458
457
|
try {
|
|
459
|
-
ast =
|
|
458
|
+
ast = parseProgram(code);
|
|
460
459
|
} catch {
|
|
461
460
|
return null;
|
|
462
461
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { SCRIPT_MODULE_ID_RE, mayContainDynamicImport, scriptParserLanguage, staticStringValue, walkAst } from "./ast-utils.js";
|
|
2
|
+
import { SCRIPT_MODULE_ID_RE, mayContainDynamicImport, parseProgram, scriptParserLanguage, staticStringValue, walkAst } from "./ast-utils.js";
|
|
3
3
|
import { canonicalizeFilePath, isPathInsideOrEqual, stripViteModuleQuery } from "../utils/path.js";
|
|
4
4
|
import { isServerEnvironment } from "./environment.js";
|
|
5
5
|
import { packageNameFromSpecifier } from "../utils/package-name.js";
|
|
6
6
|
import fs from "node:fs";
|
|
7
|
-
import { parseAst } from "vite";
|
|
8
7
|
//#region src/plugins/pages-node-externals.ts
|
|
9
8
|
const FRAMEWORK_PACKAGES = /* @__PURE__ */ new Set([
|
|
10
9
|
"@vitejs/plugin-react",
|
|
@@ -47,7 +46,7 @@ function matchesAlias(id, aliases) {
|
|
|
47
46
|
function moduleDependencySpecifiers(code, id) {
|
|
48
47
|
let ast;
|
|
49
48
|
try {
|
|
50
|
-
ast =
|
|
49
|
+
ast = parseProgram(code, { lang: scriptParserLanguage(id) ?? "jsx" });
|
|
51
50
|
} catch {
|
|
52
51
|
return [];
|
|
53
52
|
}
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
+
import { parseProgram } from "./ast-utils.js";
|
|
1
2
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
2
|
-
import { parseAst } from "vite";
|
|
3
3
|
import MagicString from "magic-string";
|
|
4
4
|
//#region src/plugins/remove-console.ts
|
|
5
|
-
/**
|
|
6
|
-
* Strip `console.*` calls from client bundle code.
|
|
7
|
-
*
|
|
8
|
-
* Mirrors Next.js's SWC `remove_console` transform:
|
|
9
|
-
* - Strips all `console.<method>()` calls regardless of context (top-level,
|
|
10
|
-
* JSX expressions, function arguments, return values, ternary branches)
|
|
11
|
-
* - Replaces removed calls with `void 0` to keep the AST valid in every
|
|
12
|
-
* position a CallExpression can appear
|
|
13
|
-
* - Respects `exclude: ["error"]` to preserve certain methods (case-insensitive)
|
|
14
|
-
* - Preserves calls when `console` is shadowed (local variable, function
|
|
15
|
-
* parameter, or destructured binding)
|
|
16
|
-
* - Preserves computed property access `console[prop]()`
|
|
17
|
-
*
|
|
18
|
-
* Uses Vite's `parseAst` (OXC/acorn) for parsing and `MagicString` for
|
|
19
|
-
* surgical source replacement. Returns `null` when no changes are made.
|
|
20
|
-
*/
|
|
21
5
|
const SCOPE_ENTERING_TYPES = /* @__PURE__ */ new Set([
|
|
22
6
|
"FunctionDeclaration",
|
|
23
7
|
"FunctionExpression",
|
|
@@ -36,7 +20,7 @@ function removeConsoleCalls(code, config) {
|
|
|
36
20
|
if (!code.match(/\bconsole\b/)) return null;
|
|
37
21
|
let ast;
|
|
38
22
|
try {
|
|
39
|
-
ast =
|
|
23
|
+
ast = parseProgram(code);
|
|
40
24
|
} catch {
|
|
41
25
|
return null;
|
|
42
26
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, scriptParserLanguage, staticStringValue, unwrapExpression } from "./ast-utils.js";
|
|
2
|
+
import { SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, parseProgram, scriptParserLanguage, staticStringValue, unwrapExpression } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
4
4
|
import { stripViteModuleQuery } from "../utils/path.js";
|
|
5
5
|
import { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, createAstScope, hasAstBinding, isFunctionNode } from "./ast-scope.js";
|
|
6
6
|
import { readFile } from "node:fs/promises";
|
|
7
|
-
import { createIdResolver
|
|
7
|
+
import { createIdResolver } from "vite";
|
|
8
8
|
import MagicString from "magic-string";
|
|
9
9
|
//#region src/plugins/require-condition-resolution.ts
|
|
10
10
|
const LITERAL_REQUIRE_RE = /\brequire\s*\(/;
|
|
@@ -30,7 +30,7 @@ function isPackageSpecifier(specifier) {
|
|
|
30
30
|
function collectLiteralRequires(code, id) {
|
|
31
31
|
let ast;
|
|
32
32
|
try {
|
|
33
|
-
ast =
|
|
33
|
+
ast = parseProgram(code, { lang: scriptParserLanguage(id) ?? "jsx" });
|
|
34
34
|
} catch {
|
|
35
35
|
return [];
|
|
36
36
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { SCRIPT_MODULE_ID_RE, booleanLiteralValue, scriptParserLanguage, stringLiteralValue, walkAst } from "./ast-utils.js";
|
|
2
|
+
import { SCRIPT_MODULE_ID_RE, booleanLiteralValue, parseProgram, scriptParserLanguage, stringLiteralValue, walkAst } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
4
4
|
import { stripViteModuleQuery } from "../utils/path.js";
|
|
5
5
|
import { readdir, realpath, stat } from "node:fs/promises";
|
|
6
|
-
import { parseAst } from "vite";
|
|
7
6
|
import MagicString from "magic-string";
|
|
8
7
|
//#region src/plugins/require-context.ts
|
|
9
8
|
function createRequireContextPlugin() {
|
|
@@ -82,7 +81,7 @@ async function transformRequireContext(code, id) {
|
|
|
82
81
|
const lang = scriptParserLanguage(id);
|
|
83
82
|
let ast;
|
|
84
83
|
try {
|
|
85
|
-
ast =
|
|
84
|
+
ast = parseProgram(code, { lang });
|
|
86
85
|
} catch {
|
|
87
86
|
return null;
|
|
88
87
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { getAstName } from "./ast-utils.js";
|
|
1
|
+
import { getAstName, parseProgram } from "./ast-utils.js";
|
|
2
2
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
3
3
|
import { findAstBindingScope, walkAstScopes } from "./ast-scope.js";
|
|
4
|
-
import { parseAst } from "vite";
|
|
5
4
|
import MagicString from "magic-string";
|
|
6
5
|
//#region src/plugins/strip-server-exports.ts
|
|
7
6
|
const SERVER_EXPORTS = /* @__PURE__ */ new Set([
|
|
@@ -225,7 +224,7 @@ function validatePageExports(code) {
|
|
|
225
224
|
if (!hasExportAllCandidate(code)) return;
|
|
226
225
|
let ast;
|
|
227
226
|
try {
|
|
228
|
-
ast =
|
|
227
|
+
ast = parseProgram(code);
|
|
229
228
|
} catch {
|
|
230
229
|
return;
|
|
231
230
|
}
|
|
@@ -243,7 +242,7 @@ function stripServerExports(code) {
|
|
|
243
242
|
if (!hasServerExportCandidate(code) && !hasExportAllCandidate(code)) return null;
|
|
244
243
|
let ast;
|
|
245
244
|
try {
|
|
246
|
-
ast =
|
|
245
|
+
ast = parseProgram(code);
|
|
247
246
|
} catch {
|
|
248
247
|
return null;
|
|
249
248
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import { SCRIPT_MODULE_ID_RE, walkAst } from "./ast-utils.js";
|
|
2
|
+
import { SCRIPT_MODULE_ID_RE, parseProgram, walkAst } from "./ast-utils.js";
|
|
3
3
|
import { NODE_MODULES_PATH_RE, stripViteModuleQuery } from "../utils/path.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
|
-
import { parseAst } from "vite";
|
|
7
6
|
//#region src/plugins/styled-jsx.ts
|
|
8
7
|
const STYLED_JSX_IMPORT_RE = /^styled-jsx(?:\/.*)?$/;
|
|
9
8
|
const STYLED_JSX_SOURCE_RE = /(?:<style\b|from\s+["']styled-jsx\/css["']|require\s*\(\s*["']styled-jsx\/css["']\s*\))/;
|
|
@@ -14,7 +13,7 @@ function hasStyledJsxTag(source, id) {
|
|
|
14
13
|
const lang = extension === ".ts" || extension === ".mts" || extension === ".cts" ? "ts" : "tsx";
|
|
15
14
|
let ast;
|
|
16
15
|
try {
|
|
17
|
-
ast =
|
|
16
|
+
ast = parseProgram(source, { lang });
|
|
18
17
|
} catch {
|
|
19
18
|
return false;
|
|
20
19
|
}
|
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
2
|
//#region src/plugins/use-cache-callable.d.ts
|
|
3
|
+
type RscTransforms = typeof import("@vitejs/plugin-rsc/transforms");
|
|
3
4
|
type Options = {
|
|
4
5
|
projectRoot: string;
|
|
5
6
|
cacheRuntime: string;
|
|
6
7
|
allowMissingRsc?: boolean;
|
|
7
8
|
};
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
type BrowserTransformOptions = {
|
|
10
|
+
environmentName: string;
|
|
11
|
+
reference: {
|
|
12
|
+
referenceKey: string;
|
|
13
|
+
};
|
|
14
|
+
secureExportName: (name: string) => string;
|
|
15
|
+
createReference: (referenceId: string, name: string) => string;
|
|
16
|
+
};
|
|
17
|
+
type BrowserTransformOutput = NonNullable<ReturnType<RscTransforms["transformDirectiveProxyExport"]>>;
|
|
18
|
+
export type UseCacheCallableApi = {
|
|
19
|
+
/**
|
|
20
|
+
* Compile a browser Web Worker module like the client environment does,
|
|
21
|
+
* with the same reference ids, without claiming references.
|
|
22
|
+
*/
|
|
23
|
+
transformWorkerModule(code: string, id: string, createReference: BrowserTransformOptions["createReference"]): Promise<BrowserTransformOutput["output"] | undefined>;
|
|
24
|
+
};
|
|
25
|
+
declare const PLUGIN_NAME = "vinext:server-function-directives";
|
|
26
|
+
export declare function createUseCacheCallablePlugin(options: Options): Promise<Plugin<UseCacheCallableApi>>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { PLUGIN_NAME as USE_CACHE_PLUGIN_NAME };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import { parseProgramAsync } from "./ast-utils.js";
|
|
2
3
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
3
4
|
import { NODE_MODULES_PATH_RE } from "../utils/path.js";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import { pathToFileURL } from "node:url";
|
|
6
|
-
import { parseAstAsync } from "vite";
|
|
7
7
|
import { createHmac, randomBytes } from "node:crypto";
|
|
8
8
|
//#region src/plugins/use-cache-callable.ts
|
|
9
9
|
const PLUGIN_NAME = "vinext:server-function-directives";
|
|
@@ -79,6 +79,41 @@ function getCacheWrapperOptions(meta) {
|
|
|
79
79
|
...captureCount === 0 ? {} : { captureCount }
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Compile a module for a browser graph: module-level cache functions become
|
|
84
|
+
* server references, and inline ones are rejected as in Next.js Client
|
|
85
|
+
* Components. Returns undefined when the module is unchanged.
|
|
86
|
+
*/
|
|
87
|
+
function transformBrowserModule(transforms, code, ast, id, moduleDirective, options) {
|
|
88
|
+
if (!moduleDirective) {
|
|
89
|
+
transforms.transformHoistInlineDirective(code, ast, {
|
|
90
|
+
directive: USE_CACHE_DIRECTIVE_CANDIDATE,
|
|
91
|
+
rejectNonAsyncFunction: true,
|
|
92
|
+
runtime: (_value, _name, meta) => {
|
|
93
|
+
matchUseCacheDirective(meta.directiveMatch[0]);
|
|
94
|
+
throw new Error(`It is not allowed to define inline "use cache" annotated functions in Client Components. Export them from a separate file with a module-level "use cache" or "use server" directive, or pass them down through props from a Server Component. (${options.environmentName}: ${id})`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const useServerExportNames = getFunctionDirectiveExportNames(transforms, ast, "use server");
|
|
100
|
+
const referenceName = (name) => useServerExportNames.has(name) ? name : options.secureExportName(name);
|
|
101
|
+
const result = transforms.transformDirectiveProxyExport(ast, {
|
|
102
|
+
code,
|
|
103
|
+
directive: moduleDirective,
|
|
104
|
+
filter: (name, meta) => {
|
|
105
|
+
if (!shouldTransformModuleExport(name, id, meta)) return false;
|
|
106
|
+
validateModuleExport(transforms, meta);
|
|
107
|
+
return true;
|
|
108
|
+
},
|
|
109
|
+
runtime: (name) => options.createReference(`${options.reference.referenceKey}#${referenceName(name)}`, name)
|
|
110
|
+
});
|
|
111
|
+
if (!result?.output.hasChanged()) return;
|
|
112
|
+
return {
|
|
113
|
+
output: result.output,
|
|
114
|
+
referenceNames: result.exportNames.map(referenceName)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
82
117
|
async function createUseCacheCallablePlugin(options) {
|
|
83
118
|
const rscModulePath = resolvePluginRscModule(options.projectRoot, "@vitejs/plugin-rsc");
|
|
84
119
|
const transformsPath = resolvePluginRscModule(options.projectRoot, "@vitejs/plugin-rsc/transforms");
|
|
@@ -86,8 +121,39 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
86
121
|
const transforms = await import(pathToFileURL(transformsPath).href);
|
|
87
122
|
const referenceSecret = randomBytes(32);
|
|
88
123
|
let manager;
|
|
124
|
+
async function analyzeModule(manager, code, id) {
|
|
125
|
+
const ast = await parseProgramAsync(code);
|
|
126
|
+
const moduleDirective = findModuleUseCacheDirective(ast);
|
|
127
|
+
const useServerBoundary = transforms.hasDirective(ast.body, "use server");
|
|
128
|
+
if (moduleDirective && useServerBoundary) throw new Error(`A module cannot contain both ${JSON.stringify(moduleDirective)} and "use server" directives.`);
|
|
129
|
+
const reference = manager.serverReferences.resolve(id, "rsc");
|
|
130
|
+
const relativeImportId = manager.toRelativeId(reference.importId);
|
|
131
|
+
const secureExportName = (name) => `$$vinext_cache_${createHmac("sha256", referenceSecret).update(relativeImportId).update("\0").update(name).digest("hex")}`;
|
|
132
|
+
return {
|
|
133
|
+
ast,
|
|
134
|
+
moduleDirective,
|
|
135
|
+
useServerBoundary,
|
|
136
|
+
reference,
|
|
137
|
+
secureExportName
|
|
138
|
+
};
|
|
139
|
+
}
|
|
89
140
|
return {
|
|
90
141
|
name: PLUGIN_NAME,
|
|
142
|
+
api: { async transformWorkerModule(code, id, createReference) {
|
|
143
|
+
if (!code.includes("use cache")) return;
|
|
144
|
+
if (!manager) {
|
|
145
|
+
if (findModuleUseCacheDirective(await parseProgramAsync(code))) throw new Error("vinext: cannot compile a \"use cache\" module in a Web Worker without @vitejs/plugin-rsc.");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, code, id);
|
|
149
|
+
if (useServerBoundary) return;
|
|
150
|
+
return transformBrowserModule(transforms, code, ast, id, moduleDirective, {
|
|
151
|
+
environmentName: "worker",
|
|
152
|
+
reference,
|
|
153
|
+
secureExportName,
|
|
154
|
+
createReference
|
|
155
|
+
})?.output;
|
|
156
|
+
} },
|
|
91
157
|
configResolved(config) {
|
|
92
158
|
const pluginApi = rscModule.getPluginApi(config);
|
|
93
159
|
const hasRscPlugin = config.plugins.some((plugin) => plugin.name === "rsc");
|
|
@@ -111,48 +177,25 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
111
177
|
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
112
178
|
return;
|
|
113
179
|
}
|
|
114
|
-
const ast = await
|
|
115
|
-
const moduleDirective = findModuleUseCacheDirective(ast);
|
|
116
|
-
const useServerBoundary = transforms.hasDirective(ast.body, "use server");
|
|
117
|
-
if (moduleDirective && useServerBoundary) throw new Error(`A module cannot contain both ${JSON.stringify(moduleDirective)} and "use server" directives.`);
|
|
118
|
-
const reference = manager.serverReferences.resolve(id, "rsc");
|
|
119
|
-
const relativeImportId = manager.toRelativeId(reference.importId);
|
|
120
|
-
const secureExportName = (name) => `$$vinext_cache_${createHmac("sha256", referenceSecret).update(relativeImportId).update("\0").update(name).digest("hex")}`;
|
|
180
|
+
const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, code, id);
|
|
121
181
|
if (!(this.environment.name === "rsc")) {
|
|
122
182
|
if (useServerBoundary) {
|
|
123
183
|
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
124
184
|
return;
|
|
125
185
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
matchUseCacheDirective(meta.directiveMatch[0]);
|
|
132
|
-
throw new Error(`It is not allowed to define inline "use cache" annotated functions in Client Components. Export them from a separate file with a module-level "use cache" or "use server" directive, or pass them down through props from a Server Component. (${this.environment.name}: ${id})`);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const useServerExportNames = getFunctionDirectiveExportNames(transforms, ast, "use server");
|
|
139
|
-
const result = transforms.transformDirectiveProxyExport(ast, {
|
|
140
|
-
code,
|
|
141
|
-
directive: moduleDirective,
|
|
142
|
-
filter: (name, meta) => {
|
|
143
|
-
if (!shouldTransformModuleExport(name, id, meta)) return false;
|
|
144
|
-
validateModuleExport(transforms, meta);
|
|
145
|
-
return true;
|
|
146
|
-
},
|
|
147
|
-
runtime: (name) => `$$ReactClient.createServerReference(${JSON.stringify(`${reference.referenceKey}#${useServerExportNames.has(name) ? name : secureExportName(name)}`)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
|
|
186
|
+
const result = transformBrowserModule(transforms, code, ast, id, moduleDirective, {
|
|
187
|
+
environmentName: this.environment.name,
|
|
188
|
+
reference,
|
|
189
|
+
secureExportName,
|
|
190
|
+
createReference: (referenceId, name) => `$$ReactClient.createServerReference(${JSON.stringify(referenceId)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
|
|
148
191
|
});
|
|
149
|
-
if (!result
|
|
192
|
+
if (!result) {
|
|
150
193
|
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
151
194
|
return;
|
|
152
195
|
}
|
|
153
196
|
manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
|
|
154
197
|
...reference,
|
|
155
|
-
exportNames: result.
|
|
198
|
+
exportNames: result.referenceNames
|
|
156
199
|
});
|
|
157
200
|
const runtimeEnvironment = this.environment.name === "client" ? "browser" : "ssr";
|
|
158
201
|
result.output.prepend(`import * as $$ReactClient from "@vitejs/plugin-rsc/react/${runtimeEnvironment}";\n`);
|
|
@@ -223,4 +266,4 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
223
266
|
};
|
|
224
267
|
}
|
|
225
268
|
//#endregion
|
|
226
|
-
export { createUseCacheCallablePlugin };
|
|
269
|
+
export { PLUGIN_NAME as USE_CACHE_PLUGIN_NAME, createUseCacheCallablePlugin };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { parseModuleRecord, quotedStringAt } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
4
4
|
import { appendDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
5
5
|
import { NODE_MODULES_PATH_RE, stripViteModuleQuery } from "../utils/path.js";
|
|
6
6
|
import fs from "node:fs";
|
|
7
|
-
import { parseAst } from "vite";
|
|
8
7
|
import MagicString from "magic-string";
|
|
9
8
|
//#region src/plugins/worker-image-imports.ts
|
|
10
9
|
const WORKER_IMAGE_METADATA_PREFIX = "\0vinext-worker-image-meta:";
|
|
@@ -70,24 +69,19 @@ function createWorkerImageImportsPlugin(options = {}) {
|
|
|
70
69
|
},
|
|
71
70
|
async handler(code, id) {
|
|
72
71
|
const sourceId = toSlash(stripViteModuleQuery(id));
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
ast = parseAst(code, { lang: /\.(?:[cm]?ts)$/.test(sourceId) ? "ts" : "tsx" });
|
|
76
|
-
} catch {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
72
|
+
const record = parseModuleRecord(code, /\.(?:[cm]?ts)$/.test(sourceId) ? "ts" : "tsx");
|
|
73
|
+
if (!record) return null;
|
|
79
74
|
const output = new MagicString(code);
|
|
80
75
|
const imageImports = [];
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
76
|
+
for (const dynamicImport of record.dynamicImports) {
|
|
77
|
+
const importPath = quotedStringAt(code, dynamicImport.moduleRequest);
|
|
78
|
+
if (importPath === null || !WORKER_IMAGE_EXTENSION_RE.test(importPath)) continue;
|
|
79
|
+
imageImports.push({
|
|
80
|
+
end: dynamicImport.end,
|
|
81
|
+
importPath,
|
|
82
|
+
start: dynamicImport.start
|
|
83
|
+
});
|
|
84
|
+
}
|
|
91
85
|
let changed = false;
|
|
92
86
|
for (const imageImport of imageImports) {
|
|
93
87
|
const resolved = await this.resolve(imageImport.importPath, sourceId, { skipSelf: true });
|
|
@@ -107,23 +101,26 @@ function createWorkerImageImportsPlugin(options = {}) {
|
|
|
107
101
|
if (!options.deploymentId) return null;
|
|
108
102
|
const chunkSpecifiers = new Set([...chunk.imports, ...chunk.dynamicImports].map((target) => workerChunkSpecifier(chunk.fileName, target)));
|
|
109
103
|
if (chunkSpecifiers.size === 0) return null;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
const record = parseModuleRecord(code, "js");
|
|
105
|
+
if (!record) return null;
|
|
106
|
+
const sources = [
|
|
107
|
+
...record.staticImports.map((statement) => statement.moduleRequest),
|
|
108
|
+
...record.staticExports.flatMap((statement) => statement.entries[0]?.moduleRequest ?? []),
|
|
109
|
+
...record.dynamicImports.map((dynamicImport) => {
|
|
110
|
+
const value = quotedStringAt(code, dynamicImport.moduleRequest);
|
|
111
|
+
return value === null ? [] : {
|
|
112
|
+
...dynamicImport.moduleRequest,
|
|
113
|
+
value
|
|
114
|
+
};
|
|
115
|
+
})
|
|
116
|
+
].flat();
|
|
116
117
|
const output = new MagicString(code);
|
|
117
118
|
let changed = false;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
changed = true;
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
});
|
|
119
|
+
for (const source of sources) {
|
|
120
|
+
if (!chunkSpecifiers.has(source.value)) continue;
|
|
121
|
+
output.overwrite(source.start, source.end, JSON.stringify(appendDeploymentIdQuery(source.value, options.deploymentId)));
|
|
122
|
+
changed = true;
|
|
123
|
+
}
|
|
127
124
|
if (!changed) return null;
|
|
128
125
|
return magicStringTransformResult(output);
|
|
129
126
|
}
|