vinext 1.0.0 → 1.0.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.
Files changed (148) hide show
  1. package/THIRD_PARTY_LICENSES.md +26 -0
  2. package/dist/build/lifecycle.js +10 -10
  3. package/dist/build/pages-client-assets-module.js +6 -1
  4. package/dist/build/precompress.js +1 -1
  5. package/dist/build/prerender-paths.js +3 -7
  6. package/dist/build/prerender.d.ts +8 -1
  7. package/dist/build/prerender.js +134 -38
  8. package/dist/build/run-prerender.js +4 -3
  9. package/dist/build/server-entry.d.ts +2 -0
  10. package/dist/build/server-entry.js +7 -1
  11. package/dist/client/browser-globals.d.ts +4 -0
  12. package/dist/client/browser-globals.js +5 -0
  13. package/dist/client/navigation-runtime.d.ts +0 -1
  14. package/dist/client/navigation-runtime.js +2 -2
  15. package/dist/config/dotenv.js +14 -3
  16. package/dist/entries/app-rsc-entry.js +3 -2
  17. package/dist/index.js +142 -71
  18. package/dist/init-cloudflare.d.ts +1 -1
  19. package/dist/init-cloudflare.js +6 -6
  20. package/dist/init-platform.js +1 -1
  21. package/dist/init.js +4 -2
  22. package/dist/plugins/commonjs-syntax.d.ts +16 -0
  23. package/dist/plugins/commonjs-syntax.js +22 -0
  24. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  25. package/dist/plugins/ignore-dynamic-requests.js +54 -3
  26. package/dist/plugins/import-meta-url.js +6 -6
  27. package/dist/plugins/og-asset-ownership.d.ts +2 -0
  28. package/dist/plugins/og-asset-ownership.js +24 -13
  29. package/dist/plugins/og-assets.d.ts +18 -0
  30. package/dist/plugins/og-assets.js +50 -8
  31. package/dist/plugins/og-harfbuzz.js +38 -27
  32. package/dist/plugins/optimize-imports.js +2 -1
  33. package/dist/plugins/require-context.d.ts +1 -0
  34. package/dist/plugins/require-context.js +28 -1
  35. package/dist/plugins/scan-build-css.d.ts +12 -0
  36. package/dist/plugins/scan-build-css.js +39 -0
  37. package/dist/plugins/strip-server-exports.d.ts +2 -0
  38. package/dist/plugins/strip-server-exports.js +3 -1
  39. package/dist/plugins/transform-result.d.ts +18 -0
  40. package/dist/plugins/transform-result.js +23 -2
  41. package/dist/plugins/typeof-window.d.ts +10 -0
  42. package/dist/plugins/typeof-window.js +33 -9
  43. package/dist/routing/app-route-graph.d.ts +0 -1
  44. package/dist/routing/app-route-graph.js +2 -4
  45. package/dist/routing/app-route-ids.d.ts +3 -0
  46. package/dist/routing/app-route-ids.js +6 -0
  47. package/dist/server/app-bfcache-id.d.ts +1 -0
  48. package/dist/server/app-bfcache-id.js +7 -1
  49. package/dist/server/app-bfcache-identity.js +1 -2
  50. package/dist/server/app-browser-entry.js +4 -2
  51. package/dist/server/app-browser-hydration.d.ts +1 -1
  52. package/dist/server/app-browser-hydration.js +2 -2
  53. package/dist/server/app-browser-navigation-controller.js +1 -1
  54. package/dist/server/app-browser-state.js +1 -1
  55. package/dist/server/app-browser-stream.d.ts +1 -1
  56. package/dist/server/app-history-state.d.ts +0 -1
  57. package/dist/server/app-history-state.js +2 -5
  58. package/dist/server/app-page-cache-render.js +2 -1
  59. package/dist/server/app-page-render.js +2 -1
  60. package/dist/server/app-page-search-params-observation.js +1 -1
  61. package/dist/server/app-page-stream.js +1 -1
  62. package/dist/server/app-page-tracing.js +2 -1
  63. package/dist/server/app-pages-bridge.js +3 -2
  64. package/dist/server/app-render-abort-error.d.ts +3 -0
  65. package/dist/server/app-render-abort-error.js +8 -0
  66. package/dist/server/app-request-stage-independent-entry.js +4 -7
  67. package/dist/server/app-route-handler-cache.d.ts +2 -1
  68. package/dist/server/app-route-handler-cache.js +11 -7
  69. package/dist/server/app-route-handler-dispatch.js +10 -3
  70. package/dist/server/app-route-handler-execution.d.ts +9 -1
  71. package/dist/server/app-route-handler-execution.js +28 -13
  72. package/dist/server/app-route-handler-policy.js +2 -2
  73. package/dist/server/app-route-handler-response.d.ts +1 -1
  74. package/dist/server/app-route-handler-response.js +14 -5
  75. package/dist/server/app-router-entry.d.ts +2 -1
  76. package/dist/server/app-router-entry.js +5 -9
  77. package/dist/server/app-rsc-errors.d.ts +0 -1
  78. package/dist/server/app-rsc-errors.js +2 -6
  79. package/dist/server/app-rsc-handler.d.ts +1 -0
  80. package/dist/server/app-rsc-handler.js +18 -7
  81. package/dist/server/app-rsc-request-normalization.d.ts +1 -1
  82. package/dist/server/app-rsc-request-normalization.js +3 -2
  83. package/dist/server/app-rsc-response-finalizer.js +4 -1
  84. package/dist/server/app-rsc-route-matching.js +1 -1
  85. package/dist/server/app-server-action-execution.d.ts +2 -1
  86. package/dist/server/app-ssr-entry.js +3 -3
  87. package/dist/server/app-ssr-search-params-gate.js +1 -1
  88. package/dist/server/app-ssr-stream.js +1 -1
  89. package/dist/server/cache-control.js +3 -11
  90. package/dist/server/cacheability-request.js +49 -49
  91. package/dist/server/config-headers.js +1 -1
  92. package/dist/server/dev-server.js +11 -3
  93. package/dist/server/headers.d.ts +2 -0
  94. package/dist/server/headers.js +5 -1
  95. package/dist/server/http-error-responses.js +1 -0
  96. package/dist/server/isr-cache.d.ts +2 -0
  97. package/dist/server/isr-cache.js +6 -1
  98. package/dist/server/metadata-route-response.js +94 -37
  99. package/dist/server/pages-api-route.js +8 -2
  100. package/dist/server/pages-asset-tags.d.ts +1 -0
  101. package/dist/server/pages-asset-tags.js +73 -22
  102. package/dist/server/pages-client-assets.d.ts +2 -0
  103. package/dist/server/pages-page-data.d.ts +6 -1
  104. package/dist/server/pages-page-data.js +71 -65
  105. package/dist/server/pages-page-handler.js +29 -11
  106. package/dist/server/pages-page-response.js +3 -1
  107. package/dist/server/pages-request-pipeline.d.ts +2 -1
  108. package/dist/server/pages-request-pipeline.js +20 -5
  109. package/dist/server/pages-request-stage-entry.js +6 -4
  110. package/dist/server/prerender-manifest.d.ts +6 -0
  111. package/dist/server/prerender-manifest.js +1 -1
  112. package/dist/server/prod-server.js +3 -13
  113. package/dist/server/response-stage-cacheability.js +1 -1
  114. package/dist/server/worker-revalidation-context.d.ts +2 -1
  115. package/dist/server/worker-revalidation-context.js +1 -0
  116. package/dist/server/workers-tracing.d.ts +17 -0
  117. package/dist/server/workers-tracing.js +48 -8
  118. package/dist/shims/cache-request-state.d.ts +3 -14
  119. package/dist/shims/cache-request-state.js +2 -13
  120. package/dist/shims/cache-runtime.js +4 -2
  121. package/dist/shims/cache.d.ts +2 -1
  122. package/dist/shims/cache.js +4 -2
  123. package/dist/shims/cacheability-classification.d.ts +1 -1
  124. package/dist/shims/cacheability-classification.js +2 -2
  125. package/dist/shims/cdn-cache.d.ts +10 -1
  126. package/dist/shims/cdn-cache.js +16 -9
  127. package/dist/shims/error.d.ts +4 -18
  128. package/dist/shims/error.js +17 -10
  129. package/dist/shims/error.react-server.d.ts +4 -6
  130. package/dist/shims/error.react-server.js +4 -1
  131. package/dist/shims/fetch-cache.js +4 -3
  132. package/dist/shims/headers.d.ts +6 -69
  133. package/dist/shims/headers.js +37 -181
  134. package/dist/shims/internal/cache-context-accessor.d.ts +16 -0
  135. package/dist/shims/internal/cache-context-accessor.js +15 -0
  136. package/dist/shims/internal/headers-state.d.ts +74 -0
  137. package/dist/shims/internal/headers-state.js +157 -0
  138. package/dist/shims/navigation.js +2 -2
  139. package/dist/shims/request-state-types.d.ts +2 -1
  140. package/dist/shims/root-params.js +1 -1
  141. package/dist/shims/server.js +52 -2
  142. package/dist/shims/unified-request-context.d.ts +1 -1
  143. package/dist/utils/encode-cache-tag.d.ts +1 -0
  144. package/dist/utils/encode-cache-tag.js +11 -1
  145. package/dist/utils/vite-cli-invocation.js +8 -1
  146. package/package.json +6 -2
  147. package/dist/server/metadata-route-cache-policy.d.ts +0 -5
  148. package/dist/server/metadata-route-cache-policy.js +0 -6
@@ -1,6 +1,6 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
2
  import { DYNAMIC_IMPORT_PRESCAN, SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, mayContainDynamicImport, scriptParserLanguage, stringLiteralValue, unwrapExpression } from "./ast-utils.js";
3
- import { magicStringTransformResult } from "./transform-result.js";
3
+ import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
4
4
  import { stripViteModuleQuery } from "../utils/path.js";
5
5
  import { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, hasAstBinding, isFunctionNode } from "./ast-scope.js";
6
6
  import { createTransformCache } from "./transform-cache.js";
@@ -12,6 +12,16 @@ const DYNAMIC_REQUEST_ERROR = "Cannot find module as expression is too dynamic";
12
12
  const REQUIRE_PRESCAN = /(?:\brequire\b|(?:r|\\u(?:0072|\{0*72\}))(?:e|\\u(?:0065|\{0*65\}))(?:q|\\u(?:0071|\{0*71\}))(?:u|\\u(?:0075|\{0*75\}))(?:i|\\u(?:0069|\{0*69\}))(?:r|\\u(?:0072|\{0*72\}))(?:e|\\u(?:0065|\{0*65\})))/i;
13
13
  const DYNAMIC_REQUEST_PRESCAN = new RegExp(String.raw`(?:${REQUIRE_PRESCAN.source}|${DYNAMIC_IMPORT_PRESCAN.source})`, "i");
14
14
  const MAX_CONSTANT_BINDING_DEPTH = 1500;
15
+ const REQUIRE_OR_IMPORT_OCCURRENCE = new RegExp(String.raw`${REQUIRE_PRESCAN.source}|\bimport\b`, "gi");
16
+ const IDENTIFIER_CHAR = /[\w$]/;
17
+ const LINE_TERMINATOR = /[\n\r\u2028\u2029]/;
18
+ const WHITESPACE_CHAR = /\s/;
19
+ const UNCHANGED_STRING_ARGUMENT = String.raw`\s*\(\s*(?:"(?!\/")[^"\\\r\n]*"|'(?!\/')[^'\\\r\n]*')\s*`;
20
+ const UNCHANGED_REQUIRE_CALL = new RegExp(String.raw`${UNCHANGED_STRING_ARGUMENT}\)`, "y");
21
+ const UNCHANGED_IMPORT_CALL = new RegExp(String.raw`${UNCHANGED_STRING_ARGUMENT}[,)]`, "y");
22
+ const POSSIBLE_REQUIRE_CALLEE_FOLLOWER = /\s*(?:[(/<]|--!?>|\?\.|!(?!=)|as\b|satisfies\b)/y;
23
+ const CLOSING_PAREN_FOLLOWER = /\s*\)/y;
24
+ const POSSIBLE_IMPORT_EXPRESSION_FOLLOWER = /\s*(?:[(/<]|--!?>|\.(?!\s*meta\b))/y;
15
25
  const VINEXT_SOURCE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
16
26
  const PLUGIN_RSC_PATH = /[\\/]node_modules[\\/](?:\.pnpm[\\/][^/\\]+[\\/]node_modules[\\/])?@vitejs[\\/]plugin-rsc[\\/]/;
17
27
  function stringFromCharCodeValue(value, scope) {
@@ -355,8 +365,48 @@ function dynamicRequireReplacement() {
355
365
  function dynamicImportReplacement() {
356
366
  return `Promise.resolve().then(() => { const error = new Error(${JSON.stringify(DYNAMIC_REQUEST_ERROR)}); error.code = "MODULE_NOT_FOUND"; throw error; })`;
357
367
  }
368
+ function matchesAt(pattern, code, index) {
369
+ pattern.lastIndex = index;
370
+ return pattern.test(code);
371
+ }
372
+ function mayBeWrappedCallee(code, start) {
373
+ let index = start - 1;
374
+ while (index >= 0 && WHITESPACE_CHAR.test(code[index])) {
375
+ if (LINE_TERMINATOR.test(code[index])) return true;
376
+ index--;
377
+ }
378
+ return index < 0 || code[index] === "(" || code[index] === ">" || code[index] === "/";
379
+ }
380
+ /**
381
+ * Cheap, conservative check run before parsing: whether any `require` or
382
+ * `import` occurrence could be a request this transform rewrites. Occurrences
383
+ * that are part of a longer identifier, member properties, static imports,
384
+ * non-callee positions (`typeof require`, `require,`), and calls with a
385
+ * single-line string literal argument other than "/" are left unchanged, so a
386
+ * module containing only those is skipped. Anything else, including escaped
387
+ * identifiers, falls through to the AST pass.
388
+ */
389
+ function mayContainVeryDynamicRequest(code) {
390
+ REQUIRE_OR_IMPORT_OCCURRENCE.lastIndex = 0;
391
+ for (let match; match = REQUIRE_OR_IMPORT_OCCURRENCE.exec(code);) {
392
+ const text = match[0];
393
+ const start = match.index;
394
+ const end = start + text.length;
395
+ if (text.includes("\\")) return true;
396
+ if (text !== "require" && text !== "import") continue;
397
+ if (IDENTIFIER_CHAR.test(code[start - 1] ?? "") || IDENTIFIER_CHAR.test(code[end] ?? "")) continue;
398
+ if (code[start - 1] === "." && code[start - 2] !== ".") continue;
399
+ if (text === "import") {
400
+ if (matchesAt(POSSIBLE_IMPORT_EXPRESSION_FOLLOWER, code, end) && !matchesAt(UNCHANGED_IMPORT_CALL, code, end)) return true;
401
+ } else if (matchesAt(POSSIBLE_REQUIRE_CALLEE_FOLLOWER, code, end)) {
402
+ if (!matchesAt(UNCHANGED_REQUIRE_CALL, code, end)) return true;
403
+ } else if (matchesAt(CLOSING_PAREN_FOLLOWER, code, end) && mayBeWrappedCallee(code, start)) return true;
404
+ }
405
+ return false;
406
+ }
358
407
  function transformVeryDynamicRequests(code, id) {
359
408
  if (!REQUIRE_PRESCAN.test(code) && !mayContainDynamicImport(code)) return null;
409
+ if (!mayContainVeryDynamicRequest(code)) return null;
360
410
  const lang = scriptParserLanguage(id) ?? "js";
361
411
  let ast;
362
412
  try {
@@ -486,7 +536,7 @@ function createIgnoreDynamicRequestsPlugin(getTranspiledPackages = () => []) {
486
536
  if (!shouldTransformVeryDynamicRequests(this.environment, cleanId, getTranspiledPackages())) return null;
487
537
  const absoluteId = path.resolve(cleanId);
488
538
  if (absoluteId === VINEXT_SOURCE_ROOT || absoluteId.startsWith(`${VINEXT_SOURCE_ROOT}/`) || PLUGIN_RSC_PATH.test(absoluteId)) return null;
489
- return cached(id, code, void 0, () => transformVeryDynamicRequests(code, id));
539
+ return omitUnusedBuildSourcemap(this.environment, cached(id, code, void 0, () => transformVeryDynamicRequests(code, id)));
490
540
  }
491
541
  }
492
542
  };
@@ -498,5 +548,6 @@ function shouldTransformVeryDynamicRequests(environment, id, transpiledPackages)
498
548
  return !transpiledPackages.some((packageName) => normalizedId.includes(`/node_modules/${packageName}/`));
499
549
  }
500
550
  const _transformVeryDynamicRequests = transformVeryDynamicRequests;
551
+ const _mayContainVeryDynamicRequest = mayContainVeryDynamicRequest;
501
552
  //#endregion
502
- export { _transformVeryDynamicRequests, createIgnoreDynamicRequestsPlugin };
553
+ export { _mayContainVeryDynamicRequest, _transformVeryDynamicRequests, createIgnoreDynamicRequestsPlugin };
@@ -1,6 +1,6 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
2
  import { SCRIPT_MODULE_ID_RE, collectBindingNames, forEachAstChild, isIdentifierNamed, scriptParserLanguage } from "./ast-utils.js";
3
- import { magicStringTransformResult } from "./transform-result.js";
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";
@@ -80,11 +80,11 @@ function createImportMetaUrlPlugin(options) {
80
80
  if (dependency) {
81
81
  const importMetaUrlReplacement = mayContainImportMetaUrl(code) ? this.environment.mode === "dev" ? JSON.stringify(pathToFileURL(dependency.canonicalId).href) : emittedModuleIdentity.importMetaUrlInitializer : void 0;
82
82
  const cjsGlobalInitializers = dependency.isCommonJs && mayContainServerCjsGlobal(code) ? this.environment.mode === "dev" ? sourcePathCjsGlobalInitializers(dependency.canonicalId) : emittedModuleIdentity.cjsGlobalInitializers : void 0;
83
- if (importMetaUrlReplacement !== void 0 || cjsGlobalInitializers) return rewriteModuleIdentity(code, {
83
+ if (importMetaUrlReplacement !== void 0 || cjsGlobalInitializers) return omitUnusedBuildSourcemap(this.environment, rewriteModuleIdentity(code, {
84
84
  id: dependency.canonicalId,
85
85
  importMetaUrlReplacement,
86
86
  cjsGlobalInitializers
87
- });
87
+ }));
88
88
  }
89
89
  }
90
90
  if (isNodeModulesId(cleanId)) return null;
@@ -106,10 +106,10 @@ function createImportMetaUrlPlugin(options) {
106
106
  setBoundedCacheEntry(transformCache, id, entry, MAX_TRANSFORM_CACHE_ENTRIES);
107
107
  }
108
108
  const cached = entry.results.get(transformKind);
109
- if (cached) return cached.value;
109
+ if (cached) return omitUnusedBuildSourcemap(this.environment, cached.value);
110
110
  const value = rewriteCanonicalSourceIdentity(code, canonicalId, paths, environment, this.environment.mode === "build" && mayContainServerCjsGlobal(code) ? emittedModuleIdentity.cjsGlobalInitializers : sourcePathCjsGlobalInitializers(canonicalId));
111
111
  entry.results.set(transformKind, { value });
112
- return value;
112
+ return omitUnusedBuildSourcemap(this.environment, value);
113
113
  }
114
114
  },
115
115
  renderChunk: {
@@ -117,7 +117,7 @@ function createImportMetaUrlPlugin(options) {
117
117
  handler(code, chunk, outputOptions) {
118
118
  if (this.environment?.config.consumer !== "server" || outputOptions.format !== "es") return null;
119
119
  const emittedFileName = resolveEmittedModuleFileName(this.environment?.name, chunk.fileName);
120
- return finalizeEmittedModuleIdentity(code, emittedModuleIdentity.replacements, emittedFileName);
120
+ return omitUnusedBuildSourcemap(this.environment, finalizeEmittedModuleIdentity(code, emittedModuleIdentity.replacements, emittedFileName));
121
121
  }
122
122
  }
123
123
  },
@@ -11,6 +11,7 @@ export declare class OgAssetOwnership {
11
11
  private readonly stringAliasesByFirstCharacter;
12
12
  private regularExpressionAliases;
13
13
  private configuredAliases;
14
+ private readonly resolvedImportPackageRoots;
14
15
  configure(projectRoot: string, aliases: readonly Alias[]): void;
15
16
  reset(): void;
16
17
  shouldTrackImport(source: string): boolean;
@@ -19,6 +20,7 @@ export declare class OgAssetOwnership {
19
20
  resolveContainedAsset(assetRoot: string, assetPath: string): Promise<string | null>;
20
21
  private findAlias;
21
22
  private getExpectedPackageName;
23
+ private findResolvedImportPackageRoot;
22
24
  private resolveAliasPackageRoot;
23
25
  private resolveConfiguredAliasRoot;
24
26
  }
@@ -93,8 +93,10 @@ var OgAssetOwnership = class {
93
93
  stringAliasesByFirstCharacter = /* @__PURE__ */ new Map();
94
94
  regularExpressionAliases = [];
95
95
  configuredAliases = [];
96
+ resolvedImportPackageRoots = /* @__PURE__ */ new Map();
96
97
  configure(projectRoot, aliases) {
97
98
  this.projectRoot = path.resolve(projectRoot);
99
+ this.resolvedImportPackageRoots.clear();
98
100
  this.dependencyPackageNames.clear();
99
101
  try {
100
102
  const manifest = JSON.parse(fs.readFileSync(path.join(this.projectRoot, "package.json"), "utf8"));
@@ -129,25 +131,20 @@ var OgAssetOwnership = class {
129
131
  }
130
132
  reset() {
131
133
  this.linkedPackageRoots.clear();
134
+ this.resolvedImportPackageRoots.clear();
132
135
  }
133
136
  shouldTrackImport(source) {
134
137
  return this.findAlias(source) !== void 0 || this.getExpectedPackageName(source) !== void 0;
135
138
  }
136
139
  async recordResolvedImport(source, resolvedId) {
137
- const configuredAlias = this.findAlias(source);
138
- const sourcePackageName = packageNameFromSpecifier(source);
139
- const expectedPackageName = this.getExpectedPackageName(source);
140
- if (configuredAlias === void 0 && expectedPackageName === void 0) return;
141
- let realResolvedPath;
142
- try {
143
- realResolvedPath = await realpathNative(path.resolve(stripViteModuleQuery(resolvedId)));
144
- } catch {
145
- return;
140
+ const key = `${source}\0${resolvedId}`;
141
+ let packageRoot = this.resolvedImportPackageRoots.get(key);
142
+ if (packageRoot === void 0) {
143
+ packageRoot = this.findResolvedImportPackageRoot(source, resolvedId);
144
+ this.resolvedImportPackageRoots.set(key, packageRoot);
146
145
  }
147
- let packageRoot;
148
- if (configuredAlias !== void 0) packageRoot = await this.resolveAliasPackageRoot(configuredAlias, source, sourcePackageName, realResolvedPath);
149
- else packageRoot = await findPackageRoot(path.dirname(realResolvedPath), expectedPackageName);
150
- if (packageRoot !== null) this.linkedPackageRoots.add(packageRoot);
146
+ const root = await packageRoot;
147
+ if (root !== null) this.linkedPackageRoots.add(root);
151
148
  }
152
149
  async resolveModuleBoundary(moduleId) {
153
150
  const modulePath = path.resolve(stripViteModuleQuery(moduleId));
@@ -219,6 +216,20 @@ var OgAssetOwnership = class {
219
216
  const packageName = packageNameFromSpecifier(source);
220
217
  return packageName === null ? void 0 : this.dependencyPackageNames.get(packageName);
221
218
  }
219
+ async findResolvedImportPackageRoot(source, resolvedId) {
220
+ const configuredAlias = this.findAlias(source);
221
+ const sourcePackageName = packageNameFromSpecifier(source);
222
+ const expectedPackageName = this.getExpectedPackageName(source);
223
+ if (configuredAlias === void 0 && expectedPackageName === void 0) return null;
224
+ let realResolvedPath;
225
+ try {
226
+ realResolvedPath = await realpathNative(path.resolve(stripViteModuleQuery(resolvedId)));
227
+ } catch {
228
+ return null;
229
+ }
230
+ if (configuredAlias !== void 0) return this.resolveAliasPackageRoot(configuredAlias, source, sourcePackageName, realResolvedPath);
231
+ return findPackageRoot(path.dirname(realResolvedPath), expectedPackageName);
232
+ }
222
233
  async resolveAliasPackageRoot(alias, source, sourcePackageName, realResolvedPath) {
223
234
  const aliasTarget = applyAlias(alias.find, alias.replacement, source);
224
235
  if (!path.isAbsolute(aliasTarget)) return null;
@@ -11,6 +11,24 @@ import { Plugin } from "vite";
11
11
  * valid file URL.
12
12
  */
13
13
  export declare function createOgInlineFetchAssetsPlugin(): Plugin;
14
+ type ReadFileSyncAssetUrlMatch = {
15
+ start: number;
16
+ end: number;
17
+ relPath: string;
18
+ };
19
+ /**
20
+ * Find every `<identifier>.readFileSync(fileURLToPath(new URL("./file", import.meta.url)))`
21
+ * call in `code`.
22
+ *
23
+ * Returns the same matches, in the same order, as `code.matchAll()` with
24
+ * `/[a-zA-Z_$][a-zA-Z0-9_$]*` followed by `READ_FILE_SYNC_ASSET_URL_TAIL_RE` as a
25
+ * global regex. That regex retries the identifier prefix at every identifier
26
+ * character of the module, which is slow on large bundles such as typescript.js.
27
+ * A match's identifier always ends right at a `.readFileSync(` occurrence, so
28
+ * candidates are found with `indexOf` and the identifier is recovered by
29
+ * scanning backwards.
30
+ */
31
+ export declare function matchReadFileSyncAssetUrls(code: string): ReadFileSyncAssetUrlMatch[];
14
32
  /**
15
33
  * Copy a single root copy of each requested WASM asset from `sourceDir` into
16
34
  * `outDir`, skipping any asset whose source is missing or whose destination
@@ -1,5 +1,5 @@
1
1
  import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
- import { magicStringTransformResult } from "./transform-result.js";
2
+ import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
3
3
  import { resolveHarfbuzzWasmPath } from "./og-harfbuzz.js";
4
4
  import { OgAssetOwnership } from "./og-asset-ownership.js";
5
5
  import { createRequire } from "node:module";
@@ -80,21 +80,63 @@ function createOgInlineFetchAssetsPlugin() {
80
80
  s.overwrite(match.index, match.index + fullMatch.length, inlined);
81
81
  didReplace = true;
82
82
  }
83
- if (code.includes("readFileSync(")) for (const match of code.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
84
- const fullMatch = match[0];
85
- const relPath = match[2];
86
- const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
83
+ if (code.includes("readFileSync(")) for (const match of matchReadFileSyncAssetUrls(code)) {
84
+ const fileBase64 = await readAsBase64(path.resolve(moduleDir, match.relPath));
87
85
  if (fileBase64 === null) continue;
88
86
  const inlined = `Buffer.from(${JSON.stringify(fileBase64)},"base64")`;
89
- s.overwrite(match.index, match.index + fullMatch.length, inlined);
87
+ s.overwrite(match.start, match.end, inlined);
90
88
  didReplace = true;
91
89
  }
92
90
  if (!didReplace) return null;
93
- return magicStringTransformResult(s);
91
+ return omitUnusedBuildSourcemap(this.environment, magicStringTransformResult(s));
94
92
  }
95
93
  }
96
94
  };
97
95
  }
96
+ const READ_FILE_SYNC_ASSET_URL_TAIL_RE = /\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/y;
97
+ /**
98
+ * Find every `<identifier>.readFileSync(fileURLToPath(new URL("./file", import.meta.url)))`
99
+ * call in `code`.
100
+ *
101
+ * Returns the same matches, in the same order, as `code.matchAll()` with
102
+ * `/[a-zA-Z_$][a-zA-Z0-9_$]*` followed by `READ_FILE_SYNC_ASSET_URL_TAIL_RE` as a
103
+ * global regex. That regex retries the identifier prefix at every identifier
104
+ * character of the module, which is slow on large bundles such as typescript.js.
105
+ * A match's identifier always ends right at a `.readFileSync(` occurrence, so
106
+ * candidates are found with `indexOf` and the identifier is recovered by
107
+ * scanning backwards.
108
+ */
109
+ function matchReadFileSyncAssetUrls(code) {
110
+ const matches = [];
111
+ let searchFrom = 0;
112
+ let dot = code.indexOf(".readFileSync(");
113
+ while (dot !== -1) {
114
+ let start = dot;
115
+ while (start > searchFrom && isAsciiIdentifierPart(code.charCodeAt(start - 1))) start--;
116
+ while (start < dot && !isAsciiIdentifierStart(code.charCodeAt(start))) start++;
117
+ if (start < dot) {
118
+ READ_FILE_SYNC_ASSET_URL_TAIL_RE.lastIndex = dot;
119
+ const tail = READ_FILE_SYNC_ASSET_URL_TAIL_RE.exec(code);
120
+ if (tail !== null) {
121
+ const end = dot + tail[0].length;
122
+ matches.push({
123
+ start,
124
+ end,
125
+ relPath: tail[2]
126
+ });
127
+ searchFrom = end;
128
+ }
129
+ }
130
+ dot = code.indexOf(".readFileSync(", Math.max(dot + 1, searchFrom));
131
+ }
132
+ return matches;
133
+ }
134
+ function isAsciiIdentifierStart(charCode) {
135
+ return charCode >= 97 && charCode <= 122 || charCode >= 65 && charCode <= 90 || charCode === 95 || charCode === 36;
136
+ }
137
+ function isAsciiIdentifierPart(charCode) {
138
+ return isAsciiIdentifierStart(charCode) || charCode >= 48 && charCode <= 57;
139
+ }
98
140
  const OG_WASM_ASSETS = [
99
141
  "resvg.wasm",
100
142
  "yoga.wasm",
@@ -243,4 +285,4 @@ function createOgAssetsPlugin() {
243
285
  };
244
286
  }
245
287
  //#endregion
246
- export { copyMissingOgWasm, createOgAssetsPlugin, createOgInlineFetchAssetsPlugin };
288
+ export { copyMissingOgWasm, createOgAssetsPlugin, createOgInlineFetchAssetsPlugin, matchReadFileSyncAssetUrls };
@@ -1,7 +1,8 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
2
  import { forEachAstChild, getAstName, staticStringValue } from "./ast-utils.js";
3
- import { magicStringTransformResult } from "./transform-result.js";
3
+ import { magicStringTransformResult, omitUnusedBuildSourcemap } from "./transform-result.js";
4
4
  import { isFunctionNode } from "./ast-scope.js";
5
+ import { createTransformCache } from "./transform-cache.js";
5
6
  import { createRequire } from "node:module";
6
7
  import fs from "node:fs";
7
8
  import { parseAst } from "vite";
@@ -210,9 +211,43 @@ const INSTANTIATE_WASM = `function __vi_hb_instantiateWasm(imports, receiveInsta
210
211
  receiveInstance(instance);
211
212
  return instance.exports;
212
213
  }`;
214
+ /**
215
+ * Patch one @vercel/og entry bundle. The result depends only on the bundle
216
+ * source, its id, the command and the callback module directory; callback
217
+ * modules are written once and reused by later calls.
218
+ */
219
+ function patchHarfbuzzBundle(code, id, isBuild, callbackModuleDir, error) {
220
+ const ogEntry = toSlash(id.split("?", 1)[0]);
221
+ const isWorkerd = ogEntry.endsWith("/index.edge.js");
222
+ 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(parseAst(code, { lang: "js" }));
224
+ if (typeof sites === "string") return fail(sites);
225
+ const output = new MagicString(code);
226
+ for (const flag of sites.environmentFlags) output.overwrite(flag.start, flag.end, "false");
227
+ for (const member of sites.instantiateWasmReads) output.overwrite(member.start, member.end, "__vi_hb_instantiateWasm");
228
+ const harfbuzzWasm = resolveHarfbuzzWasmPath(ogEntry);
229
+ const preamble = [];
230
+ if (isWorkerd) {
231
+ if (sites.moduleCompilations.length === 0) return fail("no callback module compilation (new WebAssembly.Module) was found");
232
+ for (const { node, enclosingFunction } of sites.moduleCompilations) {
233
+ const signature = isFunctionNode(enclosingFunction) ? enclosingFunction.params[1] : void 0;
234
+ if (signature?.type !== "Identifier") return fail("the callback compiler does not take a (func, sig) signature");
235
+ output.prependLeft(node.start, `(__vi_hb_callbacks[${signature.name}.replace(/p/g, "i")] || `);
236
+ output.appendRight(node.end, ")");
237
+ }
238
+ const callbacks = [...writeHarfbuzzCallbackModules(harfbuzzWasm, callbackModuleDir)];
239
+ preamble.push(`import __vi_hb_wasm from ${JSON.stringify(`${harfbuzzWasm}?module`)};`, ...callbacks.map(([, file], index) => `import __vi_hb_callback_${index} from ${JSON.stringify(`${file}?module`)};`), `var __vi_hb_callbacks = { ${callbacks.map(([signature], index) => `${signature}: __vi_hb_callback_${index}`).join(", ")} };`, "function __vi_hb_module() { return __vi_hb_wasm; }");
240
+ } else {
241
+ const location = isBuild ? `new URL("./${HARFBUZZ_WASM}", import.meta.url)` : JSON.stringify(harfbuzzWasm);
242
+ preamble.push(`import { readFileSync as __vi_hb_readFileSync } from "node:fs";`, `function __vi_hb_module() { return new WebAssembly.Module(__vi_hb_readFileSync(${location})); }`);
243
+ }
244
+ output.prepend(`${preamble.join("\n")}\n${INSTANTIATE_WASM}\n`);
245
+ return magicStringTransformResult(output);
246
+ }
213
247
  function createOgHarfbuzzPlugin() {
214
248
  let callbackModuleDir;
215
249
  let isBuild = false;
250
+ const cached = createTransformCache();
216
251
  return {
217
252
  name: "vinext:og-harfbuzz",
218
253
  enforce: "pre",
@@ -226,32 +261,8 @@ function createOgHarfbuzzPlugin() {
226
261
  code: /["'`]hb\.wasm["'`]/
227
262
  },
228
263
  handler(code, id) {
229
- const ogEntry = toSlash(id.split("?", 1)[0]);
230
- const isWorkerd = ogEntry.endsWith("/index.edge.js");
231
- const fail = (reason) => this.error(`[vinext] Unsupported @vercel/og HarfBuzz bundle in ${ogEntry}: ${reason}. vinext must be updated to support this @vercel/og version.`);
232
- const sites = findHarfbuzzPatchSites(parseAst(code, { lang: "js" }));
233
- if (typeof sites === "string") return fail(sites);
234
- const output = new MagicString(code);
235
- for (const flag of sites.environmentFlags) output.overwrite(flag.start, flag.end, "false");
236
- for (const member of sites.instantiateWasmReads) output.overwrite(member.start, member.end, "__vi_hb_instantiateWasm");
237
- const harfbuzzWasm = resolveHarfbuzzWasmPath(ogEntry);
238
- const preamble = [];
239
- if (isWorkerd) {
240
- if (sites.moduleCompilations.length === 0) return fail("no callback module compilation (new WebAssembly.Module) was found");
241
- for (const { node, enclosingFunction } of sites.moduleCompilations) {
242
- const signature = isFunctionNode(enclosingFunction) ? enclosingFunction.params[1] : void 0;
243
- if (signature?.type !== "Identifier") return fail("the callback compiler does not take a (func, sig) signature");
244
- output.prependLeft(node.start, `(__vi_hb_callbacks[${signature.name}.replace(/p/g, "i")] || `);
245
- output.appendRight(node.end, ")");
246
- }
247
- const callbacks = [...writeHarfbuzzCallbackModules(harfbuzzWasm, callbackModuleDir)];
248
- preamble.push(`import __vi_hb_wasm from ${JSON.stringify(`${harfbuzzWasm}?module`)};`, ...callbacks.map(([, file], index) => `import __vi_hb_callback_${index} from ${JSON.stringify(`${file}?module`)};`), `var __vi_hb_callbacks = { ${callbacks.map(([signature], index) => `${signature}: __vi_hb_callback_${index}`).join(", ")} };`, "function __vi_hb_module() { return __vi_hb_wasm; }");
249
- } else {
250
- const location = isBuild ? `new URL("./${HARFBUZZ_WASM}", import.meta.url)` : JSON.stringify(harfbuzzWasm);
251
- preamble.push(`import { readFileSync as __vi_hb_readFileSync } from "node:fs";`, `function __vi_hb_module() { return new WebAssembly.Module(__vi_hb_readFileSync(${location})); }`);
252
- }
253
- output.prepend(`${preamble.join("\n")}\n${INSTANTIATE_WASM}\n`);
254
- return magicStringTransformResult(output);
264
+ const patch = () => patchHarfbuzzBundle(code, id, isBuild, callbackModuleDir, (message) => this.error(message));
265
+ return omitUnusedBuildSourcemap(this.environment, isBuild ? cached(id, code, callbackModuleDir, patch) : patch());
255
266
  }
256
267
  }
257
268
  };
@@ -108,7 +108,8 @@ function createOptimizedImportSourceMatcher(packages) {
108
108
  const pattern = [...packages].map(escapeRegExp).join("|");
109
109
  if (!pattern) return () => false;
110
110
  const importFromPattern = new RegExp(String.raw`(?:^|[;}\n\r])\s*import(?!\s*\()(?:(?!\bfrom\b)[\s\S])*?\bfrom\s*["'](?:${pattern})["']`, "m");
111
- return (code) => code.includes("import") && code.includes("from") && importFromPattern.test(code);
111
+ const quotedSourcePattern = new RegExp(String.raw`["'](?:${pattern})["']`);
112
+ return (code) => code.includes("import") && code.includes("from") && quotedSourcePattern.test(code) && importFromPattern.test(code);
112
113
  }
113
114
  /**
114
115
  * Resolve a package.json exports value to a string entry path.
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from "vite";
2
2
  //#region src/plugins/require-context.d.ts
3
3
  export declare function createRequireContextPlugin(): Plugin;
4
+ export declare function _mayContainRequireContextCall(code: string): boolean;
4
5
  //#endregion
@@ -51,7 +51,34 @@ function createRequireContextPlugin() {
51
51
  }
52
52
  };
53
53
  }
54
+ const CONTEXT_CALL_SPACE = String.raw`[\s\u0085\u200b]`;
55
+ const LINE_TERMINATOR = String.raw`[\n\r\u2028\u2029]`;
56
+ const CONTEXT_PROPERTY = String.raw`(?:c|\\u(?:0063|\{0*63\}))(?:o|\\u(?:006f|\{0*6f\}))(?:n|\\u(?:006e|\{0*6e\}))(?:t|\\u(?:0074|\{0*74\}))(?:e|\\u(?:0065|\{0*65\}))(?:x|\\u(?:0078|\{0*78\}))(?:t|\\u(?:0074|\{0*74\}))`;
57
+ const CONTEXT_MEMBER_PREFIX = String.raw`(?:\.|\*\/|(?:\/\/|<!--|-->)[^\n\r\u2028\u2029]*${LINE_TERMINATOR})${CONTEXT_CALL_SPACE}*`;
58
+ const COMMENT_OPENER = String.raw`\/[*/]|<!--|-->`;
59
+ /**
60
+ * Cheap pre-parse gate for {@link transformRequireContext}. The transform only
61
+ * rewrites a `.context` member call whose first argument is a string literal,
62
+ * so the source must contain `.`, `context`, then — after optional closing
63
+ * parens of a `(require.context)` callee and an optional `?.` — a `(` followed
64
+ * by optional opening parens and a quote. TypeScript type arguments
65
+ * (`context<T>(...)`) are not scanned: any `<` after `context` keeps the parse.
66
+ *
67
+ * The transform filter admits every module that mentions both `require` and
68
+ * `.context` (React, TypeScript, ...), and parsing multi-MB dependencies that
69
+ * can never contain a matching call dominated this plugin's cost. The gate
70
+ * errs toward over-matching: a false positive costs one redundant parse,
71
+ * whereas a false negative would silently skip a real `require.context` call.
72
+ * Comments therefore count as a match instead of being scanned, and the match
73
+ * starts at `context` and looks back for the `.`. Every repetition then covers
74
+ * only whitespace and parens next to one `context`, so the scan stays linear.
75
+ */
76
+ const REQUIRE_CONTEXT_CALL_PRESCAN = new RegExp(String.raw`${CONTEXT_PROPERTY}(?<=${CONTEXT_MEMBER_PREFIX}${CONTEXT_PROPERTY})(?:${CONTEXT_CALL_SPACE}|\))*(?:\?\.${CONTEXT_CALL_SPACE}*)?(?:<|${COMMENT_OPENER}|\((?:${CONTEXT_CALL_SPACE}|\()*(?:["']|${COMMENT_OPENER}))`, "i");
77
+ function _mayContainRequireContextCall(code) {
78
+ return REQUIRE_CONTEXT_CALL_PRESCAN.test(code);
79
+ }
54
80
  async function transformRequireContext(code, id) {
81
+ if (!REQUIRE_CONTEXT_CALL_PRESCAN.test(code)) return null;
55
82
  const lang = scriptParserLanguage(id);
56
83
  let ast;
57
84
  try {
@@ -261,4 +288,4 @@ function stripTrailingSlash(value) {
261
288
  return value.endsWith("/") ? value.slice(0, -1) : value;
262
289
  }
263
290
  //#endregion
264
- export { createRequireContextPlugin };
291
+ export { _mayContainRequireContextCall, createRequireContextPlugin };
@@ -0,0 +1,12 @@
1
+ import { Plugin } from "vite";
2
+ //#region src/plugins/scan-build-css.d.ts
3
+ /**
4
+ * @vitejs/plugin-rsc discovers client and server references with two
5
+ * write-less scan builds whose output is discarded, and its `rsc:scan-strip`
6
+ * plugin reduces every module to its import specifiers. A stylesheet cannot
7
+ * contribute a JavaScript import, yet without this plugin every stylesheet in
8
+ * the app still ran through PostCSS/Tailwind/Sass in both scans. Empty their
9
+ * source during those scans only; real builds and dev are unchanged.
10
+ */
11
+ export declare function createScanBuildCssPlugin(): Plugin;
12
+ //#endregion
@@ -0,0 +1,39 @@
1
+ //#region src/plugins/scan-build-css.ts
2
+ const CSS_LANGS_RE = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
3
+ const SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/;
4
+ const VIRTUAL_MODULE_RE = /^\0/;
5
+ /**
6
+ * @vitejs/plugin-rsc discovers client and server references with two
7
+ * write-less scan builds whose output is discarded, and its `rsc:scan-strip`
8
+ * plugin reduces every module to its import specifiers. A stylesheet cannot
9
+ * contribute a JavaScript import, yet without this plugin every stylesheet in
10
+ * the app still ran through PostCSS/Tailwind/Sass in both scans. Empty their
11
+ * source during those scans only; real builds and dev are unchanged.
12
+ */
13
+ function createScanBuildCssPlugin() {
14
+ let rscApi;
15
+ return {
16
+ name: "vinext:scan-build-css",
17
+ enforce: "pre",
18
+ apply: "build",
19
+ configResolved(config) {
20
+ rscApi = config.plugins.find((plugin) => plugin.name === "rsc:minimal")?.api;
21
+ },
22
+ transform: {
23
+ order: "pre",
24
+ filter: { id: {
25
+ include: CSS_LANGS_RE,
26
+ exclude: [SPECIAL_QUERY_RE, VIRTUAL_MODULE_RE]
27
+ } },
28
+ handler() {
29
+ if (!rscApi?.manager.isScanBuild || this.environment.config.build.write !== false) return null;
30
+ return {
31
+ code: "",
32
+ map: null
33
+ };
34
+ }
35
+ }
36
+ };
37
+ }
38
+ //#endregion
39
+ export { createScanBuildCssPlugin };
@@ -1,6 +1,8 @@
1
1
  import MagicString from "magic-string";
2
2
  //#region src/plugins/strip-server-exports.d.ts
3
3
  export declare function hasServerExportCandidate(code: string): boolean;
4
+ /** Transform prefilter; must admit every module `hasExportAllCandidate` accepts */
5
+ export declare const EXPORT_ALL_CANDIDATE_FILTER: RegExp;
4
6
  export declare function hasExportAllCandidate(code: string): boolean;
5
7
  export declare function validatePageExports(code: string): void;
6
8
  type StripServerExportsResult = {
@@ -18,6 +18,8 @@ function hasServerExportCandidate(code) {
18
18
  for (const name of SERVER_EXPORTS) if (code.includes(name)) return true;
19
19
  return false;
20
20
  }
21
+ /** Transform prefilter; must admit every module `hasExportAllCandidate` accepts */
22
+ const EXPORT_ALL_CANDIDATE_FILTER = /\bexport\s*[*/]/;
21
23
  function hasExportAllCandidate(code) {
22
24
  let searchFrom = 0;
23
25
  while (searchFrom < code.length) {
@@ -510,4 +512,4 @@ function stripServerExports(code) {
510
512
  return magicStringTransformResult(string);
511
513
  }
512
514
  //#endregion
513
- export { hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };
515
+ export { EXPORT_ALL_CANDIDATE_FILTER, hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };
@@ -4,6 +4,24 @@ export type MagicStringTransformResult = {
4
4
  code: string;
5
5
  map: ReturnType<MagicString["generateMap"]>;
6
6
  };
7
+ type SourcemapEnvironment = {
8
+ mode?: string;
9
+ config?: {
10
+ build?: {
11
+ sourcemap?: boolean | "inline" | "hidden";
12
+ };
13
+ };
14
+ };
7
15
  /** Build the standard code + sourcemap result returned by source transforms. */
8
16
  export declare function magicStringTransformResult(output: MagicString, options?: Parameters<MagicString["generateMap"]>[0]): MagicStringTransformResult;
17
+ /**
18
+ * Drop the sourcemap from a transform result when the build environment
19
+ * discards it, mirroring Vite's own transforms
20
+ * (`config.build.sourcemap ? s.generateMap(...) : null`). Dev and builds with
21
+ * sourcemaps enabled keep the result unchanged.
22
+ */
23
+ export declare function omitUnusedBuildSourcemap(environment: SourcemapEnvironment | undefined, result: MagicStringTransformResult | null): {
24
+ code: string;
25
+ map: MagicStringTransformResult["map"] | null;
26
+ } | null;
9
27
  //#endregion
@@ -1,10 +1,31 @@
1
1
  //#region src/plugins/transform-result.ts
2
2
  /** Build the standard code + sourcemap result returned by source transforms. */
3
3
  function magicStringTransformResult(output, options = { hires: "boundary" }) {
4
+ let source = output;
5
+ let map;
4
6
  return {
5
7
  code: output.toString(),
6
- map: output.generateMap(options)
8
+ get map() {
9
+ if (source) {
10
+ map = source.generateMap(options);
11
+ source = void 0;
12
+ }
13
+ return map;
14
+ }
15
+ };
16
+ }
17
+ /**
18
+ * Drop the sourcemap from a transform result when the build environment
19
+ * discards it, mirroring Vite's own transforms
20
+ * (`config.build.sourcemap ? s.generateMap(...) : null`). Dev and builds with
21
+ * sourcemaps enabled keep the result unchanged.
22
+ */
23
+ function omitUnusedBuildSourcemap(environment, result) {
24
+ if (!result || environment?.mode !== "build" || environment.config?.build?.sourcemap !== false) return result;
25
+ return {
26
+ code: result.code,
27
+ map: null
7
28
  };
8
29
  }
9
30
  //#endregion
10
- export { magicStringTransformResult };
31
+ export { magicStringTransformResult, omitUnusedBuildSourcemap };
@@ -6,6 +6,11 @@ export type ConsumerEnvironmentReplacements = {
6
6
  typeofWindow?: WindowType;
7
7
  processBrowser?: boolean;
8
8
  pruneUnreachableImports?: boolean;
9
+ /**
10
+ * Return null without walking the AST when folding cannot change the module's
11
+ * scanned imports. Only valid for import-scan builds.
12
+ */
13
+ onlyIfScannedImportsChange?: boolean;
9
14
  };
10
15
  type EnvironmentLike = {
11
16
  config: {
@@ -13,6 +18,11 @@ type EnvironmentLike = {
13
18
  };
14
19
  };
15
20
  export declare function getTypeofWindowReplacement(environment: EnvironmentLike): WindowType;
21
+ /**
22
+ * Cheap pre-parse gate for import-scan builds. Over-inclusive by design; the
23
+ * parser's module record in {@link moduleRecordHasScannedFoldTargets} is exact.
24
+ */
25
+ export declare function mayFoldChangeScannedImports(code: string): boolean;
16
26
  export declare function replaceTypeofWindow(code: string, replacement: WindowType, id?: string): MagicStringTransformResult | null;
17
27
  export declare function replaceConsumerEnvironmentConditions(code: string, replacements: ConsumerEnvironmentReplacements, id?: string): MagicStringTransformResult | null;
18
28
  //#endregion